test(web): playwright e2e for key flows + axe a11y smoke (#95) - #238
test(web): playwright e2e for key flows + axe a11y smoke (#95)#238ydimitrof wants to merge 1 commit into
Conversation
Adds a Playwright E2E lane covering the critical explorer flows (search, list filtering, CSV export, contract detail, pagination, mobile nav) and an axe accessibility smoke over the key pages, wired into CI. The suite is hermetic: e2e/seed.mjs seeds an isolated D1 (raw entities + domain contracts) and runs precompute.sql to build the read model, so it never touches the developer's dev DB and needs no EOP import. The dev server runs under E2E=1 with remote bindings off (no Cloudflare login) on a dedicated port. The a11y gate blocks new serious/critical violations; the two pre-existing ones (definition-list, nested-interactive) are baselined and tracked to midt-bg#71/midt-bg#73.
There was a problem hiding this comment.
Прегледах стриктно — стабилен е и тестовете са реални, no cheater tests: seed-ът вкарва 20 договора (> PAGE_SIZE.contracts = 15), така че списъкът винаги пагинира и има ≥1 ред → detail/pagination наистина се изпълняват, а не се no-op-ват. Wiring-ът е коректен end-to-end: seed → .wrangler/e2e-state = E2E клона на vite.config.ts (порт 5273, remoteBindings:false), test:e2e = node e2e/seed.mjs && playwright test сийдва преди Playwright, а CI инсталира chromium. scripts/precompute.sql реално строи FTS search_index, тъй че search пътят е реално покрит. a11y baseline-ът за дълга #71/#73 е добър модел — блокира нови serious/critical регресии без да пада на нескоуп-нат дълг.
Две неща, нито едно не блокира:
1) Документация сочи несъществуващ файл (should-fix). Три коментара представят e2e/global-setup.ts като сийдъра, но такъв файл няма:
vite.config.ts(E2E клонът): „seeded by e2e/global-setup.ts"playwright.config.ts(заглавен коментар): „a hermetic D1 (seeded by e2e/global-setup.ts)".github/workflows/ci.yml(стъпката e2e): „test:e2e is self-contained: e2e/global-setup.ts migrates + seeds…"
Реалният механизъм е test:e2e скриптът; самият seed.mjs в заглавието си обяснява ЗАЩО умишлено не е globalSetup (Playwright транспилира setup файловете в cache dir и мести relative --persist-to). Отделно, webServer коментарът в playwright.config.ts казва „already seeded (pnpm setup)" — това сочи dev базата (.wrangler/state), не херметичния e2e-state. Разработчик ще си загуби времето да търси този файл — предлагам да изравните коментарите с реалния поток.
2) test.skip(count === 0) маскира регресии (optional nit). В pagination.spec.ts и в a11y „contract detail" skip-guard-ът не може легитимно да се задейства при този детерминиран seed (20 > 15 → винаги ≥2 страници и ≥1 ред). Значи единственото, което би ги накарало да skip-нат, е счупен селектор на пейджъра/реда — тоест реална регресия се превръща в тих зелен skip вместо fail. Предлагам да assert-ват наличие (напр. await expect(next).toBeVisible()) вместо да skip-ват, щом seed-ът гарантира данните.
Иначе — чиста работа. Коментар, не блокирам.
|
Critical (регресия извън обхвата на този test-only PR): Коментарът на main изрично казва „It MUST be a build-time value". Без блока Поправка: върни (Останалото по lane-а е издържано — hermetic seed с fail-loud проверка, Turnstile-gated chat правилно изключен. Само коментарите сочат несъществуващи |
|
Този клон е в конфликт с |
What & why
Closes #95. Adds the first committed automated E2E for the explorer, plus an axe accessibility smoke — for a government site a11y is effectively mandatory (ties to #71/#73), and until now Playwright QA was only ever run by hand.
Complements the test work already in flight: #93 (coverage), #94/#177 (integration), #99 (golden dataset).
Coverage
Critical user flows (from the issue):
main)/contracts.csvstreams a valid CSV)How it runs (hermetic)
pnpm test:e2eis self-contained:e2e/seed.mjsmigrates + seeds an isolated D1 (.wrangler/e2e-state, never the dev DB) with raw entities + 20 domain contracts, then runs the realscripts/precompute.sqlto build every rollup and the FTS index — the same read model production serves, with no EOP import.E2E=1: dedicated port (5273) andremoteBindings:false, so Workers AI / Vectorize don't force a remote-proxy login. The assistant is not exercised.A new
e2ejob in.github/workflows/ci.ymlinstalls chromium and runs the lane; the Playwright HTML report uploads on failure.a11y gating
The smoke blocks new serious/critical violations. The two pre-existing ones —
definition-list(home) andnested-interactive(list) — are baselined ina11y.spec.tsand tracked to #71/#73; remove them there as those land.Verification
pnpm test:e2e→ 10/10 green, stable (chromium + mobile-chrome)pnpm --filter @sigma/web typecheckcleanpnpm lint(prettier) clean