Тестирование доступности помогает убедиться, что пользовательский интерфейс доступен для всех, включая людей с повышенными потребностями.
Включение тестов на доступность поможет упростить задачи мануального тестирования и сделать проверку доступности частью обычного процесса разработки.
Эта статья - своеобразный мини-гайд для быстрого старта вместе с Cypress и axe-core.
Почему такое сочетание технологий?
Axe-core - это надежный движок, соответствует стандартам WCAG. Он проверяет действительно реальные проблемы: контраст, aria-label, роли, альтернативный текст. Его легко интегрировать.
Cypress - удобный фреймворк, с огромным количеством функций “из коробки”. Легкая установка, большое количество примеров. Сохраняет скриншоты, делает запись видео, идеален для пользовательских тестов.
Typescript - мой любимый инструмент. Требует чуть больше времени при настройке проекта, но зато в дальнейшем помогает выявлять явные ошибки.
Установка зависимостей
npm install --save-dev typescript cypress cypress-axe mochawesome mochawesome-merge mochawesome-report-generator rimraf
Добавляем команду для тестирования доступности: axeCheck
Добавим в файл cypress/support/commands.ts:
import 'cypress-axe';
Cypress.Commands.add('axeCheck', () => {
cy.injectAxe();
cy.checkA11y(undefined, undefined, (violations) => {
if (violations.length) {
const violationMessages = violations.map((v, i) => {
return `\n[${i + 1}] X ${v.id} - ${v.help}
Element: ${v.nodes[0].html}
Summary: ${v.nodes[0].failureSummary}
Impact: ${v.impact}
Rule: ${v.helpUrl}
`;
}).join('\n');
throw new Error(`Accessibility violations:\n${violationMessages}`);
}
});
});
Добавляем типизацию (создаем файл commands.d.ts, если он не был создан, и добавляем интерфейс):
declare namespace Cypress {
interface Chainable {
injectAxeAndCheck(): Chainable<void>;
}
}
Первый тест
Наш первый тест нужен для того, чтобы убедиться, что все настройки и зависимости правильные, что все работает так, как нужно. Для тестирования выбран ebay.com.
describe('A11y check: eBay homepage', () => {
it('Check for accessibility errors', () => {
cy.visit('https://www.ebay.com/');
cy.axeAndCheck();
});
});
Настройка генерации отчетов
Добавляем в cypress.config.ts подключение репортера mochawesome:
reporter: 'mochawesome',
reporterOptions: {
reportDir: 'cypress/reports',
overwrite: false,
html: true,
json: true,
charts: true,
reportPageTitle: 'A11y-check report',
embeddedScreenshots: true,
inlineAssets: true,
}
Сводный отчёт
Если тестов больше 1, то mochawesome будет генерировать отдельные файлы отчетов (json и html) для каждого файла с тестами. Поэтому добавляем в package.json следующие скрипты:
команду для удаления отчетов по предыдущим запускам:
"clean": "rimraf cypress/reports && rimraf cypress/merged"
запуск cypress в фоновом режиме, без открытия браузера:
"test": "cypress run"
и сами команды для создания отчетов:
"merge-reports": "mochawesome-merge cypress/reports/*.json > cypress/merged/mochawesome.json",
"generate-report": "marge cypress/merged/mochawesome.json --reportDir cypress/merged --reportFilename report",
"test:report": "npm run clean && npm run test && npm run merge-reports && npm run generate-report"
Запуск
npm run test:report - всего одна команда, которая запускает тесты в фоновом режиме без открытия браузера, удаляет предыдущие отчеты, генерирует новые и объединяет их в один сводный отчет.
Результат
Получаем подробный вывод об ошибках в консоль:

А также отчет, который поможет разработчикам легко найти нужный элемент, разобраться, какое правило нарушено, и посмотреть, насколько критична эта ошибка:

Заключение
Автоматизация тестирования позволяет запускать повторяющиеся тесты в любое время, по расписанию, добавляя их в pipeline, CI/CD, чтобы сделать разработку гибкой, настраиваемой, а приложения - доступными для всех пользователей.
Достаточно начать с одного теста, чтобы убедиться, что все настройки сделаны верно и работают. А затем расширять тестовое покрытие, проверять реальные страницы вашего приложения и внедрять доступность в повседневную разработку.