Skip to content
Back to skills

Qa Accessibility

ASecurity

[Testing] WCAG 2.2 AA accessibility audit: POUR + 2.2 additions, axe-core injection, Lighthouse MCP, keyboard walk, ARIA.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 20, 2026
testingrustgonodetesting

Works with

  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add VirtoCommerce/vc-mcp-testing-module --skill qa-accessibility --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Qa Accessibility?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Qa Accessibility
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/virtocommerce-qa-accessibility/badge)](https://www.skillsdirectory.com/skills/virtocommerce-qa-accessibility)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: qa-accessibility
description: "[Testing] WCAG 2.2 AA accessibility audit: POUR + 2.2 additions, axe-core injection, Lighthouse MCP, keyboard walk, ARIA."
argument-hint: "page URL | component name | full audit"
---

# /qa-accessibility — WCAG 2.2 AA Accessibility Audit

Run an accessibility audit against **WCAG 2.2 Level AA** (the 2026 practical baseline — 2.2 is the current W3C Recommendation since 2023-10-05 and is backward-compatible with 2.1; 4.1.1 Parsing was retired). Covers POUR plus the six new 2.2 AA criteria (Focus Not Obscured, Dragging Movements, Target Size Minimum, Consistent Help, Redundant Entry, Accessible Authentication).

> **The six 2.2 additions are manual-first.** Automated tooling covers only **2.5.8 Target Size** (nascently); the other five — 2.4.11, 2.5.7, 3.2.6, 3.3.7, 3.3.8 — **cannot be caught by axe** and must be verified in the keyboard/manual pass. A clean axe run says nothing about them.

## Usage
```
/qa-accessibility https://example.com/checkout    # Audit a specific page
/qa-accessibility ProductCard                      # Audit a component (delegate to /qa-storybook)
/qa-accessibility full audit                       # Full site audit: homepage, sign-in, catalog, PDP, cart, checkout, account
```

## Supporting Files

- **wcag-accessibility-checklist.md** — Complete WCAG 2.2 AA checklist organized by POUR, plus the six new 2.2 criteria, dynamic-state rescans, manual-only items, agent automation recipes (axe-core injection, Lighthouse, keyboard walk, contrast from computed style), and pitfalls.

## Boundary with `/qa-storybook`
- `/qa-storybook` — a11y addon **inside stories** (component-isolated; tune axe rules per component).
- `/qa-accessibility` — full-page audits against storefront/admin (keyboard journeys across landmarks, page-level contrast, modal focus return, dynamic ARIA announcements).
- A finding that reproduces in a single story belongs to `/qa-storybook`. A finding that only appears once composed into a page (focus order across landmarks, skip-link target, modal portal escape) belongs here.

## Execution

1. **Determine audit scope:**
   - Specific page URL → audit that page across the dynamic states list in the checklist
   - Component name → delegate to `/qa-storybook` instead
   - Full audit → P0 routes: `/`, `/sign-in`, `/search`, PDP, `/cart`, `/checkout`, `/account/orders`. Skip-link and consent banner must be tested first (they affect every page).

2. **Theme scope:** Run a11y assertions on the **Coffee** *and* **Red** presets — those are this project's two WCAG-gated themes. Red joined the set with the Red Theme 4 release (VCST-4226) once VCST-5555 cleared the UI-kit violations; verify it under `themePreset:red`. Capture the remaining presets for visual diff only, not a11y gating — `purple-pink` and `watermelon` still fail AA on the solid-accent token and would produce known-unsupported failures.

3. **Delegate to ui-ux-expert** via Task tool (`subagent_type: ui-ux-expert`):
   - Pass scope, URL(s), and reference to `wcag-accessibility-checklist.md`
   - Agent uses **Chrome DevTools MCP** for `lighthouse_audit`, `evaluate_script` (to inject axe-core and run it), `take_screenshot` (focus states), and the network/console capture
   - For multi-browser parity: re-run keyboard walk on `playwright-firefox` and `playwright-edge`

4. **Run the four-layer scan per route:**
   - **Layer A — axe-core (programmatic):** Use the canonical `axeRunSnippet()` from `scripts/lib/axe-runner.ts` — pass it verbatim to `evaluate_script` (it self-loads axe if absent, runs WCAG A/AA tags only, trims the result). **Await it** (returns a Promise), then `classifyAxeResults()` maps impact→severity and surfaces `incomplete` as WARN-for-manual-review (best-practice already excluded). **If `axeAvailable === false` (CSP blocked the load) the result is INCONCLUSIVE — never report it as clean.** Don't hand-roll the injection — the extracted snippet is the single source.
   - **Layer B — Lighthouse a11y category:** Call `lighthouse_audit` MCP and read the accessibility category. Lighthouse runs a subset of axe (~50 rules) — use for trend score, **never** as the only signal.
   - **Layer C — keyboard walk:** Press Tab through the page; after each press capture `document.activeElement` with `ACTIVE_ELEMENT_SNIPPET` (from `scripts/lib/axe-runner.ts`) into an ordered trail, then `classifyKeyboardTrail(trail)` flags traps (P0), off-screen focus (FAIL), and non-monotonic order (WARN). Verify Escape closes modals and focus returns to the trigger.
   - **Layer D — dynamic rescans:** Re-run Layer A after each significant state change (modal open, accordion expand, form error displayed, toast shown, mega-menu opened, async route load). Scanning only the initial DOM is the #1 cause of missed real bugs.

5. **POUR checklist (per WCAG 2.2 AA)** — the 2.2 additions marked `[MANUAL]` cannot come from axe; verify them by hand in the keyboard pass:
   - **Perceivable:** Alt text, color contrast ≥ 4.5:1 / 3:1 (UI ≥ 3:1), text resizing to 200%, reflow at 320px, time-based media captions.
   - **Operable:** Keyboard nav, focus indicators, no traps, skip links, **2.4.11 Focus Not Obscured `[MANUAL]` (sticky elements must not cover focused field)**, **2.5.7 alternative to drag `[MANUAL]`**, **2.5.8 target size ≥ 24×24 CSS px, touch targets included** (44×44 is 2.5.5 AAA — advisory, never an AA FAIL). For composite widgets, exercise the widget-specific keys (arrows/Home/End/Escape) against the matching **ARIA APG** pattern.
   - **Understandable:** Lang attributes, consistent nav, error identification and helpful messages, **3.2.6 Consistent Help placement `[MANUAL]`**, **3.3.7 Redundant Entry `[MANUAL]` (don't re-ask for known data)**, **3.3.8 Accessible Authentication `[MANUAL]` (no cognitive-function tests without alternative; password managers must work)**.
   - **Robust:** ARIA name/role/value for custom controls, state changes announced (aria-live, aria-expanded). Note: 4.1.1 Parsing was removed in 2.2 — don't report duplicate-ID issues against it.
   - **EAA (public storefront):** confirm a **published, linked accessibility statement** exists (footer / T&Cs). Its absence is a **P1** compliance finding — flag it even when axe is clean (see Rules → EU exposure).

6. **Output:**
   - Audit report with pass/fail per criterion + measured values (contrast ratios, target sizes, focus-order delta from visual order)
   - Group findings by **severity** (Critical / Serious / Moderate / Minor — match axe-core severity) and **WCAG criterion ID** (e.g., `1.4.3`, `2.4.11`)
   - **Deduplicate by pattern, don't enumerate instances.** Collapse repeated violations of the same rule on the same component family into **one** entry with an instance count (`color-contrast — VcButton ×14`), not 14 rows. Repeated low-impact violations of one rule are usually a **single root-cause fix** — report the fix once. Listing every instance blows the `reports.md` size caps and buries the signal.
   - **If a single route's scan returns more than ~50 violations, STOP and report the top patterns instead of the full list** — a 200-line dump isn't actionable; surface the ~3 highest-impact patterns and ask whether to go deeper.
   - **Locate every finding precisely** — never fabricate a source location. Pin each to the first available of: `data-test-id` (see `.claude/knowledge/automation/storefront-selectors.md`) → `role` + accessible name → DOM path / tree position. Use the tag/role/label the keyboard walk already captured; if a finding can't be located, say so ("located by selector only").
   - Explicit **"Requires manual verification"** section listing what automation cannot decide (alt-text quality, focus visibility quality, screen-reader narrative coherence, cognitive load, form-error helpfulness, modal focus-trap correctness on edge transitions, aria-live timing)
   - Bug reports follow `.claude/rules/reports.md` (hard cap 80–150 lines per bug); include WCAG criterion ID, measured vs required values, and one annotated screenshot

## Rules
- **WCAG 2.2 AA is the gate** — not 2.1, not 3.0. APCA may be cited as an *advisory* signal for designer review but never as a pass/fail (no scanner enforces APCA in 2026).
- **WCAG 3.0 is horizon-only.** It is a **March-2026 Working Draft** (W3C Accessibility Guidelines — 174 outcome-based *requirements*, graded scoring, final Recommendation est. **2028–2030**). Track it; never audit or gate against it in 2026.
- **The six 2.2 additions are manual-first** — only 2.5.8 Target Size has (nascent) axe support; **2.4.11 / 2.5.7 / 3.2.6 / 3.3.7 / 3.3.8 must be verified in the keyboard/manual pass** and never assumed clean from an axe PASS.
- **Automated PASS is necessary but not sufficient** — axe catches roughly **20–40%** of real WCAG issues (it reliably catches the six dominant failures: low contrast, missing alt text, missing form labels, empty links, empty buttons, missing document language). Always pair with a manual keyboard pass and an explicit "manual verification needed" section.
- **Test keyboard navigation, not just visual rendering** — the agent must walk Tab order programmatically and assert against expected DOM sequence.
- **Color contrast from computed CSS only** — never eyeball. Compute from `getComputedStyle` color + effective background; assert WCAG 2.x luminance ratio (4.5:1 normal text, 3:1 large/UI/focus indicator).
- **Custom interactive elements** (dropdowns, modals, tabs, comboboxes) need a full ARIA audit — name, role, value, expanded/selected/pressed states. Use the **ARIA Authoring Practices Guide (APG)** patterns as the oracle for expected keyboard interaction + roles/states, and **ARIA-AT** for expected screen-reader output; a widget that diverges from its APG pattern is a finding even if axe passes.
- **Filter axe `best-practice` tag** — those are advisory, not WCAG failures. Treating them as conformance bugs creates noise and erodes the team's trust in the report.
- **Group by pattern, not instance** — one entry per (rule ID × component family) with a count, not one row per DOM node. >~50 violations on a route → report top patterns and stop, don't dump. Locate each finding by `data-test-id` → role + accessible name → DOM path; never invent a `file:line`.
- **Re-scan dynamic states** — modal open, accordion expand, form-error displayed, toast shown, async chunk loaded. Initial-DOM-only scanning misses most real bugs in SPA storefronts.
- **EU exposure:** The **European Accessibility Act (EAA)** has been enforceable since 2025-06-28; its technical standard is **EN 301 549** (references WCAG 2.1 AA — auditing to 2.2 AA is a safe superset). Treat public-storefront a11y violations as P0/P1 for any EU-reachable site. **Check for a published, linked accessibility statement** (footer / T&Cs) describing conformance status and known barriers — a missing statement is the single most-cited enforcement trigger (French/Swedish surveillance) and is itself a **P1** finding, independent of the scan result.

Files in this skill

  • SKILL.md10.9 KB
  • wcag-accessibility-checklist.md16.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…