Drag and drop (перетаскивание элементов) является одной из важных
операций при автоматизированном тестировании веб-приложений. В
Protractor для реализации этих действий используется модуль
browser.actions(), предоставляющий богатый набор методов
для взаимодействия с элементами на странице.
1. mouseDown() и mouseUp()
Эти методы имитируют нажатие и отпускание кнопки мыши. Чаще всего их
используют вместе с mouseMove() для поэтапного
перетаскивания.
Пример поэтапного перетаскивания:
let source = element(by.id('draggable'));
let target = element(by.id('droppable'));
browser.actions()
.mouseMove(source) // Наведение на исходный элемент
.mouseDown() // Нажатие кнопки мыши
.mouseMove(target) // Перемещение к целевому элементу
.mouseUp() // Отпускание кнопки мыши
.perform();
2. dragAndDrop() Метод
dragAndDrop(source, target) объединяет все этапы
перетаскивания в одну операцию, что делает код более компактным и
читаемым.
Пример использования:
let source = element(by.id('draggable'));
let target = element(by.id('droppable'));
browser.actions().dragAndDrop(source, target).perform();
Иногда требуется перетаскивание не к другому элементу, а на
определённое смещение. Для этого используется
mouseMove({x: offsetX, y: offsetY}).
Пример перетаскивания на смещение:
let elementToMove = element(by.css('.draggable'));
browser.actions()
.mouseMove(elementToMove)
.mouseDown()
.mouseMove({x: 100, y: 50}) // Перемещение на 100px вправо и 50px вниз
.mouseUp()
.perform();
Для подтверждения корректности операции часто используется метод
getText() или проверка атрибутов/классов элементов после
перетаскивания:
let target = element(by.id('droppable'));
expect(target.getText()).toEqual('Dropped!');
expect(target.getAttribute('class')).toContain('ui-state-highlight');
Не все элементы корректно реагируют на стандартные методы
dragAndDrop. В таких случаях применяются дополнительные
подходы:
browser.executeScript(`
const source = arguments[0];
const target = arguments[1];
const dataTransfer = new DataTransfer();
source.dispatchEvent(new DragEvent('dragstart', {dataTransfer}));
target.dispatchEvent(new DragEvent('drop', {dataTransfer}));
source.dispatchEvent(new DragEvent('dragend', {dataTransfer}));
`, source.getWebElement(), target.getWebElement());
mouseMove(target) не срабатывает, можно перемещать элемент
по маленьким смещениям с промежуточными perform().browser.sleep(ms) между этапами позволяет увидеть, как
выполняется перетаскивание.getLocation() возвращает текущие координаты элемента, что
полезно для подтверждения перемещения.element(by.id('draggable')).getLocation().then(location => {
console.log(location); // {x: 150, y: 200}
});
browser.wait(ExpectedConditions.visibilityOf(element))
перед drag and drop.browser.switchTo().frame().dragAndDrop, если браузер
и элемент поддерживают стандартные события.