test: cover tackle browser acceptance

This commit is contained in:
ik
2026-09-20 18:42:33 +07:00
parent 46251c635f
commit d541443a1a
3 changed files with 23 additions and 1 deletions
@@ -1,6 +1,10 @@
import { expect, test } from "@playwright/test";
test("production bootstrap supports submission and moderation", async ({ page, request }) => {
test.skip(
!process.env.BOOTSTRAP_API_URL || !process.env.BOOTSTRAP_ADMIN_TOKEN,
"requires BOOTSTRAP_API_URL and BOOTSTRAP_ADMIN_TOKEN; run deploy/test-production-bootstrap.sh",
);
const player = `Bootstrap Player ${Date.now()}`;
const x = 7000 + Date.now() % 1000;
const y = x + 1;
+18
View File
@@ -0,0 +1,18 @@
import { expect, test } from "@playwright/test";
test("tackle catalog exposes an explicit empty state for unmatched filters", async ({ page }) => {
await page.setViewportSize({ width: 320, height: 800 });
await page.goto("/tackle?category=lure&brand=NoSuchBrand&family=NoSuchFamily");
await expect(page.getByRole("heading", { name: "Подтверждённых карточек пока нет" })).toBeVisible();
await expect(page.getByRole("link", { name: "Сбросить" })).toHaveAttribute("href", "/tackle");
await expect(page.getByLabel("Категория")).toHaveValue("lure");
await expect(page.getByLabel("Бренд")).toHaveValue("NoSuchBrand");
await expect(page.getByLabel("Семейство")).toHaveValue("NoSuchFamily");
const dimensions = await page.evaluate(() => ({
clientWidth: document.documentElement.clientWidth,
scrollWidth: document.documentElement.scrollWidth,
}));
expect(dimensions.scrollWidth).toBeLessThanOrEqual(dimensions.clientWidth);
});
+1 -1
View File
@@ -74,7 +74,7 @@
- [ ] **G06 · API и публичный каталог.** Добавлены пагинированный `/api/v1/tackle/items` с фильтрами по категории, бренду, семейству и уровню, detail endpoints для предмета и монтажа, а также ordered `tackle_components` в ответе уловов точки. Ответы показывают только канонические характеристики, provenance, timestamp проверки и `missing_fields`; рейтинг эффективности не добавляется. Остаётся подключить публичные Astro-карточки и ссылки из всех нужных представлений улова.
- [ ] **G07 · Аналитика сочетаний и рекомендации.** Добавлен `/api/v1/analytics/tackle`: approved-наблюдения группируются по роли и исходному компоненту с фильтрами водоёма, рыбы, метода и окна; дубликаты одного улова не увеличивают счётчик, а минимум наблюдений и независимых игроков отделяет факт использования от рекомендации. Пустая или малая выборка получает `insufficient_data`; decay по свежести и отдельные UI-состояния остаются следующим шагом.
- [ ] **G08 · Медиа и качество.** Добавлены отдельные reviewed-роли `tackle_card`, `tackle_detail`, `rig_diagram`, `tackle_screenshot` для `tackle`, а также CLI-параметр `--media-role`; offline audit отклоняет неизвестную роль и несовпадение роли с entity type. Существующие dimensions, MIME, SHA-256, прозрачность, aspect ratio, provenance и атомарное продвижение сохраняются. Остаётся провести реальный contact-sheet review для будущих tackle-кандидатов без автоматической публикации.
- [ ] **G09 · Приёмка и эксплуатация.** Добавлены fixture/regression tests для crosswalk, media roles, идемпотентных компонентов, пустых результатов и многокомпонентных наблюдений; каталог `/tackle` включён в visual-matrix, narrow smoke и accessibility routes. Offline catalog/media audits и сохранение старых данных при сбое проходят. Добавлен TEMP-only query-plan gate для фильтра каталога и группировки сочетаний: production-фильтры должны использовать индексы и укладываться в 250 мс. Остаются HTTP/browser acceptance для пустых, неоднозначных и многокомпонентных комплектов. Сетевые тесты не выполнять; импорт оставить opt-in, последовательным и под общим cooldown/backoff. Закрывать пакет только после проверяемого счётчика по каждой категории либо явной фиксации `unknown`.
- [ ] **G09 · Приёмка и эксплуатация.** Добавлены fixture/regression tests для crosswalk, media roles, идемпотентных компонентов, пустых результатов и многокомпонентных наблюдений; каталог `/tackle` включён в visual-matrix, narrow smoke и accessibility routes. Offline catalog/media audits и сохранение старых данных при сбое импорта проходят. TEMP-only query-plan gate для фильтра каталога и группировки сочетаний использует индексы и укладывается в 250 мс. Chromium подтвердил empty-state публичного каталога и отсутствие overflow на 320 px; обычный E2E пропускает bootstrap без явных переменных, отдельный bootstrap с токеном проходит. Остаются HTTP/browser acceptance для неоднозначных и многокомпонентных комплектов, ручной visual review и проверяемый счётчик по категориям либо явный `unknown`. Сетевые тесты не выполнять; импорт оставить opt-in, последовательным и под общим cooldown/backoff.
### Тёмная тема