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

Роль доступности в кастомных sel ect-компонентах

Компоненты выбора, построенные поверх стандартного <select>, относятся к наиболее чувствительным с точки зрения доступности элементам интерфейса. Библиотека Tom Select заменяет нативное поведение браузера собственным UI, что автоматически накладывает ответственность за корректную реализацию:

  • семантики ARIA;
  • управления фокусом;
  • клавиатурной навигации;
  • совместимости со скринридерами;
  • предсказуемого поведения при взаимодействии.

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


ARIA-структура и семантическая модель

Ключевая задача при тестировании — проверка соответствия ARIA-ролей ожидаемой модели поведения.

Типовая структура:

  • role="combobox" — основной контейнер;
  • role="listbox" — выпадающий список;
  • role="option" — элементы выбора;
  • aria-expanded — состояние раскрытия;
  • aria-activedescendant — активный элемент;
  • aria-selected — состояние выбора.

Критически важно проверять синхронизацию между внутренним состоянием и ARIA-атрибутами. Несоответствие приводит к:

  • неправильному озвучиванию скринридером;
  • потере контекста при навигации;
  • невозможности корректного выбора элементов.

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

Клавиатурное управление является основой доступности кастомных селекторов.

Типовой набор проверок включает:

  • Tab — вход и выход из компонента;
  • ArrowDown / ArrowUp — перемещение по списку;
  • Enter — выбор активного элемента;
  • Esc — закрытие списка;
  • Backspace — удаление выбранных значений (в multi-select).

Тестирование фиксирует не только факт срабатывания событий, но и состояние UI:

  • изменение aria-activedescendant;
  • корректное перемещение фокуса;
  • отсутствие «залипания» фокуса внутри списка;
  • восстановление фокуса после закрытия dropdown.

Управление фокусом и жизненный цикл компонента

Фокус в кастомных компонентах часто становится источником доступностных дефектов.

При тестировании проверяются следующие сценарии:

  • открытие списка не должно терять фокус с input;
  • закрытие списка возвращает фокус в корректный элемент;
  • программное изменение значения не должно неожиданно смещать фокус;
  • удаление выбранного элемента не должно «выкидывать» пользователя из контекста.

Особое внимание уделяется динамическому созданию/уничтожению DOM-элементов, поскольку Tom Select может пересоздавать внутреннюю структуру при обновлении данных.


Поведение со скринридерами

Проверка совместимости со скринридерами относится к обязательному этапу валидации доступности.

Тестируемые аспекты:

  • корректное объявление роли комбобокса;
  • озвучивание состояния раскрытия (expanded/collapsed);
  • чтение активного элемента списка;
  • объявление выбранных значений в multi-select;
  • отсутствие дублирующихся или «лишних» уведомлений.

Дополнительно проверяется отсутствие шумовых элементов:

  • скрытых декоративных узлов, попадающих в accessibility tree;
  • некорректных aria-live обновлений;
  • повторяющихся описаний одного и того же состояния.

Автоматизированное тестирование доступности

Автоматизация позволяет выявить базовые нарушения ARIA и DOM-структуры.

Наиболее распространённый инструмент — axe-core.

Пример интеграции в тестовый стек:

  • unit/integration уровень: jest-axe;
  • браузерный уровень: Cypress + cypress-axe;
  • E2E: Playwright + axe.

Типовые проверки:

  • отсутствие критических нарушений WCAG;
  • корректность ARIA-атрибутов;
  • наличие label и связки с input;
  • отсутствие недоступных интерактивных элементов.

Важно учитывать, что автоматические инструменты не покрывают:

  • логическую корректность навигации;
  • реальное поведение скринридеров;
  • последовательность фокуса.

Пример интеграционного теста доступности

import { axe } fr om 'jest-axe';

test('Tom Select не содержит критических нарушений доступности', async () => {
  document.body.innerHTML = `
    <select id="select">
      <option value="1">One</option>
      <option value="2">Two</option>
    </select>
  `;

  new TomSelect('#select');

  const results = await axe(document.body);
  expect(results).toHaveNoViolations();
});

E2E тестирование поведения интерфейса

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

Проверяются сценарии:

  • открытие списка через клавиатуру;
  • выбор элемента стрелками и Enter;
  • закрытие через Esc;
  • работа в multi-select режиме;
  • фильтрация и ввод текста.

Пример сценария:

cy.get('.ts-control').focus().type('{downarrow}');
cy.get('.ts-dropdown').should('be.visible');
cy.get('.option').first().trigger('keydown', { key: 'Enter' });
cy.get('.ts-control').should('contain', 'One');

Особое внимание уделяется синхронизации DOM и accessibility tree, поскольку визуально корректное поведение может расходиться с доступностной моделью.


Интеграционные сценарии Tom Select

При интеграции с формами возникают дополнительные доступностные риски:

  • отсутствие связи label → input;
  • потеря значения при submit;
  • некорректная сериализация выбранных значений;
  • конфликт с нативной валидацией формы.

Тестируются сценарии:

  • отправка формы с выбранным значением;
  • reset формы;
  • динамическое обновление options;
  • отключённое состояние (disabled) и его влияние на ARIA.

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

На практике в компонентах выбора встречаются повторяющиеся ошибки:

  • отсутствие aria-expanded при открытии dropdown;
  • некорректный aria-activedescendant;
  • невозможность навигации клавиатурой в списке;
  • фокус уходит в body при открытии меню;
  • визуальный фокус не совпадает с логическим;
  • отсутствие объявления выбранного значения.

Каждое из этих нарушений может не проявляться визуально, но критично влияет на использование скринридерами.


Стратегия построения тест-кейсов доступности

Тестирование строится слоями:

1. Статический слой

  • проверка DOM;
  • ARIA-атрибуты;
  • структура элементов.

2. Поведенческий слой

  • клавиатурная навигация;
  • управление фокусом;
  • открытие/закрытие.

3. Интеграционный слой

  • формы;
  • динамическое обновление данных;
  • взаимодействие с внешними компонентами.

4. Accessibility слой

  • axe-core проверки;
  • ручная проверка скринридером;
  • анализ accessibility tree.

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

Изменения в UI-компонентах часто приводят к скрытым регрессиям доступности:

  • рефакторинг DOM-структуры ломает ARIA связи;
  • оптимизация событий нарушает порядок фокуса;
  • стилизация заменяет семантические элементы div-ами без компенсации ARIA.

Регрессионные тесты фиксируют:

  • неизменность ARIA-схемы;
  • стабильность поведения клавиатуры;
  • сохранение accessibility tree структуры;
  • отсутствие новых violations в автоматических проверках.