WCAG 2.2 automated coverage
Every success criterion across WCAG 2.0, 2.1, and 2.2 — and exactly how WCAG Audit detects it. Dynamic checks (keyboard walks, viewport reflow, motion timelapse, multi-page consistency) and AI vision review run alongside axe-core to cover criteria that static DOM inspection alone cannot.
Route coverage
Most accessibility tools can only see what a crawler can reach — roughly 30% of a real application.
Every route gets the same 12 checkers + AI vision review regardless of whether it's behind authentication.
Screen-reader coverage
Most accessibility tools stop at static DOM analysis. WCAG Audit drives real VoiceOver and NVDA to verify your app announces the right thing to blind users. Covered criteria: 4.1.2 (Name, Role, Value), 2.4.6 (Headings and Labels), 1.3.1 (Info and Relationships).
10 criteria auto-fixed by deterministic codemod
When the @wcag-audit/next-plugin is installed, findings for the following criteria are fixed automatically with a deterministic codemod — no LLM call, no manual review needed.
- 1.4.12 — Text Spacing (text-spacing codemod)
- 1.4.3 — Contrast Minimum (contrast codemod)
- 1.1.1 — Non-text Content (alt + image-alt codemods)
- 1.3.1 — Info and Relationships (label + missing-form-label codemods)
- 4.1.2 — Name, Role, Value (button-name codemod)
- 2.4.4 — Link Purpose (link-name codemod)
- 3.1.1 — Language of Page (lang-html codemod)
- 1.4.10 — Reflow (fixed-width-overflow codemod)
Run wcag-audit plugin-init to install the Next.js plugin. Codemods apply on the next scan.
How coverage maps to tools
Chrome Extension + Companion Server + AI
- axe-core on the live DOM (37 rules across 25 criteria)
- Chrome debugger keyboard walk (Tab/Shift-Tab through every control)
- Viewport reflow at 320 CSS px + text-spacing CSS injection
- 10-second motion timelapse for flashes and autoplay
- Multi-tab consistency crawl (3.2.3 / 3.2.4 / 3.2.6)
- Form-submit probing for error identification (3.3.1)
- CAPTCHA detection gated on an actual auth form (3.3.8)
- Claude vision review for color use, headings, images of text
- Server-side augment for authenticated pages (your cookies, never persisted)
CLI + AI
- Same axe-core pass via Playwright Chromium
- Same keyboard / focus-visible / focus-not-obscured walk
- Same reflow, resize-text, text-spacing, hover-content checks
- Same motion timelapse
- Same multi-page consistency crawl (Playwright contexts)
- Same CAPTCHA + form-error probing
- Same Claude vision review (opt-in via --ai)
- Project-aware route discovery (Next.js / Vite / Remix / Astro / SvelteKit)
- Generates WCAG_FIXES.md + Cursor rules + Excel report + AI fix JSON
- Incremental 24h route cache · CI gating via --fail-on critical
Both tools run the same checker engine. A criterion covered by the extension is also covered by the CLI, and vice versa. The differences are packaging (browser vs Node), how they reach authenticated pages, and the downstream artifacts each one produces.
Coverage by checker
Each checker is a single capability that runs across whichever surfaces apply — local DOM probe in the browser, server-side Playwright pass for clean-browser checks, and the cloud-hosted AI vision call. The criteria column is the union across all surfaces, deduped — so axe-core lists every WCAG ID it can flag whether it ran in the extension or via the server.
axe-core
FREEColor contrast, ARIA, names/roles, headings, IDs, lang, landmarks, tables, lists.
Keyboard / focus
PAIDTab walk, focus-visible, focus order, focus-not-obscured.
Viewport
PAIDReflow at 320 CSS px, resize text at 200%, text-spacing override.
Hover & focus / on-input
PAIDTooltips dismissible / persistent / hoverable; no context shifts.
Motion timelapse
PAIDRecords 10s of the page, detects autoplay, marquee, flashes.
Forms
PAIDSubmits forms invalid; checks errors are announced and suggest a fix.
Pointer · Auth · Media
PAIDGestures, motion-actuation, CAPTCHAs, video / audio captions.
Multi-page consistency
PAIDCrawls up to 4 pages and compares nav structure + help mechanism.
Screen-reader walkthrough
BUSINESSDrives real VoiceOver / NVDA to verify announcements.
AI vision · Visual quality
PAIDClaude reviews the screenshot for color use, contrast on gradients, images of text.
AI vision · Structure & navigation
PAIDClaude reviews the DOM/screenshot for landmark structure, link purpose, error prevention.
Filter criteria
All WCAG 2.2 criteria
| # | Criterion | Level | Added | Ext + Srv + AI | CLI + AI | How we detect it |
|---|---|---|---|---|---|---|
| 1.1.1 | Non-text Content | A | 2.0 | Automated | Automated | axe: image-alt, input-image-alt, area-alt, role-img-alt +6 |
| 1.2.1 | Audio-only and Video-only (Prerecorded) | A | 2.0 | Automated | Automated | axe: audio-caption, video-caption dynamic: live browser check Detects <audio>/<video> presence; transcript accuracy is human-only. |
| 1.2.2 | Captions (Prerecorded) | A | 2.0 | Automated | Automated | axe: video-caption, video-caption-missing dynamic: live browser check axe video-caption + DOM probe for <video> with no <track kind=captions>. |
| 1.2.3 | Audio Description or Media Alternative (Prerecorded) | A | 2.0 | Manual | Manual | Human review required |
| 1.2.4 | Captions (Live) | AA | 2.0 | Manual | Manual | Human review required |
| 1.2.5 | Audio Description (Prerecorded) | AA | 2.0 | Manual | Manual | Human review required |
| 1.3.1 | Info and Relationships | A | 2.0 | Automated | Automated | axe: definition-list, dlitem, list, listitem +9 |
| 1.3.2 | Meaningful Sequence | A | 2.0 | Automated | Automated | axe: tabindex dynamic: live browser check Compares DOM order to visual order via bounding boxes. |
| 1.3.3 | Sensory Characteristics | A | 2.0 | Partial | Partial | AI: vision / language review |
| 1.3.4 | Orientation | AA | 2.1 | Automated | Automated | axe: css-orientation-lock |
| 1.3.5 | Identify Input Purpose | AA | 2.1 | Automated | Automated | axe: autocomplete-valid |
| 1.4.1 | Use of Color | A | 2.0 | Automated | Automated | axe: link-in-text-block AI: vision / language review |
| 1.4.2 | Audio Control | A | 2.0 | Automated | Automated | axe: no-autoplay-audio dynamic: live browser check |
| 1.4.3 | Contrast (Minimum) | AA | 2.0 | Automated | Automated | axe: color-contrast, low-placeholder-contrast, low-hover-focus-contrast, text-on-image-background AI: vision / language review |
| 1.4.4 | Resize Text | AA | 2.0 | Automated | Automated | axe: meta-viewport, viewport-zoom-disabled, text-clipped-at-200 dynamic: live browser check Zooms to 200% and checks for content loss / overflow. |
| 1.4.5 | Images of Text | AA | 2.0 | Partial | Partial | AI: vision / language review |
| 1.4.10 | Reflow | AA | 2.1 | Automated | Automated | axe: meta-viewport, fixed-width-overflow, horizontal-body-scroll dynamic: live browser check Viewport meta + DOM probes for fixed-width descendants and body min-width violations. |
| 1.4.11 | Non-text Contrast | AA | 2.1 | Automated | Automated | axe: low-button-contrast AI: vision / language review Custom probe for button text/border contrast; AI vision covers icons and meaningful graphics. |
| 1.4.12 | Text Spacing | AA | 2.1 | Automated | Automated | dynamic: live browser check AI: vision / language review Injects WCAG-required spacing CSS and checks for clipped text. |
| 1.4.13 | Content on Hover or Focus | AA | 2.1 | Partial | Partial | dynamic: live browser check Hovers tooltip triggers and verifies dismissible/persistent/hoverable. |
| 2.1.1 | Keyboard | A | 2.0 | Automated | Automated | axe: frame-focusable-content, scrollable-region-focusable, nested-interactive, keyboard-onclick-no-handler +2 dynamic: live browser check Tabs through every interactive element. |
| 2.1.2 | No Keyboard Trap | A | 2.0 | Automated | Automated | axe: keyboard-trap dynamic: live browser check DOM probe flags modals/dialogs without Escape handler or close button. |
| 2.1.4 | Character Key Shortcuts | A | 2.1 | Partial | Partial | dynamic: live browser check Scans for global single-key keydown listeners. |
| 2.2.1 | Timing Adjustable | A | 2.0 | Automated | Automated | axe: meta-refresh dynamic: live browser check |
| 2.2.2 | Pause, Stop, Hide | A | 2.0 | Automated | Automated | axe: blink, marquee, no-autoplay-audio, auto-rotating-no-pause dynamic: live browser check Catches deprecated blink/marquee + DOM probe for infinite CSS animations without pause control. |
| 2.3.1 | Three Flashes or Below Threshold | A | 2.0 | Partial | Partial | dynamic: live browser check Captures a 10s timelapse and counts large frame-to-frame deltas. |
| 2.4.1 | Bypass Blocks | A | 2.0 | Automated | Automated | axe: bypass, region, landmark-one-main, skip-link +2 |
| 2.4.2 | Page Titled | A | 2.0 | Automated | Automated | axe: document-title AI: vision / language review |
| 2.4.3 | Focus Order | A | 2.0 | Automated | Automated | axe: tabindex dynamic: live browser check axe flags positive tabindex; CLI Tab-walk compares order to visual reading order. |
| 2.4.4 | Link Purpose (In Context) | A | 2.0 | Automated | Automated | axe: link-name, identical-links-same-purpose AI: vision / language review axe catches empty/icon-only links and duplicate-text collisions; AI vision catches ambiguous text like 'click here', 'read more'. |
| 2.4.5 | Multiple Ways | AA | 2.0 | Automated | Automated | dynamic: live browser check AI: vision / language review |
| 2.4.6 | Headings and Labels | AA | 2.0 | Automated | Automated | axe: empty-heading, heading-order, empty-table-header AI: vision / language review |
| 2.4.7 | Focus Visible | AA | 2.0 | Automated | Automated | axe: focus-not-visible dynamic: live browser check AI: vision / language review DOM probe walks stylesheets for outline:none on :focus without a replacement. |
| 2.4.11 | Focus Not Obscured (Minimum) | AA | 2.2 | Automated | Automated | axe: focus-obscured-by-overlay dynamic: live browser check DOM probe checks overlap between fixed/sticky elements and focusable controls. |
| 2.5.1 | Pointer Gestures | A | 2.1 | Partial | Partial | dynamic: live browser check Scans for multi-touch / path gesture event listeners. |
| 2.5.2 | Pointer Cancellation | A | 2.1 | Partial | Partial | dynamic: live browser check Detects elements that act on pointerdown without an undo path. |
| 2.5.3 | Label in Name | A | 2.1 | Automated | Automated | axe: label-content-name-mismatch |
| 2.5.4 | Motion Actuation | A | 2.1 | Partial | Partial | dynamic: live browser check Scans for deviceorientation/devicemotion listeners. |
| 2.5.7 | Dragging Movements | AA | 2.2 | Partial | Partial | dynamic: live browser check |
| 2.5.8 | Target Size (Minimum) | AA | 2.2 | Automated | Automated | axe: target-size |
| 3.1.1 | Language of Page | A | 2.0 | Automated | Automated | axe: html-has-lang, html-lang-valid, html-xml-lang-mismatch, missing-html-lang |
| 3.1.2 | Language of Parts | AA | 2.0 | Automated | Automated | axe: valid-lang AI: vision / language review |
| 3.2.1 | On Focus | A | 2.0 | Partial | Partial | dynamic: live browser check Focuses each control and watches for navigation / context change. |
| 3.2.2 | On Input | A | 2.0 | Automated | Automated | axe: select-onchange-navigates dynamic: live browser check DOM probe flags <select onchange> handlers that navigate or submit; CLI also types into each input live. |
| 3.2.3 | Consistent Navigation | AA | 2.0 | Partial | Partial | dynamic: live browser check Crawls multiple pages and compares navigation structure. |
| 3.2.4 | Consistent Identification | AA | 2.0 | Partial | Partial | dynamic: live browser check |
| 3.2.6 | Consistent Help | A | 2.2 | Partial | Partial | dynamic: live browser check Looks for a help mechanism in the same location across pages. |
| 3.3.1 | Error Identification | A | 2.0 | Automated | Automated | axe: aria-required-attr, aria-invalid-missing dynamic: live browser check AI: vision / language review DOM probe flags inputs with describedby-error but no aria-invalid. AI vision catches color-only error indication. |
| 3.3.2 | Labels or Instructions | A | 2.0 | Automated | Automated | axe: label, form-field-multiple-labels, select-name, input-button-name +1 AI: vision / language review |
| 3.3.3 | Error Suggestion | AA | 2.0 | Partial | Partial | dynamic: live browser check Asks AI whether the error provides a fix suggestion. |
| 3.3.4 | Error Prevention (Legal, Financial, Data) | AA | 2.0 | Partial | Partial | dynamic: live browser check |
| 3.3.7 | Redundant Entry | A | 2.2 | Partial | Partial | dynamic: live browser check Walks multi-step forms and detects duplicate fields. |
| 3.3.8 | Accessible Authentication (Minimum) | AA | 2.2 | Partial | Partial | dynamic: live browser check Detects CAPTCHAs and other cognitive function tests. |
| 4.1.2 | Name, Role, Value | A | 2.0 | Automated | Automated | axe: aria-allowed-attr, aria-allowed-role, aria-command-name, aria-hidden-body +19 AI: vision / language review |
| 4.1.3 | Status Messages | AA | 2.1 | Automated | Automated | axe: aria-allowed-role, aria-valid-attr-value, status-not-announced AI: vision / language review DOM probe flags status/toast elements without role=status / aria-live. |
Use the CLI and the Extension together
The numbers above assume publicly accessible routes. For authenticated pages — dashboards, settings, checkout, admin — roughly 60–75% of real-world a11y violations live behind a login, and the CLI alone cannot reach them without exported auth state.
CLI
Public routes. Project-wide Excel. CI gating. Cursor-ready fixes.
Requires --auth-storage auth.json for auth-gated routes.
Extension + Server
Authenticated pages using your live browser session. Annotated screenshots. Real VoiceOver walk.
Single page at a time. No CI integration.
Running both can detect violations of 52 of 55 WCAG 2.2 Level A + AA criteria. The remaining 3 are media-accessibility quality checks (prerecorded audio description, live captions) that require a human reviewer. Either tool alone leaves gaps.