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

Библиотека Shopify Draggable предоставляет мощные инструменты для реализации drag-and-drop интерфейсов на JavaScript. Одним из ключевых аспектов при работе с такими интерактивными элементами является обеспечение доступности (accessibility, a11y), что позволяет пользователям с ограниченными возможностями корректно взаимодействовать с элементами интерфейса. Тестирование доступности включает проверку навигации с клавиатуры, поддержки экранных читалок и соблюдения ARIA-атрибутов.


Навигация с клавиатуры

Для drag-and-drop интерфейсов критически важно, чтобы элементы могли быть перемещены с помощью клавиатуры. В Draggable каждый контейнер и каждый draggable элемент можно сделать фокусируемым через добавление атрибута tabindex="0":

const containers = document.querySelectorAll('.draggable-container');
containers.forEach(container => {
  container.setAttribute('tabindex', '0');
});

После установки фокуса необходимо реализовать обработку событий клавиатуры, например стрелок и клавиши Enter, для начала и завершения перемещения:

draggables.forEach(item => {
  item.addEventListener('keydown', (event) => {
    switch(event.key) {
      case 'Enter':
        // Инициализация drag
        break;
      case 'ArrowUp':
      case 'ArrowDown':
        // Перемещение элемента по списку
        break;
    }
  });
});

Ключевой момент — корректная обработка перемещений, чтобы порядок элементов в DOM соответствовал визуальному расположению. Это важно для совместимости с экранными читалками.


ARIA-атрибуты для drag-and-drop

Использование ARIA-атрибутов позволяет экранным читалкам интерпретировать состояние элементов и их взаимодействие:

  • aria-grabbed — указывает, захвачен ли элемент. При начале drag устанавливается true, при завершении — false.
  • aria-dropeffect — обозначает, какие действия допустимы в контейнере: move, copy, link или none.
  • role="listbox" и role="option" — применяются для упорядоченных списков draggable элементов, чтобы читалки могли корректно объявлять элементы.

Пример:

  • Элемент 1
  • Элемент 2

В JavaScript обновление состояния:

draggable.on('drag:start', (event) => {
  event.source.setAttribute('aria-grabbed', 'true');
});

draggable.on('drag:stop', (event) => {
  event.source.setAttribute('aria-grabbed', 'false');
});

Тестирование с экранными читалками

Для проверки совместимости необходимо:

  1. Установить захват фокуса на текущий draggable элемент.
  2. Обеспечить четкое аудио-оповещение о начале перемещения и завершении, используя ARIA-атрибуты.
  3. Обновлять порядок элементов в DOM сразу после завершения перемещения, чтобы экранные читалки правильно анонсировали новый порядок.

Инструменты для тестирования: NVDA, VoiceOver, JAWS, а также встроенные браузерные проверки ARIA.


Проверка перетаскивания с помощью клавиатуры

Основные сценарии тестирования:

  • Перемещение элемента вверх/вниз с помощью клавиш ArrowUp и ArrowDown.
  • Начало/завершение перемещения клавишей Enter или Space.
  • Поддержка отмены действия клавишей Escape.
  • Обновление aria-grabbed и других атрибутов после каждого действия.
  • Проверка того, что фокус корректно перемещается на новый элемент после drop.

Пример обработки клавиатурного drag-and-drop:

function handleKeyboardDrag(event, item, container) {
  const items = Array.from(container.querySelectorAll('.draggable'));
  const index = items.indexOf(item);

  switch(event.key) {
    case 'ArrowUp':
      if (index > 0) {
        container.insertBefore(item, items[index - 1]);
      }
      break;
    case 'ArrowDown':
      if (index < items.length - 1) {
        container.insertBefore(items[index + 1], item);
      }
      break;
    case 'Escape':
      item.setAttribute('aria-grabbed', 'false');
      item.blur();
      break;
  }
}

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

Для интеграции в CI/CD можно использовать инструменты вроде:

  • axe-core — анализ DOM на наличие нарушений доступности.
  • Pa11y — проверка страниц на соответствие WCAG.
  • Lighthouse — встроенный инструмент Chrome DevTools для аудита доступности.

Пример интеграции axe-core:

import axe from 'axe-core';

axe.run(document, {}, (err, results) => {
  if (err) throw err;
  console.log(results.violations);
});

Важно: любые изменения в DOM при drag-and-drop должны быть проверены через автоматизированные тесты, чтобы исключить появление новых нарушений доступности.


Отслеживание состояния drag-and-drop

Draggable предоставляет события, которые позволяют отслеживать весь жизненный цикл перемещения:

  • drag:start — начало перемещения.
  • drag:move — движение элемента.
  • drag:stop — завершение перемещения.
  • sortable:sorted — элемент изменил позицию в списке.

Для тестирования доступности необходимо убедиться, что ARIA-атрибуты, фокус и DOM обновляются на каждом из этих этапов. Это позволяет пользователям экранных читалок и клавиатурных интерфейсов получать актуальную информацию о состоянии интерфейса в реальном времени.