Тестирование доступности

Доступность веб-приложений (Accessibility, a11y) является критически важной частью разработки. Фреймворк Fresh, построенный на Deno и использующий современный подход к серверному рендерингу с нативной поддержкой Islands Architecture, предоставляет возможности для интеграции инструментов тестирования доступности прямо в процессе разработки. Основная цель — обеспечить, чтобы интерфейс был удобен для всех пользователей, включая людей с ограниченными возможностями.

Интеграция инструментов автоматического тестирования

Fresh поддерживает использование стандартных инструментов для проверки доступности, таких как axe-core, Pa11y, Lighthouse. Они могут быть интегрированы как на уровне разработки, так и на этапе CI/CD.

Пример настройки автоматического тестирования с axe-core:

import { axe, toHaveNoViolations } from 'jest-axe';
import { render } from '@testing-library/preact';
import App from './routes/index.tsx';

expect.extend(toHaveNoViolations);

test('Главная страница не содержит нарушений доступности', async () => {
  const { container } = render(<App />);
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

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

  • jest-axe интегрируется с популярными тестовыми фреймворками.
  • Контейнер рендерится через @testing-library/preact, что позволяет тестировать реальные DOM-элементы.
  • Результат axe содержит детализированную информацию о нарушениях WCAG.

Проверка семантики и структуры

Fresh использует Preact-компоненты, которые рендерятся на сервере. Это упрощает проверку семантики HTML, так как можно анализировать статический HTML до его отправки клиенту. Основные проверки:

  • Корректное использование тегов заголовков (<h1><h6>).
  • Наличие атрибутов alt у изображений.
  • Правильное использование ролей ARIA для интерактивных элементов.
  • Контраст текста и фонов, проверяемый с помощью автоматизированных сканеров.

Пример проверки доступности кнопки:

const button = container.querySelector('button');
expect(button).toHaveAttribute('aria-label');
expect(button).not.toBeDisabled();

Тестирование клавиатурной навигации

В Fresh важно, чтобы интерактивные компоненты были доступны через клавиатуру. Для этого применяются следующие подходы:

  1. Фокусируемые элементы: все кнопки, ссылки и поля ввода должны быть доступны через Tab.
  2. Проверка событий клавиатуры: Enter и Space должны активировать интерактивные элементы.
  3. Порядок фокуса: должен соответствовать логической структуре страницы.

Пример теста с использованием @testing-library/user-event:

import userEvent from '@testing-library/user-event';

test('Клавиатурная навигация по форме', async () => {
  const { getByLabelText } = render(<Form />);
  const input = getByLabelText('Имя');
  input.focus();
  await userEvent.keyboard('{Tab}');
  expect(document.activeElement).toBe(getByLabelText('Email'));
});

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

Автоматическое тестирование доступности во Fresh рекомендуется включать в процесс CI/CD. Для этого можно использовать:

  • GitHub Actions: запуск тестов при каждом pull request.
  • Deno тесты: встроенная поддержка deno test для unit-тестов доступности.
  • Lighthouse CI: генерация отчетов и проверка ключевых страниц.

Пример конфигурации GitHub Actions:

name: Accessibility Tests

on: [push, pull_request]

jobs:
  a11y:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: denoland/setup-deno@v1
      - run: deno test --allow-net

Динамический контент и Islands

Fresh использует Islands Architecture, что позволяет выделять интерактивные части страницы. Для тестирования доступности динамических компонентов важно:

  • Проверять ARIA-состояния (aria-expanded, aria-checked) при обновлении состояния.
  • Проверять, что элементы, добавляемые динамически, доступны для скринридеров.
  • Использовать MutationObserver для отслеживания изменений DOM в тестах.

Пример проверки динамического компонента:

test('Динамическое раскрытие меню', () => {
  const { getByRole } = render(<Dropdown />);
  const button = getByRole('button');
  button.click();
  const menu = getByRole('menu');
  expect(menu).toBeVisible();
  expect(menu).toHaveAttribute('aria-hidden', 'false');
});

Локализация и доступность

Fresh позволяет работать с мультиязычностью, что требует проверки доступности:

  • Теги <html lang="..."> должны соответствовать языку контента.
  • Скринридеры должны корректно озвучивать локализованные элементы.
  • Автоматические тесты должны учитывать разные языковые версии страницы.

Использование визуальных тестов

Для комплексного контроля доступности применяется визуальное тестирование с инструментами вроде Storybook и Chromatic. Они позволяют:

  • Проверять контраст текста и фона.
  • Контролировать размеры элементов и их видимость.
  • Автоматически обнаруживать нарушения визуальной доступности.

Тщательная интеграция тестирования доступности во Fresh позволяет создавать интерфейсы, соответствующие стандартам WCAG, улучшает пользовательский опыт и снижает риск юридических проблем, связанных с недоступностью веб-продукта.