Visual Regression Pipeline
En resumen
Playwright-based visual regression pipeline acting as the design system's second guard layer beyond the hex-token check: 9-project browser/device matrix, deterministic seed data, runtime freeze for time/RNG/animations, CI on every PR with a 0.1 % pixel-diff tolerance and an in-commit-message marker for deliberately accepting new baselines.
Cómo funciona
tools/visual-regression/ houses the Playwright configuration with a projects matrix of 9 (Chromium + Firefox + WebKit × mobile + tablet + desktop). Per-app specs — www.spec.ts, web.spec.ts, admin.spec.ts, app.spec.ts and sys.spec.ts — cover roughly 25 key views; routes shipping in future tasks are marked test.skip behind an env flag so the catalogue can grow without breaking baselines.
Determinism is the hard part of screenshot diffing. tools/visual-regression/seed.py drops and recreates the MongoDB database with pinned ObjectIds, slugs and timestamps before every run; the RNG is seeded to 42 and the now() value is frozen at 2026-01-15T12:00:00Z. A docker-compose.yml at the monorepo root brings up MongoDB, Redis and the petanque-api with healthchecks (the same stack the integration suite reuses). In the browser, freezeRuntime(page) injects an init-script ahead of any application code that pins time, RNG and animations — without it, CSS transitions, lazy avatars and clock-driven UI generate diffs on every run.
The pipeline is a GitHub Actions workflow at .github/workflows/visual-regression.yml triggered on every PR. It caches Playwright browsers and node_modules and parallelises across projects. The break threshold is maxDiffPixelRatio: 0.001 globally, with documented per-test overrides for canvas-heavy views where antialiasing flicker is unavoidable. On failure the workflow uploads an HTML report as the visual-regression-report artefact (14-day retention) and posts a PR comment linking to it.
Baselines update through a deliberate gesture: putting [accept visual baseline] in a commit message tells the workflow to run with --update-snapshots and push the new baselines back to the PR branch, so the bump is reviewable in its own commit. Maintenance routines live in docs/product/design-system/visual-regression.md and tools/visual-regression/README.md. A native mobile screenshot suite using iOS and Android simulators is on the backlog if the web target proves insufficient.
Capacidades clave
- Playwright config with 9-project matrix (Chromium + Firefox + WebKit × mobile + tablet + desktop)
- Per-app spec files covering ~25 key views with test.skip for future routes
- seed.py producing deterministic MongoDB state with pinned IDs, slugs and timestamps
- Docker Compose stack (MongoDB + Redis + API) reused by integration tests
- freezeRuntime(page) init-script pinning time, RNG and animations in the browser
- GitHub Actions workflow on every PR with browser/node_modules caching and parallelism
- 0.1 % global pixel-diff tolerance with documented per-test overrides for canvas/chart views
- [accept visual baseline] commit-message marker triggering --update-snapshots and baseline push-back
- HTML diff report uploaded as 14-day artefact with PR comment on failure
En la práctica
A developer tweaks the dashboard KPI cards to add a sparkline. They push the PR and within minutes the visual-regression workflow flags four diffs across desktop and mobile viewports — three are intentional (the new sparkline) and one is a regression (the card padding shifted by 2 px on Firefox). They open the artefact, see the three-up comparison, fix the padding bug, and push again.
Two diffs remain, both intentional. They amend the commit message to include [accept visual baseline]; the workflow runs --update-snapshots, pushes the new baseline images to the PR branch, and the reviewer can see in a single follow-up commit exactly which screenshots moved. The merge goes in clean — the design system has not drifted, and the Firefox padding bug never reaches production.
Funcionalidades de este subsistema
12| ID | Status | Funcionalidades |
|---|---|---|
| F16.21.01 | Entregado | tools/visual-regression/ med Playwright-config, projects-matris (Chromium + Firefox + WebKit × mobile/tablet/desktop = 9), shared helpers för deterministisk runtime-freeze. ✅ PL-T113 |
| F16.21.02 | Entregado | Spec-filer per app — www.spec.ts, web.spec.ts, admin.spec.ts, app.spec.ts, sys.spec.ts täcker ~25 nyckelvyer. Routes som tillkommer i framtida tasks markeras med test.skip bakom env-flagga. ✅ PL-T113 |
| F16.21.03 | Entregado | tools/visual-regression/seed.py — drop+återskapa MongoDB-databas med pinnade ObjectIds, slugs och tidsstämplar. RNG seedad till 42, frozen now 2026-01-15T12:00:00Z. ✅ PL-T113 |
| F16.21.04 | Entregado | docker-compose.yml i monorepo-roten — MongoDB + Redis + petanque-api med healthchecks; återanvänds av integration-tester. ✅ PL-T113 |
| F16.21.05 | Entregado | Tids-/RNG-/animation-freeze i webbläsaren via freezeRuntime(page) (init-script innan app-kod kör). ✅ PL-T113 |
| F16.21.06 | Entregado | .github/workflows/visual-regression.yml — PR-triggered, parallell, cachar Playwright-browsers + node_modules. Bryter bygget vid > 0.1 % pixel-diff. ✅ PL-T113 |
| F16.21.07 | Entregado | [accept visual baseline]-marker i commit-meddelande tillåter workflow att köra --update-snapshots och pusha nya baselines tillbaka till PR-branchen. ✅ PL-T113 |
| F16.21.08 | Entregado | HTML-rapport (Playwright reporter) laddas upp som GitHub Actions artifact visual-regression-report (14 dagar retention). PR-kommentar med länk vid fail. ✅ PL-T113 |
| F16.21.09 | Entregado | Tolerance-tröskel maxDiffPixelRatio: 0.001 (0,1 %) global, override per-test för canvas/chart-tunga vyer med dokumenterad motivering. ✅ PL-T113 |
| F16.21.10 | Entregado | Maintenance-rutiner i docs/product/design-system/visual-regression.md (lägg till vy, uppdatera baseline, tolerance, beslutstabellen "uppdatera vs inte"). ✅ PL-T113 |
| F16.21.11 | Entregado | Kom-igång lokalt i tools/visual-regression/README.md — quick-start, layout-översikt, troubleshooting-tabell. ✅ PL-T113 |
| F16.21.12 | Planificado | Native mobile-screenshot-suite (iOS/Android-simulator) — separat task om web-target visar sig otillräckligt. Icebox |