Web testing
Facts verified 2026-07-30 by claude-code/2026.07. Generated from the authored source at docs/llm-wiki/web-testing.md — the wiki owns these facts (ADR: D1 of docs/plans/20260811_documentation_system_execution.md). Edit that file, then regenerate: python docs/portfolio/_build/generate_wiki_pages.py.
The suites
- Registry IDs (in
docs/portfolio/_data/tests.yaml):TEST-WEB-01components,TEST-WEB-02API routes,TEST-WEB-03E2E,TEST-E2E-01kavai_server compatibility smokes (the only one markedpassing). - Two Vitest configs:
web/vitest.config.ts(node env,tests/api/, threads pool,VITEST_SHARD, JUnit output) andweb/vitest.components.config.ts(jsdom,tests/components/+tests/integration/, single-threaded for CI memory, excludes unstabledashboard/bounding-box-visualizer/image-viewersuites). - Playwright:
web/playwright.config.ts— Chromium only,webServerauto-bootsnpm run devon :3000 (PLAYWRIGHT_REUSE_EXISTING_SERVER), CI: 2 retries + trace on first retry +PLAYWRIGHT_SHARD.
Commands (from web/)
npm run test:components/test:api/test:e2e; packs:test:e2e:core(@coretag),test:e2e:extras(@extra),test:e2e:m2(M2 acceptance + perf gates: FPS ≥ 30, AI-query P95 < 3 s, FCP < 5 s).test:apisetsSKIP_LOAD_TESTS=1; load tests run deliberately vianpm run test:load.- kavai_server smokes:
pixi run test-e2e-kavai-serverat repo root (scripts/e2e-kavai-server.shboots extern/KavApps kavai_server on :8080, runsask-live-smoke/ask-gallery-smokewithAI_SERVER_URLpointed at it).
Machinery
- Component setup (
tests/components/setup.ts): jest-dom matchers, MSW server (tests/mocks/handlers.tsfakes/api/datasets,/api/ag-ui-chat,/api/systems, …), lucide-react Proxy icon mock. - API tests, two styles — prefer direct handler import with
vi.mockof@/lib/supabase/server/admin(template:tests/api/equipment-positions.test.tswith its chainable PostgREST-ish stub); legacy style fetcheshttp://localhost:3000/api/...and mocks whenCI=true(datasets.test.ts). - Real JWTs:
tests/jwt-utils.ts+vitest-global-setup.tsmint tokens via Supabase magic-link admin API (admin/generate_link). - Playwright auth/fixtures:
tests/global-setup.tssavesplaywright/.auth/storageState.json(+ onboarding user) and provisions org/dataset fixtures; orgs created by specs must be prefixedPlaywrightso the stale sweep deletes leftovers.
Conventions
- Selectors:
data-testidor accessible roles — never CSS classes. - In-code
@registry TS-FE-*headers are legacy; the registry of record istests.yaml(map suites to FRs there, don’t invent newTS-FE-*IDs). - Placement: route handler →
tests/api/, component/hook →tests/components/, journey →tests/e2e/; mock at the boundary (Supabase, external services), never the code under test. - TDD where it makes sense: test-first for route handlers (mocked-handler red/green loop), pure logic, and always for bug fixes (failing repro first); test-after for Cesium/WebGL rendering, E2E journeys, and still-moving UI. Feature rhythm: failing route tests → handler → component tests per UI state → one E2E assertion; route changes also update
swagger.yaml+ the API inventory.