diff --git a/dev-docs/BACKLOG.md b/dev-docs/BACKLOG.md index 793d9e69..0c24878d 100644 --- a/dev-docs/BACKLOG.md +++ b/dev-docs/BACKLOG.md @@ -2303,3 +2303,131 @@ Removed both packages from `apps/app/package.json`, regenerated "Forms" + `dev-docs/VUEXY_COMPONENTS.md` "Form validation" row. **Refs:** Session 4 follow-up Step 1; `apps/app/src/components/timetable/AddPerformanceDialog.vue` and `apps/app/src/components/sections/CreateShiftDialog.vue` as canonical references. + +### TEST-INFRA-001 — Migrate timetable component+a11y tests to Playwright Component Testing + +**Aanleiding:** Session 4 follow-up landed component-mount, integration, +keyboard a11y, and axe-core tests on Vitest + jsdom as a deliberate +intermediate step. JSDOM does not faithfully reproduce browser layout, +PointerEvents-with-capture, drag-threshold semantics, or computed CSS +visual properties (color contrast resolution). For a module whose core +surface is drag/resize/lane-stacking/pixel-coordinates, jsdom-based +assertions are necessary but not sufficient. + +**Wat:** +- Open branch `feat/playwright-ct-foundation` after the timetable PR merges. +- Install `@playwright/experimental-ct-vue` (and Playwright runners). +- Build the equivalent of `apps/app/tests/utils/mountWithVuexy.ts` for + Playwright CT (Vuetify, Pinia testing, QueryClient, router, token + CSS injection). +- Migrate to `apps/app/tests-pw/component/`: + - `PerformanceBlock.test.ts` + - `StageRow.test.ts` + - `Wachtrij.test.ts` + - `AddPerformanceDialog.test.ts` + - `useTimetableMutations.test.ts` (drag-threshold assertions especially benefit) + - `keyboard.test.ts` + - `axe.test.ts` +- Migrate `tests/integration/timetable-flow.test.ts` to `apps/app/tests-pw/integration/`. +- Keep Vitest + jsdom for `tests/unit/` only (pure-logic + Zod + simple composables). +- CI strategy: Playwright CT runs on every PR (slow lane); Vitest unit + on pre-commit (fast lane). + +**Trigger:** **Before opening the Sessie 5 prompt.** Sessie 5 builds +Engagement Detail (6 tabs, complex form state) and Portal pages +(drag-to-reorder, file uploads). Adding more jsdom-based component +tests for those surfaces compounds the migration cost. + +**Refs:** Session 4 follow-up commits `5f135ec`..`985a5ab`, +RFC-TIMETABLE D14/D20/D21, the new `apps/app/tests/utils/mountWithVuexy.ts` +helper (designed to translate cleanly into Playwright CT's `mount()` API). + +--- + +### TEST-CONTRACT-001 — End-to-end 409 conflict contract test against running Laravel + +**Aanleiding:** The 409 rollback path in `useTimetableMutations.move()` +is currently asserted against a mocked axios response shape (Session 4 +follow-up Step 9 + Step 12). A frontend Zod schema drift vs. the backend's +actual `StaleVersionException` serialization would not be caught — only +the unit test's mocked shape is validated. For a contract that protects +against multi-user collisions (RFC D14), the integration must be verified +against the actual backend. + +**Wat:** +- After TEST-INFRA-001 lands the Playwright foundation, add + `apps/app/tests-pw/e2e/timetable-409-conflict.spec.ts`. +- Spin up Laravel via `php artisan serve` in the test setup (or use the + existing test-DB seeded against `crewli_test`). +- Seed two browser contexts authenticated as the same organizer. +- Both load the same timetable; both attempt to `POST /timetable/move` + on the same performance with the same `version` value. +- Assert: first request succeeds (200, returns new version + cascaded[]); + second request fails (409 with the actual backend conflict shape); + frontend correctly rolls back and shows the conflict toast. +- Validate the response shape parses against `MoveTimetableConflictResponse` + Zod — this is the contract proof. + +**Trigger:** First e2e flow added after TEST-INFRA-001 lands. Highest +contract-protection value per line of test code. + +**Refs:** RFC-TIMETABLE D14, Session 4 follow-up Step 4 +(zodParseFailure regression) + Step 9 (mocked 409). + +--- + +### TEST-VISUAL-001 — Visual regression baselines for PerformanceBlock states + +**Aanleiding:** Status badge colors, capacity icon presence, B2B dots, +conflict ring, and cascade-pulse animation are UX contracts encoded in +CSS tokens (RFC D21, D22, D25, D26). The Vitest+jsdom component tests +assert that the right token *resolves* (Step 6's getComputedStyle +roundtrips) but a developer changing token values, border widths, +padding, or animation timing would not trigger a test failure even +though the visual contract is broken. + +**Wat:** +- After TEST-INFRA-001 lands, add `apps/app/tests-pw/visual/PerformanceBlock.spec.ts`. +- Render PerformanceBlock in each documented state: option, confirmed, + contracted, cancelled; with/without capacity warn; with/without B2B + dots; with/without conflict ring; mid-cascade-pulse. +- Use Playwright's `toHaveScreenshot()` with locked viewport size and + font rendering. +- Commit baseline PNGs to `apps/app/tests-pw/visual/__screenshots__/`. +- CI fails on diff > 0.1% pixel delta. Diffs trigger a manual review and + baseline update if the change was intentional. +- Pin font hinting and OS rendering: run visual tests only on Linux CI + runners (consistent rendering across Mac/Windows is expensive — Linux + baseline is sufficient). + +**Trigger:** Second addition to the TEST-INFRA-001 sprint. After +TEST-CONTRACT-001 (contract-first, visual-regression-second). + +**Refs:** RFC-TIMETABLE D21, D22, D25, D26. + +--- + +### ART-S4-TESTS — Session 4 test coverage closure ✅ Resolved + +**Status:** Closed by the Session 4 follow-up branch +(commits `5c53dcd` through `985a5ab`). + +VeeValidate removed (VEE-001). CSS tokens moved to `.css` for jsdom-time +loadability. `mountWithVuexy` helper + axe-core dev dep + segmented +vitest configs landed. Zod runtime parsing wired into all timetable +queries + mutations with regression tests. `?day` query is now the +source of truth via `useActiveDay` composable with corrective fallback +for missing / invalid / cross-org IDs. Component tests cover +PerformanceBlock visuals + interactions, StageRow lane stacking, +Wachtrij rendering + drag, AddPerformanceDialog validation + submit. +useTimetableMutations 409 + idempotency-key semantics tested. +Keyboard a11y model fully covered (RFC D20). axe-core scans clean on +the user-facing surfaces (two real bugs surfaced + fixed inline: +VProgressLinear missing aria-label, dialog close button missing +aria-label). Full add → drag → resize → park → delete integration flow +verified through the mutation composable. + +Test count delta: 252 → 385 (+133 across the two PRs). + +Follow-up sprints: TEST-INFRA-001 (Playwright CT migration), +TEST-CONTRACT-001 (real-backend 409), TEST-VISUAL-001 (visual regression).