Commit graph

2 commits

Author SHA1 Message Date
senke
68f8e9b501 feat(a11y): WCAG 2.1 AA axe-core scan in CI (v1.0.10 ops item 12)
Adds tests/e2e/24-axe-wcag.spec.ts — a Playwright spec running
@axe-core/playwright (already in deps) against home, login, register,
dashboard, discover, and search. The test fails on any "serious" or
"critical" axe violation at WCAG 2.1 AA conformance level ; "moderate"
and "minor" violations are logged for backlog visibility but don't
gate the build.

What this catches that 11-accessibility-ethics.spec.ts (heuristic
checks) misses :
- Color-contrast violations across the entire DOM
- ARIA role / state mismatches
- Form fields without programmatic labels
- Focus-trap errors in modals
- Heading-order regressions

Wiring :
- New @a11y test tag + npm script "e2e:a11y"
- .github/workflows/e2e.yml runs e2e:a11y after e2e:critical on
  every PR + push (~30s overhead).
- Toast portals excluded ([data-sonner-toaster], .toast-container)
  to avoid false positives on transient color-contrast.
- Failure prints rule ids + impact + node count so the cause is
  visible in the CI log without artifact retrieval.

Lighthouse/LHCI was previously removed (security audit A06) —
axe-core is the modern recommended replacement and is what the
WCAG 2.1 AA conformance ask actually needs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 23:57:29 +02:00
senke
f23d23cf2b feat(ci): add E2E Playwright workflow + runbook (v1.0.8 C2 + C5)
Closes the second-to-last item of Batch C (after C3 reuseExistingServer
and C4 seed --ci flag landed earlier). Wires the existing Playwright
suite (60+ spec files in tests/e2e/) into Forgejo Actions.

Workflow shape (.github/workflows/e2e.yml):
- pull_request → @critical only (5-7min target, 20min timeout)
- push to main → full suite (~25min target, 45min timeout)
- nightly cron 03:00 UTC → full suite, catches infra drift
- workflow_dispatch → full suite, manual trigger

Single job structure with conditional steps based on github.event_name.
The job:
  1. Boots Postgres / Redis / RabbitMQ via docker compose.
  2. Runs Go migrations.
  3. `go run ./cmd/tools/seed --ci` — the lean seed landed in C4
     (5 test accounts + 10 tracks + 3 playlists, ~5s).
  4. Builds + starts the backend with APP_ENV=test plus
     DISABLE_RATE_LIMIT_FOR_TESTS=true and the lockout-exempt
     emails matching the auth fixture.
  5. `playwright install --with-deps chromium`.
  6. `npm run e2e:critical` (PR) or `npm run e2e` (push/cron).
  7. Uploads the Playwright HTML report + backend log on failure
     (7-day retention, sufficient for triage).

The `CI: "true"` env var is set workflow-wide so playwright.config.ts
(line 141, 155) sees `process.env.CI` and flips reuseExistingServer
to false, guaranteeing a fresh backend + Vite per job.

Secrets fall back to dev defaults (devpassword / 38-char dev JWT /
guest:guest@localhost:5672) so a fresh repo runs without configuring
secrets first; production-style runs should set `E2E_DB_PASSWORD`,
`E2E_JWT_SECRET`, `E2E_RABBITMQ_URL` in Forgejo Actions secrets.

Runbook (docs/CI_E2E.md):
- Trigger / scope / target time table.
- Step-by-step explanation of what a CI run does.
- Required secrets + their fallbacks.
- "Reproducing a CI failure locally" — exact mirror of the workflow
  invocation so a dev can rerun without pushing.
- "Debugging a red run" — where to look in the Forgejo UI, what the
  artifacts contain, when to check SKIPPED_TESTS.md.
- "Adding a new E2E test" — fixture usage, when to tag @critical.

Action pin SHAs match the rest of the workflows (consistent supply-
chain hygiene). Go 1.25 (matches ci.yml backend job, NOT the older
1.24 used in the disabled accessibility.yml template).

Remaining Batch C item: C6 — flake stabilisation (~3-5 of the 22
SKIPPED_TESTS.md entries that look fixable). Defer to a follow-up
session — wiring the workflow first means the next push-to-main run
will tell us empirically which @critical tests are flaky in CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 23:51:33 +02:00