Axe-core — это библиотека для автоматизированного тестирования доступности веб-приложений на языке JavaScript. Она позволяет выявлять нарушения стандартов WCAG (Web Content Accessibility Guidelines), ARIA и других спецификаций доступности, обеспечивая интеграцию с современными фреймворками и инструментами тестирования.
Библиотека реализована в виде модульного API, что делает возможным как использование в браузере, так и интеграцию с Node.js, что особенно полезно для CI/CD процессов. Основным принципом работы является сканирование DOM и анализ его на соответствие правилам доступности.
Для Node.js:
npm install axe-core --save-dev
Для браузера достаточно подключить скрипт через CDN:
<script src="https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.6.3/axe.min.js"></script>
После подключения можно использовать глобальный объект
axe для выполнения аудита страницы.
axe.runМетод axe.run является центральным инструментом
библиотеки. Он выполняет сканирование страницы или указанного элемента
DOM и возвращает результаты аудита в формате JSON.
Пример использования в браузере:
axe.run(document, {
runOnly: {
type: 'tag',
values: ['wcag2a', 'wcag2aa']
}
}).then(results => {
console.log(results.violations);
});
Ключевые параметры:
Promise).Каждое правило в Axe-core можно включать, отключать или изменять его параметры. Это позволяет фокусироваться на конкретных проблемах или игнорировать ложные срабатывания.
Пример настройки правил:
const options = {
rules: {
'color-contrast': { enabled: true },
'image-alt': { enabled: false }
}
};
axe.run(document, options).then(results => {
console.log(results.violations);
});
Также доступны теги правил, которые позволяют группировать проверки:
wcag2a, wcag2aa, wcag2aaa —
уровень соответствия WCAG.best-practice — общие рекомендации по качеству кода и
структуры DOM.experimental — экспериментальные проверки, находящиеся
в стадии тестирования.Результаты сканирования включают три ключевых раздела:
Пример вывода:
{
"violations": [
{
"id": "color-contrast",
"impact": "serious",
"description": "Контраст текста недостаточен для пользователей с нарушениями зрения",
"nodes": [
{
"html": "<button style='color: #aaa;'>Click</button>",
"target": ["button"]
}
]
}
]
}
Axe-core хорошо интегрируется с инструментами типа Jest, Cypress, Mocha:
import 'cypress-axe';
cy.visit('http://localhost:3000');
cy.injectAxe();
cy.checkA11y();
cy.injectAxe() — внедряет библиотеку в контекст
страницы.cy.checkA11y() — выполняет аудит и выводит результаты в
консоль Cypress.const { axe, toHaveNoViolations } = require('jest-axe');
expect.extend(toHaveNoViolations);
test('страница должна быть доступной', async () => {
const results = await axe(document.body);
expect(results).toHaveNoViolations();
});
Axe-core позволяет создавать собственные проверки, которые соответствуют внутренним стандартам компании или проектным требованиям. Каждое правило определяется объектом с ключевыми полями:
Пример пользовательского правила:
axe.configure({
rules: [
{
id: 'no-empty-buttons',
selector: 'button',
check: (node) => node.textContent.trim() !== '',
message: 'Кнопки не должны быть пустыми'
}
]
});
Для крупных страниц и динамического контента важна оптимизация:
Promise позволяет не блокировать интерфейс
пользователя.Внедрение Axe-core в процесс непрерывной интеграции позволяет выявлять проблемы доступности на ранних стадиях разработки. Часто используется совместно с GitHub Actions, Jenkins или GitLab CI:
- name: Run accessibility tests
run: |
node run-axe-tests.js
Скрипт run-axe-tests.js запускает аудит всех страниц
проекта и генерирует отчет в формате JSON или HTML для анализа командой
QA.
Axe-core поддерживает форматы вывода:
Пример генерации HTML-отчета:
const fs = require('fs');
const { htmlReport } = require('axe-html-reporter');
axe.run(document).then(results => {
const report = htmlReport(results);
fs.writeFileSync('accessibility-report.html', report);
});
Axe-core эффективно работает с динамическими интерфейсами, такими как одностраничные приложения (SPA). Для этого используется:
axe.run
после обновления контента.Пример с React:
import { useEffect } from 'react';
import axe from 'axe-core';
function App() {
useEffect(() => {
axe.run(document.body).then(results => {
console.log(results.violations);
});
}, []);
return <div>Контент приложения</div>;
}