or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcore-testing.mdindex.mdplugins-frames.mdrules-reporting.mdutilities.md
tile.json

rules-reporting.mddocs/

Rules and Reporting

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.

Capabilities

Get Rules

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 Virtual Rule

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();

Reporter Management

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);
});

Built-in Reporters

Axe-core includes several built-in reporters:

  • v1: Legacy version 1 format
  • v2: Default version 2 format (current standard)
  • raw: Raw results without processing
  • rawEnv: Raw results with environment data
  • no-passes: Results with passing tests filtered out
  • na: Results with not-applicable tests filtered out
// Use different built-in reporters
axe.run(document, { reporter: 'v1' });
axe.run(document, { reporter: 'raw' });
axe.run(document, { reporter: 'no-passes' });

Types

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;
}

Common Rule Tags

Axe-core uses tags to categorize rules. Common tags include:

WCAG Levels:

  • wcag2a, wcag2aa, wcag2aaa
  • wcag21a, wcag21aa, wcag21aaa
  • wcag22a, wcag22aa, wcag22aaa

Categories:

  • cat.color - Color and contrast
  • cat.keyboard - Keyboard accessibility
  • cat.language - Language identification
  • cat.name-role-value - Name, role, and value
  • cat.parsing - HTML parsing and validity
  • cat.semantics - Semantic structure
  • cat.sensory-and-visual-cues - Visual and sensory information
  • cat.structure - Document structure
  • cat.tables - Data table accessibility
  • cat.text-alternatives - Alternative text
  • cat.time-and-media - Time-based media

Best Practices:

  • best-practice - Recommended practices beyond WCAG

Impact Levels:

  • minor - Minor accessibility barriers
  • moderate - Some users may be unable to access content
  • serious - Some users will be unable to access content
  • critical - Blockers that prevent access for many users