Automated accessibility scanning across the five engines - axe-core (primary), pa11y, Lighthouse a11y, WAVE, and IBM Equal Access. Authors and runs axe-core scans via the `axe.run()` JavaScript API or the @axe-core/playwright / @axe-core/cli wrappers, parses `violations[]` into per-rule severity, configures rule disable / disable-by-tag patterns, and emits CI-gateable output; references/ carry the pa11y CLI (htmlcs + axe runners), Lighthouse CI `categories:accessibility` assertions, the WAVE API / overlay, and IBM Equal Access (Section 508) with their verified CLI / API / config. Use for any automated a11y scanner setup - axe-core for JS/TS UI test suites on every PR, and the references for CLI-only, Lighthouse-pipeline, WebAIM-branded, or Section 508 scanning.
72
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Companion reference for axe-a11y. Consult when a regulatory audit requires
WebAIM-branded reports (common in US public-sector / education compliance),
when designers or non-technical reviewers need the visual overlay, when
auditing a third-party site without code access, or to cross-check axe /
pa11y findings. For purely automated CI gating, direct axe (SKILL.md) and
pa11y are simpler and free.
WAVE (Web Accessibility Evaluation Tool) is WebAIM's flagship scanner - distinguished by a visual overlay that places icons directly on the rendered page. It runs via browser extension (manual, visual), the WAVE API (programmatic), or the commercial Stand-Alone API (self-hosted).
WAVE categorizes findings into: errors (definite WCAG failures), alerts (likely issues needing review), features (positive patterns), structural elements (landmarks, headings), HTML5 / ARIA semantics, and contrast errors.
Source-fetch note (2026-05-04): WAVE's documentation lives across
wave.webaim.organdwebaim.org/articles; the API specifics may evolve - verify the current WAVE API v3+ documentation atwave.webaim.org/apibefore authoring CI integrations against specific endpoints.
| Method | Cost |
|---|---|
| Browser extension (Chrome / Firefox / Edge) | Free. |
| WAVE API | Free credits + paid tiers (per WebAIM). |
| Stand-Alone API (self-hosted server) | Commercial license. |
curl 'https://wave.webaim.org/api/request?key=YOUR_KEY&url=https://example.com&reporttype=4'Reporttype 4 returns the full JSON: a statistics block
(errorcount, alertcount, featurecount, ...) and a categories object
(error / alert / feature / structure / html5 / contrast). Per
category, items is keyed by WAVE issue code (e.g. alt_missing,
label_missing, contrast); each entry has description, count,
selectors[], and per-instance xpath / selector / html.
jq triage:
# All error-level codes + counts
jq -r '.categories.error.items | to_entries[] | "\(.key): \(.value.count)"' wave-results.json
# Failing selectors per issue
jq -r '.categories.error.items | to_entries[] | .value.selectors[] | tostring' wave-results.jsonCapture WAVE API JSON per URL and feed it to the gate
(a11y-violation-gate owns the gate logic):
- name: Run WAVE scan via API
env:
WAVE_API_KEY: ${{ secrets.WAVE_API_KEY }}
run: |
for url in https://staging.example.com/ https://staging.example.com/dashboard; do
slug=$(echo "$url" | tr '/:' '__')
curl -sS "https://wave.webaim.org/api/request?key=$WAVE_API_KEY&url=$url&reporttype=4" \
> "wave-$slug.json"
done| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Treating "alerts" as errors | Alerts are flagged for human review, not auto-fail. | Block on errors; route alerts to review. |
| Storing the WAVE API key in config | Key leak; quota theft. | CI secrets only. |
| Running WAVE against production | API hits load production; possible PII leakage in scan data. | Staging / pre-prod only. |
| Using WAVE alone | Different rule coverage; misses some structural / ARIA issues. | Pair with axe for full coverage. |
| Dismissing "contrast errors" | They are SC 1.4.3 violations - definite WCAG failures. | Treat as errors; aggregate via the gate. |