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.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
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. |