Автоматизация тестов

Shopify Draggable — это мощная библиотека для создания интерактивных перетаскиваемых элементов на веб-странице. Она предоставляет API для управления drag-and-drop интерфейсами, позволяя реализовать сложные сценарии сортировки, переносов между контейнерами и динамических анимаций. Библиотека построена на событийной модели, что делает её удобной для интеграции с автоматизированными тестами.

Инициализация Draggable

Для начала необходимо подключить библиотеку и определить контейнеры с элементами:

import { Draggable } from '@shopify/draggable';

const draggable = new Draggable(document.querySelectorAll('.container'), {
  draggable: '.item',
  delay: 0,
  mirror: {
    constrainDimensions: true,
  },
});

Ключевые параметры:

  • draggable — CSS-селектор элементов, которые будут перемещаемыми.
  • delay — задержка начала перетаскивания (мс), полезна для предотвращения случайных drag-событий.
  • mirror — настройка отображения копии перетаскиваемого элемента.

Основные события

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

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

Пример привязки событий:

draggable.on('drag:start', (event) => {
  console.log('Начало перетаскивания', event.source);
});

draggable.on('sortable:sorted', (event) => {
  console.log('Элемент перемещён', event.newIndex);
});

Работа с контейнерами

Draggable поддерживает множественные контейнеры для переноса элементов между ними.

const containers = document.querySelectorAll('.list');

const draggable = new Draggable(containers, {
  draggable: '.list-item',
  swapAnimation: true,
});

Особенности:

  • Элементы можно перемещать между любыми контейнерами.
  • swapAnimation плавно анимирует перемещение.
  • containers могут быть динамическими, что важно при автоматизации тестов на изменяемых DOM-структурах.

Автоматизация тестов взаимодействия

Для написания тестов можно использовать события Draggable вместе с инструментами типа Jest, Cypress или Playwright. Основная идея — симулировать события drag-and-drop, затем проверять состояние DOM и порядок элементов.

Пример с Cypress:

cy.get('.item').first().trigger('mousedown', { button: 0 });
cy.get('.item').eq(2).trigger('mousemove').trigger('mouseup', { force: true });

cy.get('.container .item').eq(2).should('contain.text', 'Перемещённый элемент');

Для более точного тестирования можно использовать метод draggable.on() для отслеживания событий и подтверждать их вызов:

let sorted = false;

draggable.on('sortable:sorted', () => {
  sorted = true;
});

// затем проверка
expect(sorted).toBe(true);

Настройка зеркала и ограничений

Draggable позволяет тонко настраивать зеркало перетаскиваемого элемента, что критично для визуального тестирования:

const draggable = new Draggable(containers, {
  draggable: '.item',
  mirror: {
    appendTo: document.body,
    constrainDimensions: true,
  },
});

Параметры зеркала:

  • appendTo — контейнер для отображения копии элемента.
  • constrainDimensions — сохраняет исходные размеры.
  • xAxis, yAxis — можно ограничивать перемещение по осям, полезно для тестов ограниченных интерфейсов.

Сортировка и динамическое обновление

Draggable отлично интегрируется с динамическими списками. При автоматизации важно проверять:

  1. Корректность индексов элементов после перемещения (event.newIndex и event.oldIndex).
  2. Обновление состояния модели данных, если drag используется для изменения порядка в бэкенде.
  3. События sortable:stop для завершения операций, что позволяет запускать цепочки проверок в тестах.

Пример проверки порядка элементов:

draggable.on('sortable:stop', (event) => {
  const items = Array.from(event.currentTarget.children).map(el => el.textContent);
  console.log('Новый порядок элементов:', items);
});

Интеграция с фреймворками

Draggable совместим с React, Vue, Angular. Важно:

  • Использовать рефы или querySelector для передачи элементов в Draggable.
  • Обновлять состояние компонента при событии sortable:stop.
  • Для тестов можно использовать виртуальный DOM и симулировать drag с помощью событий.

Лучшие практики для тестирования

  • Всегда привязывать события перед симуляцией drag, чтобы не пропустить callback.
  • Проверять как визуальное, так и логическое состояние DOM.
  • Использовать mirror для тестов UI, чтобы убедиться, что элемент перемещается корректно.
  • При тестах с несколькими контейнерами проверять корректность переноса элементов и их индексов.
  • Применять delay для предотвращения ложных срабатываний при быстрых тестах.

Отладка и логирование

Для автоматизации тестов важно иметь расширенное логирование:

draggable.on('drag:start', event => console.log('Start', event.source));
draggable.on('drag:stop', event => console.log('Stop', event.source));
draggable.on('sortable:sorted', event => console.log('Sorted', event.oldIndex, '->', event.newIndex));

Это позволяет сопоставлять события с тестовыми сценариями и быстро выявлять ошибки в логике перетаскивания.


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