page.runAccessibilityTest()
Run an axe-core accessibility audit on the current page and return structured results for use in assertions or test reports.
Runs an axe-core accessibility audit on the current page and returns structured results. Use it to gate builds on accessibility compliance or to surface violations in test reports.
Signature
page.runAccessibilityTest(): Promise<AccessibilityResults>
Return type: AccessibilityResults
type AccessibilityResults = {
violations: Result[]; // Rules that definitively failed
incomplete: IncompleteResult[]; // Rules that need manual review
passCount: number; // Number of rules that passed
ignoredRuleCount: number; // Rules marked inapplicable to this page
totalRuleCount: number; // Total rules evaluated
};
violations and incomplete are standard axe-core result objects. The key fields on each entry are:
type Result = {
id: string; // axe-core rule ID, e.g. 'color-contrast'
impact: 'critical' | 'serious' | 'moderate' | 'minor' | null;
description: string; // Human-readable description of the rule
help: string; // Short summary of the issue
helpUrl: string; // Link to the axe-core documentation for this rule
nodes: NodeResult[]; // Elements on the page that triggered the rule
};
type IncompleteResult = Result; // Same shape; impact may be null for inconclusive checks
type NodeResult = {
html: string; // Outer HTML of the offending element
target: string[]; // CSS selector path to the element
failureSummary: string | undefined; // Why it failed (violations only)
};
Basic usage
import { test, expect } from 'donobu';
test('home page has no accessibility violations', async ({ page }) => {
await page.goto('https://www.example.com');
const results = await page.runAccessibilityTest();
expect(results.violations).toHaveLength(0);
});
Filtering by impact level
const results = await page.runAccessibilityTest();
const criticalViolations = results.violations.filter(
(v) => v.impact === 'critical',
);
if (criticalViolations.length > 0) {
console.log('Critical violations:');
criticalViolations.forEach((v) => {
console.log(` - ${v.id}: ${v.description}`);
v.nodes.forEach((node) => console.log(` HTML: ${node.html}`));
});
}
expect(criticalViolations).toHaveLength(0);
Running after AI interaction
page.runAccessibilityTest() can be called at any point during a test — including after page.ai has navigated to a specific state:
test('settings page is accessible after opening a modal', async ({ page }) => {
await page.goto('https://app.example.com/settings');
await page.ai('Open the "Change password" modal');
const results = await page.runAccessibilityTest();
expect(results.violations).toHaveLength(0);
});
Notes
- The audit runs against the full current page DOM. Dynamic content loaded after the initial navigation is included.
- axe-core tests cover a wide range of WCAG 2.x success criteria. Refer to the axe-core documentation for the full rule list.
incompleteresults are cases where axe-core found a potential issue but cannot definitively classify it as a violation — manual review is recommended for these.