Single Page Applications

Библиотека 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 может быть избыточной.

Динамический 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-core можно использовать вместе с 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);
}
  • Vue: Проверки можно внедрять в lifecycle hooks (mounted, updated) для анализа динамически изменяемых элементов.
  • Angular: Axe-core используется через сервисы или директивы для анализа компонентов после рендеринга.

Обработка результатов

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.
  • Ограничивать область анализа контейнерами компонентов, а не всем документом.

Интеграция в CI/CD

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);
  });
});

Ключевые моменты работы с SPA

  • Запускать проверки после каждого обновления DOM.
  • Использовать ограничение области анализа.
  • Настраивать правила под проект.
  • Интегрировать автоматические проверки в процессы разработки.
  • Обрабатывать результаты структурированно, учитывая степень важности нарушений.

Использование Axe-core в SPA позволяет системно отслеживать доступность и гарантирует, что динамический интерфейс остаётся соответствующим стандартам WCAG, даже при частых изменениях пользовательского интерфейса.