You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium Chrome Driver调用dragAndDrop卡顿,需物理移动鼠标恢复

Selenium拖拽操作卡顿需手动移动鼠标才能继续的问题

问题场景

  • 目标网站:https://app.involve.me/
  • 操作流程:
    1. 登录网站
    2. 从头创建新项目
    3. 尝试从右侧列表拖拽任意元素时,Selenium会卡顿,必须手动移动物理鼠标,测试才会继续执行
  • 技术栈:TestNG 框架 + Selenium 4.3.0

selenium hangs

现有代码

public void dragAndDropCleanPage(String imageName) {
    try {
        WebElement to = driver.findElement(By.cssSelector("[class='e-target-dropzone vcentered bgfixed center-center']"));
        List<WebElement> listOfImages = imageList;
        for(WebElement el : listOfImages ) {
            WebElement text = el.findElement(By.cssSelector("[class='v-title'] p"));
            if(getText(text).equalsIgnoreCase(imageName)){
                WebElement drag = el;
                Actions act = new Actions(driver);
                act.clickAndHold(drag)
                .pause(Duration.ofSeconds(1))
                .moveToElement(to)
                .pause(Duration.ofSeconds(1))
                .moveByOffset(0,1)
                .pause(Duration.ofSeconds(1))
                .release(to)
                .pause(Duration.ofSeconds(1))
                .build().perform();
                break;
            }
        }
    }catch (Exception e) {
        System.out.println("Did not find the requested item");
    }
}

注:代码通过名称选取对应元素,已使用PageFactory定位元素,尝试过Actions拖拽、JavaScript Executor等方案,问题仍未解决。

解决方案尝试

1. 启用原生事件

Selenium默认的合成事件可能无法被目标网站的拖拽监听逻辑识别,开启原生事件可模拟真实鼠标操作:

ChromeOptions options = new ChromeOptions();
options.addArguments("--enable-native-events");
WebDriver driver = new ChromeDriver(options);

(Firefox可通过设置dom.w3c_events.enabled为true开启原生事件)

2. 简化Actions操作逻辑

过多的pause可能导致事件队列阻塞,尝试用原生dragAndDrop方法或分步执行减少等待时长:

// 方案一:直接使用dragAndDrop
Actions act = new Actions(driver);
act.dragAndDrop(drag, to).perform();

// 方案二:分步执行,缩短等待
Actions act = new Actions(driver);
act.clickAndHold(drag).perform();
Thread.sleep(300); // 短等待确保元素被选中
act.moveToElement(to).perform();
Thread.sleep(300);
act.release(to).perform();

3. 模拟完整拖拽事件链

部分前端框架需要监听完整的拖拽事件序列,手动触发dragstart/dragover/drop/dragend事件:

// 封装执行脚本方法
private void executeScript(String script, WebElement element) {
    ((JavascriptExecutor) driver).executeScript(script, element);
}

// 触发完整拖拽事件
executeScript("var event = new MouseEvent('dragstart', {bubbles: true, cancelable: true, clientX: arguments[0].getBoundingClientRect().x + 10, clientY: arguments[0].getBoundingClientRect().y + 10}); arguments[0].dispatchEvent(event);", drag);
executeScript("var event = new MouseEvent('dragover', {bubbles: true, cancelable: true, clientX: arguments[0].getBoundingClientRect().x + 10, clientY: arguments[0].getBoundingClientRect().y + 10}); arguments[0].dispatchEvent(event);", to);
executeScript("var event = new MouseEvent('drop', {bubbles: true, cancelable: true, clientX: arguments[0].getBoundingClientRect().x + 10, clientY: arguments[0].getBoundingClientRect().y + 10}); arguments[0].dispatchEvent(event);", to);
executeScript("var event = new MouseEvent('dragend', {bubbles: true, cancelable: true, clientX: arguments[0].getBoundingClientRect().x + 10, clientY: arguments[0].getBoundingClientRect().y + 10}); arguments[0].dispatchEvent(event);", drag);

注:clientX/clientY取元素内部坐标,确保事件触发有效。

4. 确保元素完全可交互

拖拽前显式等待元素加载完成并可交互:

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.elementToBeClickable(drag));
wait.until(ExpectedConditions.elementToBeClickable(to));

内容的提问来源于stack exchange,提问作者talvi8942

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 20:09:10