@democratize-quality/accessibility-cli
v1.0.1
Published
CLI for accessibility testing — extends playwright-cli with axe-core WCAG scanning, keyboard tests, and compliance reports
Maintainers
Readme
@democratize-quality/accessibility-cli
WCAG accessibility auditing from a single prompt — or zero prompts.
a11y-cli extends @playwright/cli with axe-core WCAG scanning, keyboard navigation testing, and HTML/JSON compliance reports. Invoke it with Claude Code for an AI-guided audit in one prompt, or run it standalone via YAML scripts in CI/CD — no LLM required.
# One command. Axe-core WCAG scan + keyboard navigation + HTML report.
a11y-cli scan https://example.com --wcag-level AA --jurisdiction US --format htmlWhy not just MCP?
| | MCP server | a11y-cli |
|---|---|---|
| Needs a running LLM | Always | Never (YAML mode) |
| CI/CD integration | Not directly | Native (--ci flag, exit codes) |
| Multi-page scripted audits | Manual tool calls | Single a11y-cli script audit.yaml |
| Safety guardrails | None built-in | PreToolUse hook blocks dangerous commands |
| AI workflow included | Bring your own | SKILL ships with the package |
| Reports | Tool response text | Standalone HTML + JSON files |
| Browser state management | Stateless per call | Named sessions across commands |
| Secrets in config | Leak risk | ${ENV_VAR} interpolation enforced |
MCP is a protocol — it gives an LLM access to tools. a11y-cli is an auditor — it gives a human (or a CI runner, or an LLM) a complete, opinionated, safe accessibility testing workflow out of the box.
Key features
- Single
scancommand — axe-core WCAG scan and keyboard navigation in one step, matchingaccessibility_scanbehaviour exactly - YAML script mode — describe a full multi-page audit in YAML and run it unattended, with no LLM in the loop
- Claude Code SKILL — install once, then a single natural-language prompt drives a full audit end-to-end
- Safety hook — a
PreToolUsehook ships with the package; it blockssudo, package installs, destructive filesystem operations, and source-file edits during every audit session - Multi-jurisdiction compliance — legal references for US (ADA/Section 508), NZ (Human Rights Act), AU, CA, EU (EN 301 549), UK, and more
- Device emulation — test WCAG 1.3.4 Orientation, 1.4.4 Resize Text, and 1.4.10 Reflow with
--device,--zoom, and--viewport-width - HTML + JSON reports — standalone compliance reports with screenshots embedded as visual evidence
- CI/CD ready —
--ciflag exits1when violations are found;--rawoutputs machine-readable JSON - REPL — interactive session for exploring a live page before writing a YAML script
Installation
npm install -g @democratize-quality/accessibility-cli
# Install Playwright browsers (first time only)
npx playwright install --with-deps chromiumQuick start
Scan a single page
# WCAG AA scan — axe-core + keyboard + HTML report in one command
a11y-cli scan https://example.com --wcag-level AA --jurisdiction US --format htmlRun a scripted multi-page audit (no LLM)
export APP_USERNAME=standard_user
export APP_PASSWORD=secret_sauce
a11y-cli script examples/saucedemo-audit.yamlOne-prompt audit with Claude Code
Install the SKILL into your Claude Code project once:
a11y-cli install-skillThen in Claude Code, just say:
Audit https://saucedemo.com — full checkout flow, WCAG AA, jurisdiction NZClaude navigates the flow live, builds a YAML script as it goes, and generates a compliance report. The safety hook runs automatically throughout.
CI/CD
# Exits 0 — no violations. Exits 1 — violations found.
a11y-cli scan https://staging.example.com --ci --wcag-level AA --format jsonThe SKILL — AI-guided audits in one prompt
The SKILL is a Claude Code skill definition (skills/accessibility-cli/SKILL.md) that ships inside this package. It teaches Claude how to:
- Open a headed browser and explore the page live
- Resolve stable selectors via
eval(never guesses CSS) - Build a YAML script incrementally during exploration
- Scan every page in the flow with a single
scancommand - Generate an HTML compliance report and close the browser
Install it once per project:
# Copies the skill and hook into your project's .claude/ directory
a11y-cli install-skillWhat gets installed:
.claude/
├── hooks/
│ └── accessibility-safety.js ← PreToolUse safety hook
├── settings.json ← wires the hook to Bash, Edit, Write
└── skills/
└── accessibility-cli/
├── SKILL.md ← main skill definition
└── references/
├── audit-flows.md
├── keyboard-testing.md
├── report-generation.md
└── wcag-scanning.mdThen just describe the audit:
Audit the checkout flow on https://shop.example.com — WCAG AA, jurisdiction AUClaude picks up the SKILL automatically, opens a browser, navigates each step, and hands you a YAML script plus an HTML report.
The safety hook — guardrails without babysitting
A PreToolUse hook intercepts every Bash, Edit, and Write call Claude makes during an audit. It enforces a strict read-only policy:
Always blocked:
| Category | Examples |
|---|---|
| Privilege escalation | sudo, runas |
| Package management | npm install, brew install, pip install, winget, choco |
| Destructive filesystem | rm -rf, rd /s, Remove-Item -Recurse |
| Source code edits | Any .ts, .js, .py, .java, .go, … file |
| Permission changes | chmod, chown, icacls |
| Registry modifications | reg add, reg delete |
| PowerShell RCE | Invoke-Expression, IEX |
Always allowed:
a11y-clicommands- YAML scripts, JSON/HTML reports, Markdown docs
- Files under
./a11y-artifactsand/tmp
The hook is a plain Node.js script — no extra dependencies, works on macOS, Linux, and Windows. If a command is blocked, the agent sees a clear reason and stops; it cannot override the block.
YAML script reference
Run any audit without an LLM:
a11y-cli script my-audit.yaml
a11y-cli script - < my-audit.yaml # stdin
a11y-cli script my-audit.yaml --ci # exit 1 on violationsMinimal structure
version: '1.0'
name: My App Audit
config:
session: my-audit
output_dir: ./a11y-artifacts
wcag_level: AA
jurisdiction: US # controls legal references in the report — required
format: html
steps:
- command: open
url: https://example.com
headed: false # true for local exploration, false for CI
- command: scan
page_name: Home
- command: report
format: html
- command: closeFull checkout flow example
version: '1.0'
name: Saucedemo Full Checkout Accessibility Audit
description: >
WCAG 2.1 AA audit of the complete checkout funnel:
login → inventory → product detail → cart → checkout → confirmation.
config:
session: saucedemo-audit
output_dir: ./a11y-artifacts/saucedemo
wcag_level: AA
format: html
jurisdiction: NZ
# device: iPhone 15 # uncomment to test WCAG 1.3.4 Orientation
# zoom: 200 # uncomment to test WCAG 1.4.4 Resize Text
# viewport_width: 320 # uncomment to test WCAG 1.4.10 Reflow
steps:
- command: open
url: https://www.saucedemo.com/
headed: false
- command: scan
page_name: Login
- command: fill
ref: '#user-name'
value: ${SAUCEDEMO_USERNAME} # never hardcode — use env vars
- command: fill
ref: '#password'
value: ${SAUCEDEMO_PASSWORD}
- command: click
ref: '#login-button'
- command: scan
page_name: Product Listing
- command: click
ref: '#item_4_title_link'
- command: scan
page_name: Product Detail
- command: click
ref: '#add-to-cart'
- command: click
ref: '.shopping_cart_link'
- command: scan
page_name: Cart
- command: click
ref: '#checkout'
- command: scan
page_name: Checkout - Contact Info
- command: fill
ref: '#first-name'
value: Jane
- command: fill
ref: '#last-name'
value: Smith
- command: fill
ref: '#postal-code'
value: '90210'
- command: click
ref: '#continue'
- command: scan
page_name: Checkout - Order Overview
- command: click
ref: '#finish'
- command: scan
page_name: Order Confirmation
- command: report
format: html
include_screenshots: true
- command: closeexport SAUCEDEMO_USERNAME=standard_user
export SAUCEDEMO_PASSWORD=secret_sauce
a11y-cli script examples/saucedemo-audit.yamlSee examples/yaml-script-reference.md for the full command reference.
Command reference
scan [url] — primary audit command
Runs axe-core WCAG checks and keyboard navigation in one step.
a11y-cli scan https://example.com --wcag-level AA --jurisdiction US --format html
a11y-cli scan -s=audit --page-name "Dashboard" # scan current session page
a11y-cli scan https://example.com --ci # exit 1 on violations
a11y-cli scan https://example.com --no-include-keyboard # axe onlykeyboard [url] — standalone keyboard test
a11y-cli keyboard https://example.com
a11y-cli keyboard https://example.com --expected-order "#skip-link" "#nav" "#search"screen-reader · contrast · alt-text · headings · form
Focused checks that feed into the session report.
a11y-cli contrast -s=audit --level AAA
a11y-cli form "#checkout-form" -s=audit
a11y-cli headings -s=auditscript <file> — run a YAML audit
a11y-cli script audit.yaml
a11y-cli script audit.yaml --ci --output-dir ./ci-reportsrepl — interactive session
a11y-cli repl -s=my-sessiona11y> goto https://example.com
a11y> snapshot
a11y> eval "document.title"
a11y> scan
a11y> report --format html
a11y> .exitBrowser automation passthrough
All @playwright/cli commands are available directly:
a11y-cli open https://example.com -s=audit --headed
a11y-cli snapshot -s=audit
a11y-cli snapshot --depth=4 -s=audit
a11y-cli eval "el => el.id" e5 -s=audit
a11y-cli fill "#user-name" [email protected] -s=audit
a11y-cli click "#login-button" -s=audit
a11y-cli screenshot --filename ./out/page.png -s=audit
a11y-cli devices # list device emulation profilesGlobal options
| Flag | Default | Description |
|---|---|---|
| -s, --session | default | Browser session name |
| --output-dir | ./a11y-artifacts | Report and screenshot output directory |
| --format | both | json | html | both |
| --wcag-level | AA | A | AA | AAA |
| --jurisdiction | — | US | NZ | AU | CA | EU | UK | JP | IN | BR | MX | INTERNATIONAL |
| --device | — | Playwright device name, e.g. iPhone 15 |
| --viewport-width | — | Viewport width in pixels — use 320 for WCAG 1.4.10 Reflow |
| --zoom | — | CSS text zoom % — use 200 for WCAG 1.4.4 Resize Text |
| --ci | false | Exit 1 if violations found |
| --raw | false | Machine-readable JSON output |
| --no-screenshots | false | Skip visual evidence capture |
| -v, --verbose | false | Verbose logging |
Report output
a11y-artifacts/
└── session-<timestamp>/
├── scan-Login-<timestamp>.json
├── scan-Dashboard-<timestamp>.json
├── keyboard-Login-<timestamp>.json
├── report-<timestamp>.html ← standalone HTML compliance report
├── report-<timestamp>.json
└── screenshots/
├── evidence-1.png
└── evidence-2.pngHTML reports include: violation summary, WCAG criterion references, jurisdiction-specific legal references, element selectors, remediation guidance, and screenshot evidence.
Requirements
- Node.js >= 18
- Playwright browsers:
npx playwright install --with-deps chromium
License
AGPL-3.0-or-later
