CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-storybook--addon-a11y

Storybook addon that provides comprehensive accessibility testing for UI components using axe-core engine to ensure WCAG compliance

Pending
Overview
Eval results
Files

testing.mddocs/

Testing and Validation

Automated accessibility testing capabilities that run axe-core tests on stories, with support for different execution modes and detailed result reporting.

Capabilities

Accessibility Test Runner

Exported function for executing accessibility tests using axe-core.

/**
 * Executes accessibility tests using axe-core
 * @param input - Optional A11yParameters for configuring the test run
 * @param storyId - The ID of the story being tested
 * @returns Promise resolving to enhanced accessibility test results
 */
function run(
  input?: A11yParameters, 
  storyId: string
): Promise<EnhancedResults>;

The run function can be imported and used directly for custom accessibility testing scenarios:

import { run } from '@storybook/addon-a11y';

// Run accessibility tests programmatically
const results = await run(
  {
    options: {
      rules: {
        'color-contrast': { enabled: true }
      }
    }
  },
  'button--primary'
);

console.log('Violations:', results.violations.length);

The function is also used internally by the addon's afterEach hook and can be triggered manually through the addon panel.

After Each Hook

Automated test execution hook that runs after each story renders.

/**
 * Hook that runs accessibility tests after each story render
 * Automatically called by Storybook's preview system
 */
const afterEach: AfterEach<any> = async ({
  id: storyId,
  reporting,
  parameters,
  globals,
  viewMode,
}) => Promise<void>;

The afterEach hook automatically:

  • Checks if accessibility testing is enabled
  • Runs axe-core tests on the story
  • Reports results through Storybook's reporting system
  • Handles different test modes ('off', 'todo', 'error')
  • Integrates with Vitest for standalone testing

Result Enhancement

Internal utility for enhancing axe-core results with navigation links (not directly exported).

/**
 * Internal utility that augments axe results with debuggable links for Storybook navigation
 * Used internally by the addon to add linkPath properties to results
 * @param results - Raw axe-core test results
 * @param storyId - The story ID for generating navigation links
 * @returns Enhanced results with linkPath properties
 */
// Note: This is an internal utility, not part of the public API
function withLinkPaths(
  results: AxeResults, 
  storyId: string
): EnhancedResults;

The withLinkPaths function is used internally to augment axe-core results with navigation links that allow users to jump directly to violations in the Storybook interface. This enhancement is applied automatically to all test results.

Environment Detection

Exported utilities for detecting test environment and execution context.

/**
 * Detects if running in standalone Vitest mode (outside Storybook)
 * @returns true if running in Vitest standalone mode
 */
function getIsVitestStandaloneRun(): boolean;

/**
 * Detects if running in any Vitest test mode
 * @returns true if running in Vitest environment
 */
function getIsVitestRunning(): boolean;

These utilities can be imported and used to adapt accessibility testing behavior based on the execution environment:

import { getIsVitestStandaloneRun, getIsVitestRunning } from '@storybook/addon-a11y';

// Adapt behavior based on test environment
if (getIsVitestStandaloneRun()) {
  // Running in Vitest outside Storybook - violations should throw errors
  console.log('Running in Vitest standalone mode');
} else if (getIsVitestRunning()) {
  // Running in Vitest but within Storybook context
  console.log('Running in Vitest within Storybook');
} else {
  // Running in regular Storybook mode
  console.log('Running in Storybook');
}

These functions are used internally by the addon to detect test environments and adjust behavior accordingly. In Vitest standalone mode, accessibility violations will throw errors to properly fail tests.

Enhanced Result Types

Enhanced Results

Extended axe-core results with additional metadata and navigation links.

interface EnhancedResults extends Omit<AxeResults, 'incomplete' | 'passes' | 'violations'> {
  incomplete: EnhancedResult[];
  passes: EnhancedResult[];
  violations: EnhancedResult[];
}

interface EnhancedResult extends Omit<Result, 'nodes'> {
  nodes: EnhancedNodeResult[];
}

interface EnhancedNodeResult extends NodeResult {
  linkPath: string;
}

A11Y Report

Union type representing the result of accessibility testing.

type A11YReport = EnhancedResults | { error: Error };

Test Integration

Storybook Integration

The addon integrates seamlessly with Storybook's testing infrastructure:

  • Automatic Execution: Tests run automatically when stories are rendered
  • Reporting Integration: Results are reported through Storybook's reporting system
  • Panel Integration: Results are displayed in the accessibility panel
  • Story Navigation: Violations include links to navigate to specific story elements

Vitest Integration

Special handling for Vitest test environments:

  • Standalone Mode: When running outside Storybook, violations throw errors to fail tests
  • Matcher Extensions: Automatically extends Vitest expectations with toHaveNoViolations matcher
  • Error Propagation: Accessibility violations properly fail test suites

Example Vitest Integration:

// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'jsdom',
  },
});

// test file
import { expect } from 'vitest';
import { run, getIsVitestStandaloneRun } from '@storybook/addon-a11y';

test('component has no accessibility violations', async () => {
  const results = await run({}, 'button--primary');
  
  // Check if running in standalone mode
  if (getIsVitestStandaloneRun()) {
    // In Vitest standalone mode, this will automatically extend expect
    expect(results).toHaveNoViolations();
  } else {
    // Manual assertion for other environments
    expect(results.violations).toHaveLength(0);
  }
});

Rule Configuration

The addon includes default rule configuration to reduce false positives in component testing:

const DISABLED_RULES = [
  // In component testing, landmarks are not always present
  // and the rule check can cause false positives
  'region',
] as const;

Queue Management

The addon includes a queue system to ensure axe-core tests run sequentially:

  • Tests are queued and executed one at a time
  • Prevents concurrent axe-core execution issues
  • Ensures reliable test results in multi-story environments

Error Handling

Comprehensive error handling ensures graceful degradation:

  • Test Failures: Caught and reported through Storybook's reporting system
  • Configuration Errors: Invalid parameters are handled gracefully
  • Environment Issues: Fallback behavior for different execution contexts
  • Axe-core Loading: Handles dynamic import issues and UMD fallbacks

Install with Tessl CLI

npx tessl i tessl/npm-storybook--addon-a11y

docs

configuration.md

index.md

rule-mapping.md

testing.md

ui-components.md

tile.json