Перетягивание элементов

Перетягивание элементов (drag and drop) является важной частью автоматизированного тестирования интерфейсов, где пользователю предоставляется возможность перемещать объекты внутри страницы. WebdriverIO предоставляет несколько способов реализации такого взаимодействия с элементами, опираясь на возможности WebDriver протокола и JavaScript.


Основные подходы

1. Использование встроенного метода dragAndDrop

WebdriverIO имеет встроенный метод dragAndDrop, который позволяет перемещать элемент к целевому элементу или на указанное смещение:

const source = await $('#source');
const target = await $('#target');

// Перетащить элемент source на элемент target
await source.dragAndDrop(target);

// Перетащить элемент source на смещение {x: 100, y: 50}
await source.dragAndDrop({ x: 100, y: 50 });

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

  • Метод автоматически рассчитывает координаты целевого элемента.
  • Можно использовать как абсолютные координаты, так и другой WebdriverIO элемент в качестве цели.
  • Работает с современными браузерами, поддерживающими Pointer Actions.

2. Использование цепочек действий (Actions API)

Для сложных сценариев перетягивания лучше применять Actions API. Это позволяет более точно управлять движением курсора и имитацией поведения пользователя:

const source = await $('#source');
const target = await $('#target');

await browser.performActions([{
    type: 'pointer',
    id: 'mouse',
    parameters: { pointerType: 'mouse' },
    actions: [
        { type: 'pointerMove', origin: source, x: 0, y: 0 },
        { type: 'pointerDown', button: 0 },
        { type: 'pointerMove', origin: target, x: 0, y: 0, duration: 1000 },
        { type: 'pointerUp', button: 0 }
    ]
}]);

await browser.releaseActions();

Преимущества:

  • Можно задать скорость движения курсора (duration).
  • Поддержка сложных сценариев, например, перетаскивания через несколько промежуточных точек.
  • Полный контроль над событиями pointerDown, pointerMove, pointerUp.

3. Перетаскивание через JavaScript

Иногда стандартные методы не работают с кастомными библиотеками интерфейса (например, с drag-and-drop, реализованным через React DnD). В таких случаях можно выполнить перетягивание через эмуляцию событий Jav * aScript:

await browser.execute((sourceSelector, targetSelector) => {
    const source = document.querySelector(sourceSelector);
    const target = document.querySelector(targetSelector);

    const dataTransfer = new DataTransfer();
    
    source.dispatchEvent(new DragEvent('dragstart', { dataTransfer }));
    target.dispatchEvent(new DragEvent('drop', { dataTransfer }));
    source.dispatchEvent(new DragEvent('dragend', { dataTransfer }));
}, '#source', '#target');

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

  • Подходит для элементов с кастомной обработкой событий.
  • Требует понимания структуры DOM и событий dragstart, drop, dragend.
  • Эмуляция через DataTransfer обеспечивает совместимость с HTML5 Drag and Drop API.

Настройка ожиданий

При работе с перетягиванием важно учитывать асинхронность и анимации. Например, перемещаемый элемент может перемещаться с анимацией, поэтому следует использовать ожидания состояния элемента:

const target = await $('#target');
await target.waitForDisplayed({ timeout: 5000 });

const source = await $('#source');
await source.dragAndDrop(target);
await expect(target).toHaveElementContainingText('Перемещено');

Советы:

  • waitForDisplayed или waitForEnabled помогают избежать ошибок взаимодействия с невидимыми элементами.
  • Проверка итогового состояния элемента гарантирует корректность перетягивания.

Особенности работы с мобильными платформами

На мобильных устройствах перетаскивание часто реализуется через тач-события. WebdriverIO поддерживает Touch Actions:

const source = await $('#source');
const target = await $('#target');

await browser.touchAction([
    { action: 'press', element: source },
    { action: 'wait', ms: 500 },
    { action: 'moveTo', element: target },
    { action: 'release' }
]);

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

  • Указывается длительность ожидания (wait), чтобы имитировать человеческое взаимодействие.
  • Используется последовательность действий press → moveTo → release.
  • Работает для симуляции свайпов и перетягивания на мобильных устройствах.

Частые ошибки и рекомендации

  1. Элемент не перетаскивается Причины: невидимый элемент, overlay поверх элемента, нестандартная реализация drag-and-drop. Решение: использовать Actions API или эмуляцию через JavaScript.

  2. Целевая позиция не совпадает с ожидаемой Причины: динамический layout, анимация. Решение: добавить небольшие задержки или использовать абсолютные координаты.

  3. Мобильные жесты не срабатывают Причины: неправильно задана последовательность touchAction. Решение: убедиться, что используется press → wait → moveTo → release.


Перетягивание элементов в WebdriverIO требует понимания структуры DOM, особенностей браузера и используемых библиотек интерфейса. Комбинация методов dragAndDrop, Actions API и эмуляции через JavaScript обеспечивает гибкость и надежность автоматизированного тестирования.