Storybook addon that provides comprehensive accessibility testing for UI components using axe-core engine to ensure WCAG compliance
—
Automated accessibility testing capabilities that run axe-core tests on stories, with support for different execution modes and detailed result reporting.
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.
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:
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.
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.
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;
}Union type representing the result of accessibility testing.
type A11YReport = EnhancedResults | { error: Error };The addon integrates seamlessly with Storybook's testing infrastructure:
Special handling for Vitest test environments:
toHaveNoViolations matcherExample 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);
}
});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;The addon includes a queue system to ensure axe-core tests run sequentially:
Comprehensive error handling ensures graceful degradation:
Install with Tessl CLI
npx tessl i tessl/npm-storybook--addon-a11y