Библиотека Axe-core предназначена для автоматизированного тестирования доступности веб-приложений. В контексте Single Page Applications (SPA) она становится особенно важной, так как динамически обновляемый DOM требует особого подхода к проверкам.
Для работы с Axe-core в SPA используется стандартная установка через npm:
npm install axe-core
После установки библиотека подключается в проект:
import axe from 'axe-core';
Инициализация стандартная, но в SPA нужно учитывать динамическое изменение DOM:
axe.run(document, {
runOnly: ['wcag2a', 'wcag2aa'], // Проверка по стандартам WCAG
resultTypes: ['violations', 'incomplete']
}, (err, results) => {
if (err) throw err;
console.log(results.violations);
});
Ключевой момент — указать область проверки, так как проверка всего документа при каждом изменении DOM может быть избыточной.
В SPA элементы добавляются и удаляются без полной перезагрузки
страницы. Axe-core предоставляет метод run для повторного
анализа конкретного контейнера:
const container = document.getElementById('app');
axe.run(container, {}, (err, results) => {
if (err) throw err;
handleViolations(results.violations);
});
Рекомендуется запускать проверку после каждого значимого изменения интерфейса:
Для автоматизации часто используют MutationObserver:
const observer = new MutationObserver(() => {
axe.run(document.getElementById('app'), {}, (err, results) => {
if (!err && results.violations.length) {
console.log('Доступность нарушена:', results.violations);
}
});
});
observer.observe(document.getElementById('app'), {
childList: true,
subtree: true
});
Это позволяет автоматически запускать анализ при изменении DOM, минимизируя ручное тестирование.
Axe-core предоставляет гибкую настройку правил:
const config = {
rules: {
'color-contrast': { enabled: false }, // отключение проверки контраста
'label': { enabled: true } // включение проверки наличия label
}
};
axe.run(document, config, (err, results) => {
console.log(results.violations);
});
Можно также добавлять пользовательские правила, например для проверки специфических компонентов SPA:
axe.configure({
rules: [
{
id: 'custom-button-label',
selector: 'button.custom',
any: ['accessible-name'],
enabled: true
}
]
});
react-axe для разработки, чтобы проверять компоненты в
режиме реального времени:import React from 'react';
import ReactDOM from 'react-dom';
import axe from 'react-axe';
if (process.env.NODE_ENV !== 'production') {
axe(React, ReactDOM, 1000);
}
mounted, updated) для анализа динамически
изменяемых элементов.Axe-core возвращает объект с массивом violations, каждая
из которых содержит:
id — уникальный идентификатор правила.impact — степень влияния на доступность (critical,
serious, moderate, minor).description — описание нарушения.help — ссылка на документацию.nodes — массив элементов, где нарушено правило.Пример обработки:
function handleViolations(violations) {
violations.forEach(v => {
console.warn(`Нарушение: ${v.id} (${v.impact})`);
v.nodes.forEach(node => {
console.log('Элемент:', node.target, 'Сообщение:', node.failureSummary);
});
});
}
Для SPA важно минимизировать нагрузку:
runOnly для ограничения проверок нужными
стандартами WCAG.Axe-core легко интегрируется в автоматические тесты через Jest, Cypress или Playwright. В этом случае результаты нарушений можно использовать для прерывания сборки или генерации отчетов, что помогает поддерживать постоянный уровень доступности при развитии SPA.
import { injectAxe, checkA11y } from 'axe-core';
describe('Accessibility tests', () => {
it('should have no violations', async () => {
await page.goto('http://localhost:3000');
await injectAxe(page);
const results = await checkA11y(page);
expect(results.violations.length).toBe(0);
});
});
Использование Axe-core в SPA позволяет системно отслеживать доступность и гарантирует, что динамический интерфейс остаётся соответствующим стандартам WCAG, даже при частых изменениях пользовательского интерфейса.