petrkindlmann/qa-skillsMIT3 files

Accessibility Testing

>-

Specification
Skill ID
petrkindlmann/qa-skills/accessibility-testing
Publisher
petrkindlmann
Repository
qa-skills
Installs
0
Files
3
License
MIT
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

petrkindlmann/qa-skills/accessibility-testingInstalls these files
  • SKILL.md
  • references/patterns.md
  • references/recipes.md

What this skill tells the agent

<objective> Make an application usable by people who rely on keyboards and assistive technology, and prove it with tests that run in CI. A button that passes toBeVisible() can still be unreachable by keyboard; a page with zero axe violations can still be impossible to operate with a screen reader. Automated tools catch 30-40% of accessibility issues — this skill covers the automated scan plus the keyboard, screen reader, and ARIA-state testing that catch the other 60-70%. </objective>

Discovery Questions

Check .agents/qa-project-context.md first — if it exists, use it as the foundation and skip anything already answered.

Requirements and compliance (sets the target level and audit obligations)

  • What WCAG conformance level is required — A, AA, or AAA? AA is the practical legal default.
  • What laws apply — ADA, EAA/EN 301 549, Section 508, AODA? Each maps to a WCAG level.
  • Is there a VPAT or accessibility statement to maintain, or contractual a11y clauses from enterprise/government customers?

