Войти Регистрация
Фронтенд

52. Поиск по классам в дереве каталога Wildberries

Лёгкая

Каталог Wildberries рендерится на сервере, и до появления настоящего DOM разметка — это дерево объектов {tag, id, classes, children}. В тестах SSR нужен свой querySelectorAll: найти все карточки со скидкой, все активные фильтры.

Напишите queryAll(root, selector). Селектор — тег и/или классы через точку без пробелов: li, .sale, li.card.sale. Узел подходит, если тег совпал (когда он указан) и у узла есть все перечисленные классы.

Верните массив id подходящих узлов в порядке документа: сначала узел, потом его дети слева направо. Корень тоже проверяется. Ничего не нашлось — пустой массив.

В работе: SSR-тест каталога на 120 карточек проверяет, что у всех товаров со скидкой отрисована зачёркнутая цена.

Пример 1: все карточки со скидкой

Аргументы теста
{"tag": "main", "id": "catalog", "classes": ["catalog"], "children": [{"tag": "div", "id": "f1", "classes": ["filters"], "children": [{"tag": "button", "id": "b-sale", "classes": ["chip", "active"], "children": []}, {"tag": "button", "id": "b-new", "classes": ["chip"], "children": []}]}, {"tag": "ul", "id": "grid", "classes": ["grid"], "children": [{"tag": "li", "id": "p-1", "classes": ["card", "sale"], "children": [{"tag": "span", "id": "p-1-price", "classes": ["price", "sale"], "children": []}]}, {"tag": "li", "id": "p-2", "classes": ["card"], "children": [{"tag": "span", "id": "p-2-price", "classes": ["price"], "children": []}]}, {"tag": "li", "id": "p-3", "classes": ["card", "sale", "hit"], "children": []}]}]}, "li.card.sale"
Ожидается
["p-1", "p-3"]

Пример 2: класс на разных тегах, порядок документа

Аргументы теста
{"tag": "main", "id": "catalog", "classes": ["catalog"], "children": [{"tag": "div", "id": "f1", "classes": ["filters"], "children": [{"tag": "button", "id": "b-sale", "classes": ["chip", "active"], "children": []}, {"tag": "button", "id": "b-new", "classes": ["chip"], "children": []}]}, {"tag": "ul", "id": "grid", "classes": ["grid"], "children": [{"tag": "li", "id": "p-1", "classes": ["card", "sale"], "children": [{"tag": "span", "id": "p-1-price", "classes": ["price", "sale"], "children": []}]}, {"tag": "li", "id": "p-2", "classes": ["card"], "children": [{"tag": "span", "id": "p-2-price", "classes": ["price"], "children": []}]}, {"tag": "li", "id": "p-3", "classes": ["card", "sale", "hit"], "children": []}]}]}, ".sale"
Ожидается
["p-1", "p-1-price", "p-3"]
Как проверяем Объявите queryAll — тест вызывает её сам. Таймеры и Date в тестах ненастоящие: время идёт по команде теста, поэтому setTimeout на 5 секунд проверяется мгновенно. Тестов 9: 2 открыты выше, остальные приходят после старта подхода. Лимит — 2 с на тест.
function queryAll(root, selector) // → string[]
деревьяобход в глубинуселекторы

Источник: на задачах Wildberries: каталог и SSR-разметка. Условие пересказано своими словами.