Тестування доступності з 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'],
};
// У историях
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 робочих дні.