Current state (tells you whether you're auditing or preventing regressions)

  • Has an audit run before? What were the findings, and what's already in the backlog?
  • Does the design system carry accessibility guidance and accessible components?

Testing infrastructure (determines what you can automate vs. must do by hand)

  • Is automated a11y testing already in CI?
  • Which screen readers does the team test with — VoiceOver, NVDA, JAWS, TalkBack?

Core Principles

  1. Automated testing catches 30-40% of issues — no more. axe-core finds missing alt text, low contrast, missing labels, and invalid ARIA. It cannot tell you whether alt text is meaningful, whether tab order is logical, or whether a custom widget is operable. Passing axe is necessary, not sufficient. Crucially, axe ships no automated rule for several WCAG 2.2 success criteria (2.4.11 focus-not-obscured, 2.5.7 dragging movements, and 2.5.8 target-size only partially) — a green axe run does not equal 2.2 AA conformance.
  1. Semantic HTML first, ARIA as last resort. Native elements (<button>, <nav>, <input>, <dialog>) carry built-in semantics, keyboard behavior, and screen reader support. A <div role="button"> also needs tabindex, Enter/Space handlers, focus styles, and ARIA state — all of which a <button> gives you free. Reach for ARIA only when no native element fits.
  1. Test in impact order: keyboard, screen reader, automated. Keyboard issues physically block users from features (highest impact). Screen reader issues confuse with wrong announcements. Automated checks catch the mechanical remainder. Start where the damage is worst, not where the tooling is easiest.
  1. Accessibility is a quality attribute, not a feature. Test it continuously like performance or security — every new component, every PR. Retrofitting accessibility onto a finished product costs 10-100x more because inaccessible patterns get baked into the component library.
  1. Test with real assistive technology. Browser DevTools and axe extensions are dev aids, not substitutes for VoiceOver (macOS/iOS), NVDA (Windows), and TalkBack (Android), which each behave differently. Reserve manual AT passes for complex custom widgets.

Automated Scanning with axe-core + Playwright

Install @axe-core/playwright (the 4.11.x line; it tracks axe-core's major.minor). Wrap it in a reusable checkAccessibility(page, testInfo, options) helper that filters to the WCAG tags ['wcag2a', 'wcag2aa', 'wcag22aa'], attaches the full results JSON to the test for the audit trail, and asserts violations.toHaveLength(0). Loop it over every key page and over interactive states (modal open, menu expanded), not just the default load.

Suppress a rule only with a documented justification (a tracking issue or inline comment) and exclude third-party widgets you don't own rather than disabling the rule globally.

See references/recipes.md for the install command, RGAA tag caveat, the full helper, the page-loop and interactive-state specs, rule suppression, and CI integration.

Manual Testing Checklist

Automated scanning is the floor. These checks need a human (or a keyboard-driven Playwright spec — see references/recipes.md for the keyboard specs).

Keyboard navigation audit

  • [ ] Tab order is logical — left-to-right, top-to-bottom for LTR. No surprise focus jumps.
  • [ ] All interactive elements reachable via Tab / Shift+Tab.
  • [ ] Focus indicator visible on every focused element. No outline: none without a replacement.
  • [ ] Skip link works — first Tab reveals "Skip to main content"; Enter moves focus to <main>.
  • [ ] Enter activates buttons/links; Space activates buttons and toggles checkboxes.
  • [ ] Escape closes modals, dropdowns, tooltips; focus returns to the trigger.
  • [ ] Arrow keys navigate within tabs, menus, radio groups, tree views.
  • [ ] No keyboard traps (modal dialogs intentionally trap until dismissed — that's allowed).
  • [ ] Custom widgets operable without a mouse (sliders, date pickers, drag-and-drop).

Screen reader testing

Screen ReaderOSBrowserFree?
VoiceOvermacOS/iOSSafariYes (Cmd+F5)
NVDAWindowsFirefox/ChromeYes
JAWSWindowsChrome/EdgeNo
TalkBackAndroidChromeYes
  • [ ] Page title announced on navigation.
  • [ ] Headings form a navigable outline (h1 → h2 → h3, no skipped levels).
  • [ ] Images have descriptive alt text (or alt="" for decorative).
  • [ ] Form inputs announce their labels when focused.
  • [ ] Required fields announced as required; errors associated with their input.
  • [ ] Live regions announce dynamic content (toasts, loading states).
  • [ ] Buttons/links announce their purpose (no "click here").

Color contrast and visual

  • [ ] Normal text: 4.5:1 minimum (WCAG AA). Large text (18pt+ / 14pt+ bold): 3:1.
  • [ ] UI components and graphical objects: 3:1 against adjacent colors.
  • [ ] Information never conveyed by color alone — add icons, patterns, or text.

Form and error accessibility

  • [ ] Every input has a visible <label> tied via for/id (placeholder is not a label).
  • [ ] Required fields indicated visually and programmatically (required / aria-required).
  • [ ] Errors use aria-describedby to link to the input and role="alert" to announce.
  • [ ] Focus moves to the first error on submission failure.
  • [ ] Related fields grouped with <fieldset> and <legend>.

WCAG 2.2 Quick Reference

Level A (must fix)

CriterionWhat it meansCommon failure
1.1.1 Non-text ContentImages have alt text<img> without alt
1.3.1 Info and RelationshipsStructure via HTML semantics<div> styled as a heading
2.1.1 KeyboardAll functionality via keyboardCustom widget responds only to mouse
2.4.1 Bypass BlocksSkip navigation linkNo skip link
3.1.1 Language of Page<html lang="en"> setMissing lang
3.3.1 Error IdentificationErrors described in textError shown only by red border
4.1.2 Name, Role, ValueCustom controls expose name/role<div onclick> with no role

Level AA (most common legal requirement)

CriterionWhat it meansCommon failure
1.4.3 Contrast (Minimum)4.5:1 normal, 3:1 largeLight gray on white
1.4.4 Resize TextScales to 200% without lossFixed-height containers clip text
1.4.11 Non-text ContrastUI components 3:1Low-contrast input borders
2.4.7 Focus VisibleKeyboard focus visibleoutline: none with no replacement
2.5.8 Target SizeTouch targets 24×24px minTiny icon buttons
3.3.2 Labels or InstructionsInputs have labelsPlaceholder as the only label

Use this skill in a project

Open any RiverX project, search the Skills panel for petrkindlmann/qa-skills/accessibility-testing, and install it in one click.

Use this skill