Rule management and result reporting functionality for filtering, customizing, and formatting accessibility results. This includes functions for querying available rules, running individual rules, and managing result reporters.
Retrieve metadata for rules, optionally filtered by tags.
/**
* Searches and returns rules that contain a tag in the list of tags
* @param tags - Optional array of tags to filter by
* @returns Array of rule metadata objects
*/
function getRules(tags?: string[]): RuleMetadata[];Usage Examples:
// Get all available rules
const allRules = axe.getRules();
console.log(`Total rules: ${allRules.length}`);
console.log('First rule:', allRules[0]);
// Get WCAG 2.1 AA rules
const wcag21AARules = axe.getRules(['wcag21aa']);
console.log('WCAG 2.1 AA rules:', wcag21AARules.length);
// Get critical impact rules
const criticalRules = axe.getRules(['cat.critical']);
console.log('Critical rules:', criticalRules);
// Get specific categories
const colorRules = axe.getRules(['cat.color']);
const keyboardRules = axe.getRules(['cat.keyboard']);
const structureRules = axe.getRules(['cat.structure']);
// Multiple tags (rules must have ALL specified tags)
const wcagAAKeyboard = axe.getRules(['wcag2aa', 'cat.keyboard']);
console.log('WCAG AA keyboard rules:', wcagAAKeyboard);Run a single rule against a virtual node.
/**
* Run a single rule against a virtual node
* @param ruleId - ID of the rule to run
* @param node - Virtual node to test
* @param options - Optional rule-specific options
* @returns Raw result for the rule execution
*/
function runVirtualRule(ruleId: string, node: VirtualNode, options?: any): RawResult;Usage Examples:
// Setup virtual tree first
const virtualTree = axe.setup();
// Run specific rule on a node
const colorContrastResult = axe.runVirtualRule(
'color-contrast',
virtualTree,
{ noScroll: true }
);
console.log('Color contrast result:', colorContrastResult);
// Run accessibility rule on specific element
const button = document.querySelector('button');
const buttonVirtual = axe.setup(button);
const buttonNameResult = axe.runVirtualRule('button-name', buttonVirtual);
console.log('Button name result:', buttonNameResult);
// Check heading structure
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
headings.forEach(heading => {
const headingVirtual = axe.setup(heading);
const result = axe.runVirtualRule('heading-order', headingVirtual);
if (result.violations?.length) {
console.log('Heading issue:', heading, result);
}
});
// Don't forget to cleanup
axe.teardown();Functions for managing result reporters that format and output test results.
/**
* Check if a reporter is registered
* @param reporterName - Name of the reporter to check
* @returns True if reporter exists, false otherwise
*/
function hasReporter(reporterName: string): boolean;
/**
* Get a reporter function by name
* @param reporterName - Name of the registered reporter
* @returns Reporter function
*/
function getReporter<T>(reporterName: string): AxeReporter<T>;
/**
* Register a new reporter, optionally setting it as the default
* @param reporterName - Name for the new reporter
* @param reporter - Reporter function
* @param isDefault - Whether to set as default reporter (optional)
*/
function addReporter<T>(
reporterName: string,
reporter: AxeReporter<T>,
isDefault?: boolean
): void;Usage Examples:
// Check for existing reporters
console.log('Has v2 reporter:', axe.hasReporter('v2'));
console.log('Has custom reporter:', axe.hasReporter('my-reporter'));
// Get and use a reporter
const v2Reporter = axe.getReporter('v2');
// Note: reporters are typically called internally by axe.run
// Add custom reporter
axe.addReporter('simple', (rawResults, options, resolve, reject) => {
try {
const violations = rawResults
.filter(result => result.result === 'failed')
.map(result => ({
rule: result.id,
impact: result.impact,
nodeCount: result.nodes.length,
description: result.description
}));
resolve({
violationsCount: violations.length,
violations: violations,
url: window.location.href,
timestamp: new Date().toISOString()
});
} catch (error) {
reject(error);
}
});
// Use custom reporter
axe.run(document, { reporter: 'simple' }).then(results => {
console.log('Simple results:', results);
});
// Add reporter as default
axe.addReporter('detailed', (rawResults, options, resolve) => {
const processed = {
summary: {
violations: rawResults.filter(r => r.result === 'failed').length,
passes: rawResults.filter(r => r.result === 'passed').length,
incomplete: rawResults.filter(r => r.result === 'incomplete').length,
inapplicable: rawResults.filter(r => r.result === 'inapplicable').length
},
details: rawResults
};
resolve(processed);
}, true); // Set as default
// Now 'detailed' will be used by default
axe.run().then(results => {
console.log('Detailed results:', results);
});Axe-core includes several built-in reporters:
// Use different built-in reporters
axe.run(document, { reporter: 'v1' });
axe.run(document, { reporter: 'raw' });
axe.run(document, { reporter: 'no-passes' });interface RuleMetadata {
ruleId: string;
description: string;
help: string;
helpUrl: string;
tags: string[];
actIds?: string[];
}
interface RawResult {
id: string;
result: 'passed' | 'failed' | 'incomplete' | 'inapplicable';
pageLevel: boolean;
impact: 'minor' | 'moderate' | 'serious' | 'critical' | null;
nodes: RawNodeResult[];
description: string;
help: string;
helpUrl: string;
tags: string[];
inapplicable: never[];
passes: RawNodeResult<'passed'>[];
incomplete: RawNodeResult<'incomplete'>[];
violations: RawNodeResult<'failed'>[];
}
interface RawNodeResult<T extends 'passed' | 'failed' | 'incomplete' = any> {
node: SerialDqElement;
any: RawCheckResult[];
all: RawCheckResult[];
none: RawCheckResult[];
impact: 'minor' | 'moderate' | 'serious' | 'critical' | null;
result: T;
}
interface RawCheckResult {
id: string;
impact: string;
message: string;
data: any;
relatedNodes?: SerialDqElement[];
}
interface SerialDqElement {
source: string;
nodeIndexes: number[];
selector: string[];
xpath: string[];
ancestry: string[];
}
type AxeReporter<T = any> = (
rawResults: RawResult[],
options: RunOptions,
resolve: (report: T) => void,
reject: (error: Error) => void
) => void;
interface VirtualNode {
actualNode?: Node;
shadowId?: string;
children?: VirtualNode[];
parent?: VirtualNode;
attr(attr: string): string | null;
hasAttr(attr: string): boolean;
props: { [key: string]: any };
boundingClientRect: DOMRect;
}
interface RunOptions {
runOnly?: RunOnly | string[] | string;
rules?: RuleObject;
reporter?: string;
resultTypes?: string[];
selectors?: boolean;
ancestry?: boolean;
xpath?: boolean;
absolutePaths?: boolean;
iframes?: boolean;
elementRef?: boolean;
frameWaitTime?: number;
preload?: boolean | PreloadOptions;
performanceTimer?: boolean;
pingWaitTime?: number;
}
interface RunOnly {
type: 'rule' | 'rules' | 'tag' | 'tags';
values: string[];
}
interface RuleObject {
[ruleId: string]: {
enabled: boolean;
};
}
interface PreloadOptions {
assets: string[];
timeout?: number;
}Axe-core uses tags to categorize rules. Common tags include:
WCAG Levels:
wcag2a, wcag2aa, wcag2aaawcag21a, wcag21aa, wcag21aaawcag22a, wcag22aa, wcag22aaaCategories:
cat.color - Color and contrastcat.keyboard - Keyboard accessibilitycat.language - Language identificationcat.name-role-value - Name, role, and valuecat.parsing - HTML parsing and validitycat.semantics - Semantic structurecat.sensory-and-visual-cues - Visual and sensory informationcat.structure - Document structurecat.tables - Data table accessibilitycat.text-alternatives - Alternative textcat.time-and-media - Time-based mediaBest Practices:
best-practice - Recommended practices beyond WCAGImpact Levels:
minor - Minor accessibility barriersmoderate - Some users may be unable to access contentserious - Some users will be unable to access contentcritical - Blockers that prevent access for many users