Jest и axe-core

Для интеграции axe-core с Jest необходимо установить два основных пакета: саму библиотеку и утилиту для работы с Jest.

npm install axe-core jest-axe --save-dev
  • axe-core — ядро библиотеки для анализа доступности веб-страниц.
  • jest-axe — адаптер для запуска тестов с Jest.

После установки создается конфигурация Jest, если она еще не настроена. Для тестов достаточно иметь базовый testEnvironment: "jsdom", чтобы имитировать DOM в Node.js.

// jest.config.js
module.exports = {
  testEnvironment: "jsdom",
};

Базовое использование axe-core в тестах

Подключение библиотеки осуществляется через jest-axe, который предоставляет удобный метод axe.

import { axe, toHaveNoViolations } from 'jest-axe';
import { render } from '@testing-library/react';

expect.extend(toHaveNoViolations);

test('страница должна быть доступной', async () => {
  const { container } = render(<MyComponent />);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

Ключевые моменты:

  • render из @testing-library/react используется для генерации DOM-компонента.
  • axe(container) анализирует DOM и возвращает объект с результатами проверок.
  • toHaveNoViolations() позволяет интегрировать результаты axe с системой утверждений Jest.

Работа с результатами анализа

Объект results, возвращаемый axe, содержит несколько важных полей:

  • violations — массив найденных нарушений доступности.
  • passes — массив элементов, которые прошли проверку.
  • incomplete — проверки, которые не были полностью выполнены.
  • inapplicable — правила, которые не применимы к текущему DOM.

Пример расширенной обработки нарушений:

const results = await axe(container);
if (results.violations.length > 0) {
  results.violations.forEach(violation => {
    console.log(`Нарушение: ${violation.id}`);
    violation.nodes.forEach(node => {
      console.log(`Элемент: ${node.html}`);
      console.log(`Сообщение: ${node.failureSummary}`);
    });
  });
}

Это позволяет создавать отчеты и логировать конкретные элементы с проблемами доступности.


Настройка правил axe-core

axe-core позволяет включать, отключать или настраивать отдельные правила. Это особенно полезно для сложных компонентов, где стандартные проверки могут быть слишком строгими.

const results = await axe(container, {
  rules: {
    'color-contrast': { enabled: false },
    'label': { enabled: true },
  },
});
  • enabled: false отключает правило.
  • enabled: true принудительно включает правило, даже если оно по умолчанию отключено.

Можно также передавать глобальные опции, например runOnly, чтобы запускать только определенные категории правил:

const results = await axe(container, {
  runOnly: {
    type: 'tag',
    values: ['wcag2a', 'wcag2aa'],
  },
});

Интеграция axe-core с React-компонентами

Для React-приложений важно учитывать асинхронность рендеринга и динамическое обновление DOM. axe-core может анализировать только существующий DOM, поэтому следует вызывать проверку после того, как компонент полностью отрендерился:

import { render, waitFor } from '@testing-library/react';

test('компонент динамически доступен', async () => {
  const { container } = render(<AsyncComponent />);
  await waitFor(async () => {
    const results = await axe(container);
    expect(results).toHaveNoViolations();
  });
});

waitFor гарантирует, что все асинхронные операции завершены перед проверкой.


Использование axe-core с SSR и Next.js

При серверном рендеринге DOM формируется на сервере, поэтому анализ доступности проводится на этапе тестирования компонентов в Jest.

Для компонентов Next.js необходимо оборачивать рендер в @testing-library/react и использовать axe после получения HTML:

import { render } from '@testing-library/react';
import { axe } from 'jest-axe';
import HomePage from '../pages/index';

test('HomePage доступна', async () => {
  const { container } = render(<HomePage />);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

Генерация подробных отчетов

Для CI/CD удобно выводить подробные отчеты в формате JSON или HTML. Можно использовать собственные скрипты или утилиты, преобразующие results.violations:

const fs = require('fs');

const results = await axe(container);
fs.writeFileSync('axe-report.json', JSON.stringify(results, null, 2));

В результате можно интегрировать проверку доступности в пайплайны GitHub Actions, GitLab CI или Jenkins.


Советы по эффективной работе с axe-core в Jest

  1. Фокус на компонентах, а не всей странице — тестирование небольших единиц проще и стабильнее.
  2. Асинхронные проверки — компоненты с ленивой загрузкой требуют waitFor.
  3. Отключение ненужных правил — уменьшает количество ложных срабатываний.
  4. Регулярное обновление axe-core — библиотека активно развивается, включая новые рекомендации WCAG.
  5. Интеграция с CI — тесты доступны для автоматического контроля качества доступности на каждом коммите.

Эта практика обеспечивает системный контроль доступности интерфейсов и позволяет выявлять проблемы на ранней стадии разработки.