Нативе драг-дроп

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

Нативная реализация drag-and-drop

В WebdriverIO можно использовать нативную реализацию drag-and-drop через браузерные API. Эти API позволяют взаимодействовать с элементами страницы так, как если бы это делал пользователь, т.е. перетаскивая их с помощью мыши. Для выполнения операции drag-and-drop в WebdriverIO используется метод browser.performActions(), который отправляет серию действий, эмулирующих перемещение объектов.

Пример простого перетаскивания:

const fromElement = await $('#fromElement'); // Исходный элемент
const toElement = await $('#toElement'); // Целевой элемент

await browser.performActions([
  {
    type: 'pointer',
    id: 'drag',
    parameters: { pointerType: 'mouse' },
    actions: [
      { type: 'pointerMove', origin: fromElement },
      { type: 'pointerDown', button: 0 },
      { type: 'pointerMove', origin: toElement },
      { type: 'pointerUp', button: 0 }
    ]
  }
]);

Подробное описание работы с performActions

Метод performActions() позволяет выполнять сложные серии взаимодействий с элементами, включая нативное перетаскивание. В этом примере сначала происходит инициализация действия с помощью pointer, указывая, что действия будут выполняться с использованием мыши. Далее идет серия действий, каждая из которых имеет конкретное назначение:

  1. pointerMove — перемещение указателя мыши на начальную позицию (откуда будет начинаться перетаскивание).
  2. pointerDown — эмуляция нажатия на кнопку мыши (перетаскивание начинается).
  3. pointerMove — перемещение указателя мыши в целевую точку, на которую нужно перетащить элемент.
  4. pointerUp — отпускание кнопки мыши, что завершает процесс перетаскивания.

Зачем используется performActions?

Метод performActions важен для нативной эмуляции событий, так как это позволяет отправлять последовательность низкоуровневых действий, таких как перемещения мыши и нажатия. Это дает возможность более точно имитировать действия пользователя, в отличие от других подходов, таких как использование JavaScript для создания перетаскивания. performActions имитирует реальные события, что позволяет успешно тестировать веб-приложения, не полагаясь на работу с API других библиотек.

Работа с элементами на странице

При использовании performActions необходимо правильно указывать элементы для начала и конца перетаскивания. Для этого нужно получить WebElement, с которым будет взаимодействовать тест. Важно помнить, что WebDriverIO использует промисы, поэтому все взаимодействия с элементами должны быть асинхронными.

Пример: Перетаскивание в списке

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

const item1 = await $('#item1');
const item2 = await $('#item2');

await browser.performActions([
  {
    type: 'pointer',
    id: 'drag',
    parameters: { pointerType: 'mouse' },
    actions: [
      { type: 'pointerMove', origin: item1 },
      { type: 'pointerDown', button: 0 },
      { type: 'pointerMove', origin: item2 },
      { type: 'pointerUp', button: 0 }
    ]
  }
]);

В данном примере элемент с id item1 будет перемещен в позицию элемента с id item2. Этот подход можно адаптировать для перетаскивания в любые другие контейнеры.

Использование dragAndDrop в WebdriverIO

В WebdriverIO существует собственный метод dragAndDrop, который значительно упрощает задачу. Этот метод позволяет перетаскивать один элемент в другой с использованием JavaScript и WebDriver API.

Пример использования:

const fromElement = await $('#fromElement');
const toElement = await $('#toElement');

await fromElement.dragAndDrop(toElement);

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

Проблемы и решения

  1. Анимации при перетаскивании: Иногда на странице могут быть анимации, которые мешают корректному выполнению перетаскивания. Для таких случаев можно использовать методы, которые отключают анимации, либо замедляют выполнение тестов с помощью команды browser.pause(), чтобы дать время анимациям завершиться.

  2. Элементы, скрытые за другими: Если элементы, с которыми нужно взаимодействовать, скрыты или перекрыты другими элементами, можно использовать методы scrollIntoView или moveTo для прокрутки или перемещения элемента в видимую область.

  3. Необычные действия drag-and-drop: Некоторые приложения могут требовать специфических действий для успешного выполнения drag-and-drop, например, необходимость скрывать и показывать элементы, менять их положение динамически. В таких случаях можно использовать дополнительные шаги, например, ожидания с помощью waitForDisplayed() или другие методы из API WebDriverIO, чтобы гарантировать правильное выполнение теста.

Примечания по безопасности

При работе с drag-and-drop необходимо учитывать, что на странице могут быть защищенные элементы, которые ограничивают доступ к ним. Это могут быть элементы с атрибутами, такими как pointer-events: none. В таких случаях важно проверить, что элементы доступны для взаимодействия, и в случае необходимости использовать специальные методы WebDriverIO для эмуляции событий, минуя ограничения.

Заключение

Нативное перетаскивание в WebdriverIO через performActions или dragAndDrop предоставляет мощный инструментарий для автоматизации взаимодействий с пользователем в веб-приложениях. Важно правильно настроить тесты, учитывая различные аспекты, такие как анимации, скрытые элементы и специфические действия на странице. В зависимости от ситуации можно выбирать подход, который будет наиболее эффективным для решения конкретной задачи.