docs(backlog): close TEST-INFRA-001 / TEST-CONTRACT-001 / TEST-VISUAL-001; open TEST-INFRA-002

Marks all three sprint backlog entries Resolved with sprint commit
references and documented deviations:

- TEST-INFRA-001 (b8d18e6, 82af117, f6509d9, 2dfb1e8) — Playwright
  foundation operational locally. CI deferred.
- TEST-CONTRACT-001 (2dfb1e8) — 409 conflict shape verified against
  real Laravel. Single-context replay instead of two-browser
  concurrent edit; UI rollback assertion deferred to F4.
- TEST-VISUAL-001 (f6509d9) — 5 composite baselines from canonical
  prototype. Composite-over-isolated rationale: prototype DOM lacks
  data-* attributes; isolated artist-name locators would rot. F4
  adds isolated baselines using stable data-test-id.

Opens TEST-INFRA-002 for the deferred CI work: Gitea/GitHub Actions
decision, runner image, caching, screenshot-diff artifacts, label-
gated nightly e2e. No deadline; surfaces when first review cycle
feels drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-10 15:29:33 +02:00
parent 7e21c6a633
commit a2fce268fa

View File

@@ -2304,7 +2304,28 @@ Removed both packages from `apps/app/package.json`, regenerated
**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
### TEST-INFRA-001 — Migrate timetable component+a11y tests to Playwright Component Testing ✅ Resolved
**Status:** Closed in `chore/test-infra-001` (commits `b8d18e6`,
`82af117`, `f6509d9`, `2dfb1e8`). Sprint executed per
RFC-WS-FRONTEND-PRIMEVUE Amendment A-1.
**Resolution:** Playwright + axe-core installed; CT and e2e runners
configured; Git LFS enabled for screenshots; `mountWithProviders`
helper established; full provider stack (Vuetify [TEMPORARY: replaced
in F3], Pinia, TanStack Query, Memory-history Router) wired in
`apps/app/playwright/index.ts`'s `beforeMount` hook. Existing
402 Vitest+jsdom tests left unchanged per amendment §A.3 goal 5
(natural replacement during F4 component migration).
**Deviations from original:**
- **CI integration deferred** to TEST-INFRA-002 — no CI exists in repo
today. Sprint scope cut to "passes locally" per amendment A-1
acceptance terms.
- Provider plugins wired in `playwright/index.ts` rather than at mount
call time (Playwright CT API divergence from `@vue/test-utils`).
Documented in `mountWithProviders.ts` JSDoc and
`dev-docs/ARCH-TESTING.md` §6.
**Aanleiding:** Session 4 follow-up landed component-mount, integration,
keyboard a11y, and axe-core tests on Vitest + jsdom as a deliberate
@@ -2347,7 +2368,28 @@ helper (designed to translate cleanly into Playwright CT's `mount()` API).
---
### TEST-CONTRACT-001 — End-to-end 409 conflict contract test against running Laravel
### TEST-CONTRACT-001 — End-to-end 409 conflict contract test against running Laravel ✅ Resolved
**Status:** Closed in `chore/test-infra-001` commit `2dfb1e8` (B4 of
TEST-INFRA-001 sprint).
**Resolution:** `apps/app/tests/playwright-e2e/timetable/409-conflict.
spec.ts` runs against a real Laravel test server (`php artisan serve
--port=8001`) seeded by `api/database/seeders/E2EBaselineSeeder.php`
via Playwright's `globalSetup`. Test asserts first-move 200 and
second-move 409 with `errors.conflict: 'version_mismatch'`. The
schema-drift bug class that motivated the entry (timetable-
stabilization B5) is now caught end-to-end.
**Deviations from original:**
- **Single-context replay** instead of two-browser-context concurrent
edit. The 409 is server-determined by stored version, not by
session identity, so single-context replay is functionally
equivalent for contract validation. Multi-context concurrent-edit
test is documented in ARCH-TESTING.md §9 as deferred to F4.
- **UI rollback assertion** (popover toast, block snap-back) deferred
to F4 UI-driven e2e — out of scope for B4 contract test.
- CI integration deferred to TEST-INFRA-002.
**Aanleiding:** The 409 rollback path in `useTimetableMutations.move()`
is currently asserted against a mocked axios response shape (Session 4
@@ -2379,7 +2421,42 @@ contract-protection value per line of test code.
---
### TEST-VISUAL-001 — Visual regression baselines for PerformanceBlock states
### TEST-VISUAL-001 — Visual regression baselines for PerformanceBlock states ✅ Resolved
**Status:** Closed in `chore/test-infra-001` commit `f6509d9` (B3 of
TEST-INFRA-001 sprint).
**Resolution:** 5 composite baselines captured from the canonical
prototype at `resources/Crewli - Artist Timetable Management/
crewli-timetable.html` (note: actual filename, not "Crewli Timetable.
html" as referenced in the older Aanleiding section below). Tests
live in `apps/app/tests/playwright-ct/visual/prototype.spec.ts`,
PNGs at `apps/app/tests/playwright-ct/__screenshots__/visual/
prototype.spec.ts/`. Tracked via Git LFS.
| Baseline | Captures |
| ----------------------------- | --------------------------------------------------- |
| `canvas-friday.png` | Status colors, B2B indicators, multi-lane stacking |
| `canvas-saturday.png` | Conflict ring, capacity warning |
| `stage-row-multilane.png` | First row in isolation |
| `wachtrij-populated.png` | Sidebar list, status badges, counts |
| `popover.png` | Block-click popover layout |
**Deviations from original 8-state-minimum scope:**
- Composite-over-isolated strategy. Prototype DOM exposes status only
via inline `style.background`, no `data-*` attributes. Isolated-
block locators by artist name would lock tests to specific seed
data. Composite captures yield the same visual vocabulary in fewer
more stable images. Documented in `dev-docs/ARCH-TESTING.md` §4.
- 9 surfaces from RFC §A.3's enumerated list documented as
`test.skip()` with gap reasons (cancelled status absent from
prototype data, drag-mode flaky under simulated pointer events,
empty-state surfaces unreachable from canonical seed). All
deferred to F4 isolated component-level baselines using stable
`data-test-id` attributes.
- Pixel tolerance `maxDiffPixelRatio: 0.001` (0.1%) per RFC §A.6.
- Linux+Chromium only per RFC §A.5; no Mac/Windows baselines.
- CI integration deferred to TEST-INFRA-002.
**Aanleiding:** Status badge colors, capacity icon presence, B2B dots,
conflict ring, and cascade-pulse animation are UX contracts encoded in
@@ -2421,6 +2498,64 @@ TEST-CONTRACT-001.
---
### TEST-INFRA-002 — CI integration for Playwright + visual + e2e
**Aanleiding:** TEST-INFRA-001 sprint scope was cut to "passes
locally" because no CI exists in this repo today. The test
infrastructure is operational on developer machines (Vitest 402,
Playwright CT smoke + sanity + 5 visual baselines, e2e 409
contract test) but no automated gate prevents drift over time.
**Wat:**
- **Decision:** Gitea Actions vs. GitHub Actions vs. self-hosted
runner. Determines runner image availability, secrets management,
and pipeline DSL. No deadline; surface when first review cycle
feels drift without automated tests.
- **Runner image** with PHP 8.2+ (composer, ext-bcmath, ext-zip),
MySQL 8 (or service container), Node v22, pnpm 10, Chromium for
Playwright. Probably layered on top of a stock `ubuntu-22.04`
image with explicit installs to keep image size predictable.
- **Caching strategy:**
- `pnpm-store` keyed on `pnpm-lock.yaml` hash
- `vendor/` keyed on `composer.lock` hash
- `~/.cache/ms-playwright` keyed on Playwright version
- `__screenshots__/` cached locally for diff base; fetched via
Git LFS on baseline tests
- **Pipeline jobs (suggested):**
1. `lint+typecheck` — pnpm lint, pnpm typecheck (fast lane)
2. `vitest` — pnpm test (fast lane, runs in parallel with #1)
3. `playwright-component` — pnpm test:component (medium lane,
after #1+#2 pass)
4. `playwright-visual` — pnpm test:visual (medium lane, parallel
with #3). Diff PNGs uploaded as artifacts on failure; PR
comment with diff summary if runner supports it.
5. `playwright-e2e` — pnpm test:e2e (slow lane). Likely **label-
gated** or **nightly only**, not on every PR. Requires MySQL
service + Laravel server; ~10× more expensive than CT.
6. `phpunit` — composer test (medium lane). Independent of #3-#5.
- **Screenshot-diff artifact upload** — failing visual tests upload
expected.png + actual.png + diff.png as job artifacts. PR comment
links to artifact download.
- **Branch protection** — pre-merge required: lint, typecheck,
vitest, playwright-component, playwright-visual, phpunit. e2e
optional gate.
- **E2E DB strategy in CI** — fresh `crewli_test` per workflow run
via `make test-db-create` then `migrate:fresh + seed` from
globalSetup. No state shared across runs (unlike local
development).
**Trigger:** No explicit deadline. Surfaces when first review cycle
feels drift without automated tests, OR when first regression slips
through the local-only gates, OR when team scales beyond solo
maintainer.
**Refs:** RFC-WS-FRONTEND-PRIMEVUE Amendment A-1 §A.7 DoD-17/19
deferral; `chore/test-infra-001` sprint commits `b8d18e6`-`2dfb1e8`
(local infrastructure operational); `dev-docs/ARCH-TESTING.md` §5
(CI strategy stub).
---
### ART-S4-UX-PARITY — Timetable UX parity with prototype
**Aanleiding:** Manual browser testing after `fix/timetable-stabilization`