From accessibility-test-scanner
Validate WCAG compliance and accessibility standards (ARIA, keyboard navigation). Use when auditing WCAG compliance or screen reader compatibility. Trigger with phrases like "scan accessibility", "check WCAG compliance", or "validate screen readers".
npx claudepluginhub flight505/skill-forge --plugin accessibility-test-scannerThis skill is limited to using the following tools:
Validate web applications against WCAG 2.1/2.2 accessibility standards covering perceivability, operability, understandability, and robustness. Combines automated scanning with axe-core, Pa11y, and Lighthouse accessibility audits alongside manual validation checklists for keyboard navigation, screen reader compatibility, and color contrast.
Applies Acme Corporation brand guidelines including colors, fonts, layouts, and messaging to generated PowerPoint, Excel, and PDF documents.
Enforces four-phase systematic debugging: root cause investigation via error reading, reproduction, change checks, and multi-component logging before any fixes for bugs, tests, or issues.
Share bugs, ideas, or general feedback.
Validate web applications against WCAG 2.1/2.2 accessibility standards covering perceivability, operability, understandability, and robustness. Combines automated scanning with axe-core, Pa11y, and Lighthouse accessibility audits alongside manual validation checklists for keyboard navigation, screen reader compatibility, and color contrast.
@axe-core/playwright to scan after page load.role="button" on clickable divs).aria-label or aria-labelledby on elements without visible text.aria-live regions announce dynamic content changes.aria-expanded, aria-selected, and aria-checked states toggle correctly.<label> with matching for/id.aria-describedby and aria-invalid.aria-required="true" and visual indicators.| Error | Cause | Solution |
|---|---|---|
| axe-core reports no violations but page is inaccessible | Automated tools catch ~30-40% of issues; manual testing needed | Supplement automated scans with keyboard and screen reader manual testing |
| Color contrast violation on dynamic theme | Theme colors computed at runtime not captured by static scan | Run scans with each theme active (light/dark); test with high-contrast mode |
| False positive on hidden content | Scanner checks elements that are visually hidden but present in DOM | Use axe.configure({ rules: [{ id: 'rule-id', selector: ':visible' }] }) |
| ARIA role conflicts | Multiple conflicting ARIA attributes on same element | Remove redundant roles; follow WAI-ARIA authoring practices for the component pattern |
| Focus order incorrect after dynamic content | DOM insertion order differs from visual order | Use tabindex to correct order; restructure DOM to match visual layout |
Playwright + axe-core accessibility test:
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test('homepage meets WCAG AA', async ({ page }) => {
await page.goto('/');
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21aa'])
.analyze();
expect(results.violations).toEqual([]);
});
test('login form is keyboard accessible', async ({ page }) => {
await page.goto('/login');
await page.keyboard.press('Tab');
const focused = await page.evaluate(() => document.activeElement?.getAttribute('data-testid'));
expect(focused).toBe('email-input');
await page.keyboard.press('Tab');
const nextFocused = await page.evaluate(() => document.activeElement?.getAttribute('data-testid'));
expect(nextFocused).toBe('password-input');
});
Pa11y CI configuration:
{
"defaults": {
"standard": "WCAG2AA",
"timeout": 10000, # 10000: 10 seconds in ms
"wait": 1000 # 1000: 1 second in ms
},
"urls": [
"http://localhost:3000/", # 3000: 3 seconds in ms
"http://localhost:3000/login", # 3 seconds in ms
"http://localhost:3000/dashboard", # 3 seconds in ms
{ "url": "http://localhost:3000/settings", "actions": ["click element #tab-profile"] }
]
}