docs(backlog): add TEST-INFRA-001, TEST-CONTRACT-001, TEST-VISUAL-001 with sharp triggers; close ART-S4-TESTS

Three new entries that codify the test-architecture roadmap surfaced
during the Session 4 follow-up:

TEST-INFRA-001 — Migrate timetable component+a11y tests to Playwright
Component Testing. **Trigger: before opening the Sessie 5 prompt.**
Sessie 5 builds Engagement Detail (6 tabs) + Portal pages (drag-to-
reorder, file uploads); adding more jsdom-based tests for those
surfaces compounds the migration cost.

TEST-CONTRACT-001 — End-to-end 409 contract test against running Laravel.
Trigger: first e2e flow added after TEST-INFRA-001 lands. Highest
contract-protection value per line of test code.

TEST-VISUAL-001 — Visual regression baselines for PerformanceBlock
states (RFC D21/D22/D25/D26). Trigger: second addition to the
TEST-INFRA-001 sprint.

ART-S4-TESTS marked  Resolved with the audit trail of all 9 commits
that landed the test coverage closure (252 → 385 tests across both PRs).

.claude-sync/ regenerated by the post-commit hook (gitignored;
re-uploaded to Project Knowledge separately).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 03:57:02 +02:00
parent 985a5ab987
commit a156fe2a53

View File

@@ -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).