Shopify Draggable — это мощная библиотека для создания
интерактивных перетаскиваемых элементов на веб-странице. Она
предоставляет API для управления drag-and-drop
интерфейсами, позволяя реализовать сложные сценарии сортировки,
переносов между контейнерами и динамических анимаций. Библиотека
построена на событийной модели, что делает её удобной
для интеграции с автоматизированными тестами.
Для начала необходимо подключить библиотеку и определить контейнеры с элементами:
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 и порядок элементов.
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 отлично интегрируется с динамическими списками. При автоматизации важно проверять:
event.newIndex и event.oldIndex).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.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, что критично для надежной проверки поведения интерфейса.