← Назад к вопросам

Как выполнить drag and drop в Selenium?

2.0 Middle🔥 121 комментариев
#Selenium и UI автоматизация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Методы Drag and Drop в Selenium WebDriver

Для выполнения операции перетаскивания (Drag and Drop) в Selenium WebDriver существует несколько подходов, выбор которых зависит от конкретной реализации на веб-странице, сложности элемента и требований теста.

1. Стандартный метод Actions API (наиболее распространенный)

Основной и рекомендуемый способ - использование класса Actions, который предоставляет продвинутые пользовательские взаимодействия.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class DragAndDropExample {
    public void performDragAndDrop(WebDriver driver) {
        // Локаторы элементов
        WebElement sourceElement = driver.findElement(By.id("draggable"));
        WebElement targetElement = driver.findElement(By.id("droppable"));
        
        // Создание объекта Actions
        Actions actions = new Actions(driver);
        
        // Вариант 1: Стандартный drag and drop
        actions.dragAndDrop(sourceElement, targetElement).perform();
        
        // Вариант 2: Пошаговый процесс с задержками
        actions.clickAndHold(sourceElement)
               .moveToElement(targetElement)
               .release()
               .perform();
    }
}
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By

def perform_drag_and_drop(driver):
    # Находим элементы
    source_element = driver.find_element(By.ID, "draggable")
    target_element = driver.find_element(By.ID, "droppable")
    
    # Создаем цепочку действий
    actions = ActionChains(driver)
    
    # Вариант 1: Прямой метод
    actions.drag_and_drop(source_element, target_element).perform()
    
    # Вариант 2: Детализированный подход
    actions.click_and_hold(source_element)\
           .move_to_element(target_element)\
           .release()\
           .perform()

2. Расширенный метод с offset (смещением)

Когда нужно перетащить элемент в определенную точку страницы или относительно другого элемента с точным позиционированием:

// Перетаскивание со смещением по координатам
Actions actions = new Actions(driver);
actions.dragAndDropBy(sourceElement, xOffset, yOffset).perform();

// Или детализированный вариант
actions.clickAndHold(sourceElement)
       .moveByOffset(150, 200)  // смещение на 150px по X и 200px по Y
       .release()
       .build()
       .perform();

3. Использование JavaScript для сложных случаев

В некоторых случаях, особенно с современными JavaScript-фреймворками (React, Angular, Vue), нативные методы Selenium могут не работать. Тогда можно использовать JavaScript Executor:

// JavaScript код для drag and drop
const dragAndDropScript = `
    var source = arguments[0];
    var target = arguments[1];
    
    // Создаем события drag and drop
    var dragStart = new Event('dragstart', { bubbles: true });
    var dragOver = new Event('dragover', { bubbles: true });
    var drop = new Event('drop', { bubbles: true });
    
    source.dispatchEvent(dragStart);
    target.dispatchEvent(dragOver);
    target.dispatchEvent(drop);
`;

// Выполнение через Selenium
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(dragAndDropScript, sourceElement, targetElement);

4. Решение проблем совместимости

Современные веб-приложения часто используют сложные реализации drag and drop. Вот решения для частых проблем:

Проблема: Элементы с complex-трансформациями

// Используем JavaScript для обхода CSS трансформаций
String script = "arguments[0].style.transform = 'none';";
((JavascriptExecutor)driver).executeScript(script, sourceElement);

// Теперь стандартный drag and drop должен работать
new Actions(driver).dragAndDrop(sourceElement, targetElement).perform();

Проблема: iframe или shadow DOM

// Переключение контекста для iframe
driver.switchTo().frame("iframeName");
// Выполнение drag and drop
actions.dragAndDrop(sourceElement, targetElement).perform();
// Возврат к основному контексту
driver.switchTo().defaultContent();

Лучшие практики и рекомендации

  1. Ожидание элементов: Всегда используйте явные ожидания перед операцией

    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    wait.until(ExpectedConditions.elementToBeClickable(sourceElement));
    
  2. Обработка исключений: Реализуйте retry-логику

    int attempts = 0;
    while (attempts < 3) {
        try {
            actions.dragAndDrop(source, target).perform();
            break;
        } catch (StaleElementReferenceException e) {
            // Перепоиск элементов и повторная попытка
            source = driver.findElement(By.id("draggable"));
            target = driver.findElement(By.id("droppable"));
            attempts++;
        }
    }
    
  3. Визуальная проверка: Для критичных тестов добавьте скриншоты

    File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    // Сохранение или сравнение скриншота
    
  4. Cross-browser тестирование: Учитывайте различия в браузерах

    • Chrome/Firefox: обычно работают нативные методы
    • Safari: могут потребоваться дополнительные задержки
    • Мобильные браузеры: используйте Appium с touch actions

Выбор подхода

  • Стандартный Actions API - для большинства случаев
  • JavaScript Executor - когда нативные методы не работают
  • Специализированные библиотеки (Selenide, Robot) - для упрощения кода
  • Собственные реализации - для экзотических фреймворков

Критические аспекты: При реализации drag and drop тестов всегда проверяйте, что состояние DOM после операции соответствует ожидаемому, используйте валидацию через assertions, и учитывайте анимации и переходы, добавляя соответствующие ожидания между действиями.

Как выполнить drag and drop в Selenium? | PrepBro