Тестирование доступности с axe-core
axe-core — библиотека от Deque Systems для автоматизированного тестирования доступности (WCAG 2.1/2.2). Запускается в браузере и в Node.js, интегрируется с Jest, Playwright, Cypress и Storybook. Автоматически находит ~57% нарушений доступности.
Интеграция с Jest + Testing Library
npm install --save-dev jest-axe @testing-library/react
// __tests__/accessibility.test.tsx
import { render } from '@testing-library/react';
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
describe('Доступность компонентов', () => {
it('Button не имеет нарушений', async () => {
const { container } = render(<Button>Отправить</Button>);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
it('Form не имеет нарушений', async () => {
const { container } = render(
<form>
<label htmlFor="email">Email</label>
<input id="email" type="email" />
<button type="submit">Войти</button>
</form>
);
const results = await axe(container, {
rules: {
'color-contrast': { enabled: true },
'label': { enabled: true },
},
});
expect(results).toHaveNoViolations();
});
});
Интеграция с Playwright
// tests/accessibility.spec.ts
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test('Главная страница проходит WCAG 2.1 AA', async ({ page }) => {
await page.goto('/');
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21aa'])
.exclude('.cookie-banner') // Исключаем компоненты третьих сторон
.analyze();
expect(results.violations).toEqual([]);
});
test('Форма регистрации — доступность', async ({ page }) => {
await page.goto('/register');
const results = await new AxeBuilder({ page })
.include('#registration-form')
.analyze();
// Детальный отчёт при падении
if (results.violations.length > 0) {
console.table(results.violations.map(v => ({
id: v.id,
impact: v.impact,
description: v.description,
nodes: v.nodes.length,
})));
}
expect(results.violations).toEqual([]);
});
Интеграция со Storybook
npm install --save-dev @storybook/addon-a11y
// .storybook/main.js
module.exports = {
addons: ['@storybook/addon-a11y'],
};
// В stories
export default {
component: Button,
parameters: {
a11y: {
config: {
rules: [{ id: 'color-contrast', enabled: true }],
},
},
},
};
Программный запуск в браузере
// Для аудита произвольной страницы через консоль
import axe from 'axe-core';
axe.run(document, {
runOnly: { type: 'tag', values: ['wcag2aa'] },
}).then(results => {
console.log('Violations:', results.violations.length);
results.violations.forEach(v => {
console.group(`[${v.impact.toUpperCase()}] ${v.id}`);
console.log(v.description);
v.nodes.forEach(n => console.log(' Element:', n.target[0]));
console.groupEnd();
});
});
Уровни нарушений
| Impact | Значение | Пример |
|---|---|---|
| critical | Блокирует доступ | Изображение без alt |
| serious | Значительно мешает | Форма без label |
| moderate | Затрудняет использование | Недостаточный контраст |
| minor | Небольшое неудобство | Неправильный lang |
Сроки
Настройка axe-core в Jest + Playwright, покрытие ключевых страниц и компонентов: 2–3 рабочих дня.







