Files
atomic-design-poc/docs/project/archive/backlog/WP-01-axe-ci-gate.md
T
ehoandClaude Opus 5 12f17d9d73 docs: archive the finished backlogs (RD-30)
Two backlog trees are complete: `docs/project/backlog/` (75 files, every
WP done) and `docs/project/refactor-backlog-setup/` (the arc before it).
Move both under `docs/project/archive/` with `git mv`, so history stays
intact through `git log --follow`. `SHOWCASE-ROADMAP.md` moves with them,
because it points at the now-archived backlog README.

Add `docs/project/archive/README.md`. It states that these trees are
historical and names the two directories that are still live.

Repoint every inbound reference named in RD-30's Files table: CLAUDE.md,
the root README, both backend READMEs, `LetterHtml.cs`, `a11y.mdx`, the
`document-feature` and `new-ssp` skills, and the readable-codebase PLAN,
README, and RD-19 ticket. Fix two upward-relative links inside the moved
WP files (WP-68, WP-69) that gained a directory level and would otherwise
break. Repoint `.prettierignore`'s two agent-prompt exclusions to their
new path, so prettier keeps leaving those files' exact wording alone.

Mark RD-30 done and check off its acceptance criteria; flip its README
row to done.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 23:00:38 +02:00

3.6 KiB

WP-01 — Axe-on-every-story CI gate

Status: done (97f7de4) Phase: 0 — enforcement & gates

Why

The Storybook a11y addon (@storybook/addon-a11y, configured in .storybook/preview.ts for wcag2a, wcag2aa, wcag21a, wcag21aa) only surfaces violations interactively. Nothing gates CI. This WP turns "a panel you can look at" into "a check that fails the build", so every story added or changed by later WPs is automatically covered.

Read first

  • .storybook/main.ts, .storybook/preview.ts (existing a11y config — reuse its tags)
  • .github/workflows/ci.yml (job layout to extend)
  • package.json (scripts; note .npmrc has legacy-peer-deps=true)

Decisions (pre-made, don't relitigate)

  • Mechanism: @storybook/test-runner + axe-playwright against the static build. The repo uses @storybook/angular on the webpack builder, which rules out @storybook/addon-vitest (Vite-only). Fallback if test-runner doesn't support Storybook 10 yet: a hand-rolled Playwright + axe-core loop over storybook-static (same gate semantics — document the swap in this file if taken).
  • Escape hatch: parameters: { a11y: { disable: true } } per story, allowed only with an inline justification comment and a cross-reference to the WP that will fix it (WP-16/WP-17).

Files

  • package.json (devDependencies + scripts)
  • .storybook/test-runner.ts (new)
  • .github/workflows/ci.yml (new job)
  • Possibly a handful of story/component files for triaged violations

Steps

  1. Check version fit first: npm view @storybook/test-runner peerDependencies and pick the release matching the installed Storybook 10 (legacy-peer-deps absorbs minor lag).
  2. npm i -D @storybook/test-runner axe-playwright http-server wait-on concurrently (+ npx playwright install chromium locally).
  3. .storybook/test-runner.ts:
    • preVisit: injectAxe(page).
    • postVisit: getStoryContext(page, context); skip when parameters.a11y?.disable === true; else checkA11y(page, '#storybook-root', …), honoring parameters.a11y.config/options.runOnly from preview.ts (don't duplicate the tag list — read it from the story context).
  4. Scripts:
    • "test-storybook": "test-storybook"
    • "test-storybook:ci": "concurrently -k -s first -n sb,axe \"http-server storybook-static -p 6006 --silent\" \"wait-on tcp:127.0.0.1:6006 && test-storybook --url http://127.0.0.1:6006\""
  5. CI job storybook-a11y in ci.yml: checkout → setup-node (same version as the frontend job) + npm cache → npm cinpx playwright install --with-deps chromiumnpm run build-storybooknpm run test-storybook:ci.
  6. Run locally against a fresh build-storybook; triage violations: fix trivial ones (labels, roles, contrast via --rhc-* tokens); anything structural gets the escape hatch + comment + WP cross-ref.
  7. Update docs/project/backlog/README.md: GREEN now includes npm run test-storybook:ci.

Acceptance criteria

  • npm run test-storybook:ci passes locally against a fresh storybook-static/.
  • CI has a storybook-a11y job; an axe violation makes it fail (verified once with a deliberately broken story, then reverted).
  • Every a11y.disable skip carries a justification comment + WP cross-ref.
  • Backlog README GREEN updated.

Verification

GREEN + npm run test-storybook:ci.

Out of scope

Fixing structural a11y issues in components (WP-16/WP-17); Playwright e2e page sweeps (explicitly not chosen).

Risks

  • test-runner ↔ Storybook 10 peer mismatch → use the documented fallback.
  • Unknown violation count on first run → the escape hatch keeps the WP bounded.