Run automated accessibility tests on URLs or HTML content using axe-core engine to WCAG 2.2 AA standards.
Run automated accessibility testing using axe-core and output violations in raw format or as formatted issues.
Before running accessibility tests, you need the Playwright MCP (Model Context Protocol) server configured in VS Code. This provides the browser automation tools needed to test web pages.
If you don't have Playwright MCP set up, follow these steps:
Install the Playwright extension (if not already installed):
Cmd+Shift+P / Ctrl+Shift+P)Add the Playwright MCP server:
Cmd+Shift+P / Ctrl+Shift+P)OR manually add via:
Verify MCP access (if needed):
To verify Playwright MCP is available, look for these tools in your chat context:
mcp_playwright_browser_navigatemcp_playwright_browser_evaluatemcp_playwright_browser_snapshotIf these tools are not available, you need to complete the setup above.
This skill provides two output modes:
When to use each:
Note: The a11y-issue-writer skill requires the accessibility-issues-template-mcp server. See the a11y-issue-writer skill documentation for details.
mcp_playwright_browser_navigate to load the pageBefore running axe-core:
mcp_playwright_browser_evaluate to inject and run axe-coreWhen outputting raw violations (not delegating to a11y-issue-writer), return:
# Accessibility Test Results: [Site Name]
**URL Tested:** https://example.com
**Date:** [Current Date]
**Tool:** Axe-core 4.8.4 via Playwright
**Browser:** Chromium
**Operating System:** Windows
## Summary Statistics
| Metric | Count |
|--------|-------|
| **Violations** | X |
| **Passes** | X |
| **Incomplete** | X |
| **Inapplicable** | X |
## Violations
[Return the violations array as formatted JSON or summarized table]
This format is ideal for:
When delegating to a11y-issue-writer skill, follow this workflow:
Present results in this order:
# Accessibility Test Report: [Site Name]
**URL Tested:** https://example.com
**Date:** [Current Date]
**Tool:** Axe-core 4.8.4 via Playwright
**Browser:** Chromium
**Operating System:** Windows
## Summary
| Metric | Count |
|--------|-------|
| **Total Violations** | X issues |
| **Rules Failed** | X |
| **Rules Passed** | X |
| **Needs Review** | X |
### Issues by Severity
| Severity | Count | WCAG Level |
|----------|-------|------------|
| **Critical** | X | A |
| **Severe** | X | AA |
| **Minor** | X | Best Practice |
### Issues by Type
| Rule ID | Description | Impact | Count |
|---------|-------------|--------|-------|
| `rule-id` | Description | Impact | X |
After the summary, output each issue using the full template format (see Issue Output Format below).
## Recommendations Summary
| Priority | Action |
|----------|--------|
| **High** | Description of fix |
| **Low** | Description of fix |
mcp_playwright_browser_navigate(url: "https://example.com")
Use mcp_playwright_browser_evaluate with this function to inject axe-core and run the analysis:
async () => {
// Load axe-core if not already present
if (typeof axe === 'undefined') {
const script = document.createElement('script');
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.8.4/axe.min.js';
document.head.appendChild(script);
await new Promise((resolve, reject) => {
script.onload = resolve;
script.onerror = reject;
});
}
// Run axe and return results
const results = await axe.run();
// (Optional) Recommended tags focus for WCAG 2.2 AA mapping
// Note: Tag availability depends on axe-core version.
// const results = await axe.run(document, {
// runOnly: { type: 'tag', values: ['wcag2a','wcag2aa','wcag21aa','wcag22aa'] },
// resultTypes: ['violations','incomplete']
// });
return {
violations: results.violations,
passes: results.passes.length,
incomplete: results.incomplete.length
};
}
This returns JSON with a violations array for output or delegation.
For raw output, present the violations array with summary statistics:
{
"violations": [
{
"id": "color-contrast",
"impact": "serious",
"tags": ["wcag2aa", "wcag143"],
"description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",
"help": "Elements must have sufficient color contrast",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.8/color-contrast",
"nodes": [{ /* node data from axe */ }]
}
],
"passes": 42,
"incomplete": 3,
"inapplicable": 18
}
This is useful when:
For formatted issue output, delegate to the a11y-issue-writer skill:
Delegation workflow:
format_axe_violation from the accessibility-issues-template-mcpExample delegation:
"I found 5 violations. Delegating to a11y-issue-writer skill to format these as standardized issue reports:
- color-contrast (2 instances)
- label (1 instance)
- button-name (2 instances)
Context: URL https://example.com, Browser: Chromium, OS: Windows"
The a11y-issue-writer skill handles all formatting, template retrieval, and validation.
When to delegate:
When to output raw violations:
See the a11y-issue-writer skill documentation for details on issue formatting and templates.
After running axe-core tests, you can enrich results by querying accessibility MCP servers:
wcag-mcp: get-criterion("4.1.2")
→ Returns full SC details, understanding docs, techniques
magentaa11y-mcp: get_web_component("button")
→ Returns acceptance criteria and developer notes
a11y-personas-mcp: get-personas(["blindness-screen-reader-nvda"])
→ Returns persona details showing who is affected
axe-core typically finds only a subset of issues. Always pair results with a short manual pass:
Keyboard + Focus
Zoom / Reflow
Pointer / Touch
Forms
mcp_playwright_browser_navigate + mcp_playwright_browser_evaluate) to run axe-corehttps://cdnjs.cloudflare.com/ajax/libs/axe-core/4.8.4/axe.min.jsmcp_playwright_browser_snapshot for comprehensive testing