AccessLens
An accessibility regression scanner that catches WCAG violations before they ship.
← Back to WorkProblem
Accessibility regressions are quiet. A fix ships, it breaks again weeks later, and the first sign is a support ticket, long after the check that should have caught it.
What I built
I built a Playwright + axe-core route crawler that fingerprints each WCAG finding deterministically and diffs it against a baseline that changes only through an explicit accept command. Coverage-aware comparisons prevent an unscanned route from being treated as resolved. GitHub Actions runs the scanner in CI, and a static dashboard reads report JSON entirely in the browser.
Why it matters
It turns accessibility from a one-off audit into a repeatable quality gate, the same discipline teams already apply to test coverage or type safety.
Result
CI fails on genuinely new violations, not ones already known and triaged. Findings stay filterable by status, route, rule, severity, and component in a dashboard that runs entirely client-side, with a live public demo anyone can open.
Architecture
- Route crawler configurable per project: entry points, auth states, exclusions, plus bounded same-origin discovery
- Versioned SHA-256 fingerprints normalize each finding so it is recognized across runs even as others change
- A baseline is created only through an explicit accept command; ordinary scans stay baseline-read-only
- Diffing is coverage aware: an unscanned route is never implied to be resolved
- Static, zero-backend dashboard: JSON reports are validated and inspected entirely in the browser, never uploaded


Testing & reliability
Fingerprinting logic is tested against fixture pages with known violations to guard against false new/resolved classifications. GitHub Actions runs the ordinary CLI against a controlled demo app and a committed baseline on every push, uploading JSON and HTML reports even when the run fails, so a coherent failure is never silent.
Stack
- TypeScript
- Playwright
- axe-core
- Next.js
- GitHub Actions