【问题标题】:Why drag and drop is not working in Selenium Webdriver?为什么拖放在 Selenium Webdriver 中不起作用?
【发布时间】:2017-01-19 02:20:45
【问题描述】:

我正在尝试使用 Selenium WebDriver 将一个元素拖到另一个元素中,但它不起作用。我尝试了所有可以在互联网上找到的解决方案,但似乎没有一个解决方案对我有用。

WebElement sourceelement = driver.findElement(By.cssSelector("XXX"));
WebElement destelement = driver.findElement(By.cssSelector("YYY"));

代码1:-

Actions builder = new Actions( _controls.getDriver());
builder.dragAndDrop(sourceelement, destelement);

代码2:-

Actions builder = new Actions(_controls.getDriver());
Action dragAndDrop =
builder.clickAndHold(sourceelement).moveToElement(destelement).release(destelement).build();
Thread.sleep(2000);
dragAndDrop.perform()

代码3:-

Point coordinates1 = sourceelement.getLocation();
Point coordinates2 = destelement.getLocation();  
Robot robot = new Robot();           
robot.mouseMove(coordinates1.getX(), coordinates1.getY());
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseMove(coordinates2.getX(), coordinates2.getY());
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Thread.sleep(2000);

代码4:-

final String java_script =
"var src=arguments[0],tgt=arguments[1];var dataTransfer={dropEffe" +
                "ct:'',effectAllowed:'all',files:[],items:{},types:[],setData:fun" +
                "ction(format,data){this.items[format]=data;this.types.append(for" +
                "mat);},getData:function(format){return this.items[format];},clea" +
                "rData:function(format){}};var emit=function(event,target){var ev" +
                "t=document.createEvent('Event');evt.initEvent(event,true,false);" +
                "evt.dataTransfer=dataTransfer;target.dispatchEvent(evt);};emit('" +
                "dragstart',src);emit('dragenter',tgt);emit('dragover',tgt);emit(" +
                "'drop',tgt);emit('dragend',src);";

        ((JavascriptExecutor)_controls.getDriver()).executeScript(java_script, sourceelement, destelement);
        Thread.sleep(2000);

以上代码都不适合我。以上所有运行都没有任何错误,但应用程序中没有发生拖放。有人有其他解决方案吗?谢谢。

【问题讨论】:

  • 你在为 HTML5 尝试这个吗?
  • 它在查看源页面中以 开头。所以是的,它是 html5 页面。
  • 看看这个 - stackoverflow.com/questions/29381233/…。甚至有人用相应的 java 代码创建了一个 github。
  • 是的,我之前也看到了同样的问题,并尝试使用 github 站点中提到的 js 文件,但它在我的情况下不起作用:(
  • 我们需要知道 HTML,但是如果它是一个标准的 HTML5 页面,如果没有一些额外的工作来触发特定的 JS 回调,它将无法在 selenium 中工作

标签: java selenium


【解决方案1】:

您可以为此尝试 Java Script Executor

JavascriptExecutor js = (JavascriptExecutor)driver
js.executeScript("function createEvent(typeOfEvent) {\n" + "var event =document.createEvent(\"CustomEvent\");\n"
                    + "event.initCustomEvent(typeOfEvent,true, true, null);\n" + "event.dataTransfer = {\n" + "data: {},\n"
                    + "setData: function (key, value) {\n" + "this.data[key] = value;\n" + "},\n"
                    + "getData: function (key) {\n" + "return this.data[key];\n" + "}\n" + "};\n" + "return event;\n"
                    + "}\n" + "\n" + "function dispatchEvent(element, event,transferData) {\n"
                    + "if (transferData !== undefined) {\n" + "event.dataTransfer = transferData;\n" + "}\n"
                    + "if (element.dispatchEvent) {\n" + "element.dispatchEvent(event);\n"
                    + "} else if (element.fireEvent) {\n" + "element.fireEvent(\"on\" + event.type, event);\n" + "}\n"
                    + "}\n" + "\n" + "function simulateHTML5DragAndDrop(element, destination) {\n"
                    + "var dragStartEvent =createEvent('dragstart');\n" + "dispatchEvent(element, dragStartEvent);\n"
                    + "var dropEvent = createEvent('drop');\n"
                    + "dispatchEvent(destination, dropEvent,dragStartEvent.dataTransfer);\n"
                    + "var dragEndEvent = createEvent('dragend');\n"
                    + "dispatchEvent(element, dragEndEvent,dropEvent.dataTransfer);\n" + "}\n" + "\n"
                    + "var source = arguments[0];\n" + "var destination = arguments[1];\n"
                    + "simulateHTML5DragAndDrop(source,destination);", ElementFrom, ElementTo);

参考:https://www.linkedin.com/pulse/javascriptexecutor-selenium-gaurav-gupta/

它适用于基于角度的 Web 应用程序。

【讨论】:

  • 工作!打得好!
  • 这适用于我的 Java/ReactJS 实现!使用 org.openqa.selenium 3.141
【解决方案2】:

如果已知情况都不起作用,你可以试试这个解决方案

        WebElement a = driver.findElement(By.cssSelector("your_selector"));
        WebElement b = driver.findElement(By.cssSelector("your_selector"));

        int x = b.getLocation().x;
        int y = b.getLocation().y;

        Actions actions = new Actions(driver);
        actions.moveToElement(a)
                .pause(Duration.ofSeconds(1))
                .clickAndHold(a)
                .pause(Duration.ofSeconds(1))
                .moveByOffset(x, y)
                .moveToElement(b)
                .moveByOffset(x,y)
                .pause(Duration.ofSeconds(1))
                .release().build().perform();

【讨论】:

  • 尝试了很多解决方案,但这在我的反应应用程序中非常有效。谢谢
【解决方案3】:

我也遇到了同样的问题。请在下面找到用于拖放的自定义 java-script 函数。

1) 创建 DragDrop.js 文件并将以下代码粘贴到其中

    function customEvent(typeOfEvent) {
    var event = document.createEvent("CustomEvent");
    event.initCustomEvent(typeOfEvent, true, true, null);
    event.dataTransfer = {
        data: {},
        setData: function (key, value) {
            this.data[key] = value;
        },
        getData: function (key) {
            return this.data[key];
        }
    };
    return event;
}
function dispatchEvent(element, event, transferData) {
    if (transferData !== undefined) {
        event.dataTransfer = transferData;
    }
    if (element.dispatchEvent) {
        element.dispatchEvent(event);
    } else if (element.fireEvent) {
        element.fireEvent("on" + event.type, event);
    }
}
function executeDrageAndDrop(element, target) {
    var dragStartEvent = customEvent('dragstart');
    dispatchEvent(element, dragStartEvent);
    var dropEvent = customEvent('drop');
    dispatchEvent(target, dropEvent, dragStartEvent.dataTransfer);
    var dragEndEvent = customEvent('dragend');
    dispatchEvent(element, dragEndEvent, dropEvent.dataTransfer);
}

2)使用下面的代码我们可以调用上面的自定义函数(下面是C#代码)

string script = System.IO.File.ReadAllText(@"{filepath of DragDrop.js file}");
script = script + "executeDrageAndDrop(arguments[0], arguments[1])";
IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;

IWebElement source = driver.findElement(By......);
IWebElement target = driver.findElement(By......);

executor.ExecuteScript(script, source, target);

【讨论】:

    【解决方案4】:

    请参考这个基于 Java 脚本的解决方案,其中包含由 Dmitrii Bormotov 在 Medium 中提供的示例 Web 应用程序。它在 python 中(只需稍加调整,您就可以在 java 中使用它)

    我尝试使用普通硒 Actions DragAndDrop 方法,有不同的组合,但它根本不适合我。

    【讨论】:

      【解决方案5】:

      您可能希望在对其执行所需操作之前检查是否启用或显示了 webelement。你可以试试下面的代码

      public void dragAndDrop(WebElement sourceElement, WebElement destinationElement) {
          try {
              if (sourceElement.isDisplayed() && destinationElement.isDisplayed()) {
                  Actions action = new Actions(driver);
                  action.dragAndDrop(sourceElement, destinationElement).build().perform();
              } else {
                  System.out.println("Element was not displayed to drag");
              }
          } catch (StaleElementReferenceException e) {
              System.out.println("Element with " + sourceElement + "or" + destinationElement + "is not attached to the page document "
                      + e.getStackTrace());
          } catch (NoSuchElementException e) {
              System.out.println("Element " + sourceElement + "or" + destinationElement + " was not found in DOM "+ e.getStackTrace());
          } catch (Exception e) {
              System.out.println("Error occurred while performing drag and drop operation "+ e.getStackTrace());
          }
      }
      
      
      public void dragAndDrop(WebElement sourceElement, WebElement destinationElement)
          {
              (new Actions(driver)).dragAndDrop(sourceElement, destinationElement).perform();
          }
      }
      

      【讨论】:

      • 感谢 Nandesh,但元素已启用。尝试使用上面的代码,它运行没有任何错误,但没有拖放
      • @Naseem 你介意分享 Selenium webdriver、页面源代码、浏览器的版本吗?假设您与之交互的 Web 元素支持拖放操作。
      • 我使用 Seleniun 版本为 2.53.0,浏览器为 IE。很遗憾无法在此处分享页面源代码。
      【解决方案6】:

      我建议您尝试以下解决方案:

      WebElement sourceelement  = driver.findElement(By.cssSelector("XXX"));
      Locatable element = (Locatable)sourceelement ;
      Point p= element.getCoordinates().inViewPort();
      int sourceX=p.getX();
      int sourceY=p.getY();
      
      WebElement destelement = driver.findElement(By.cssSelector("YYY"));
      Locatable elementTarget = (Locatable)destelement;
      Point Target= elementTarget.getCoordinates().inViewPort();
      int targetX=Target.getX();
      int targetY=Target.getY();
      

      然后您可以使用机器人拖放元素

      【讨论】:

        【解决方案7】:

        我建议你使用 Touch Action 来执行拖放操作。

        Point coordinates1 = sourceelement.getLocation();
        Point coordinates2 = destelement.getLocation();  
        TouchActions builder = new TouchActions(driver);
        builder.longPress(coordinates1)
               .move(coordinates2).release(coordinates2).perform();
        

        【讨论】:

          【解决方案8】:

          我以前也遇到过类似的问题,我曾使用 dragAndDropBy 来移动滑块,但它对我没有用,但后来我找到了帮助,并在我的工作代码的 sn-p 下方:

          public static void slider(){
          x=10;
          WebElement slider = driver.findElement(By.id("slider"));
          int width=slider.getSize().getWidth();
          Actions move = new Actions(driver);
          move.moveToElement(slider, ((width*x)/100), 0).click();
          move.build().perform();
          System.out.println("Slider moved");
          }
          

          可以参考链接here

          【讨论】:

            【解决方案9】:

            您可以尝试执行以下 javascript 来执行拖放操作

            WebDriver _driver;
            WebElement _sourceElement = _driver.findElement(<source>);
            WebElement _targetElement = _driver.findElement(<source>);
            JavascriptExecutor _js = (JavascriptExecutor) _driver;
            _js.executeScript("$(arguments[0]).simulate('drag-n-drop',{dragTarget:arguments[1],interpolation:{stepWidth:100,stepDelay:50}});", _sourceElement, _targetElement);
            

            更多详情请查看here

            它适用于所有浏览器和设备。

            【讨论】:

              【解决方案10】:

              这对我有用:

              Actions act = new Actions(driver);
              act.moveToElement(element, (elementWidth / 2), elementHeight / 2).clickAndHold().build().perform();
              act.moveToElement(dest, (destWidth / 2) , (destHeight / 2)).release().build().perform();
              

              在某些版本的 selenium 中有时会出现错误。确保您使用最新的并玩弄点击。你可以发送一个你试图拖放的链接会更容易

              【讨论】:

                【解决方案11】:

                我尝试了很多解决方法,这个似乎对我使用 macOS 和 chromedriver 有效

                public void dragAndDrop(WebElement source, WebElement target) throws AWTException {
                    new Actions(driver).dragAndDrop(source, target).release().build().perform();
                    Robot robot = new Robot();
                    robot.keyPress(KeyEvent.VK_ESCAPE);
                    robot.keyRelease(KeyEvent.VK_ESCAPE);
                }
                

                【讨论】:

                  【解决方案12】:

                  在您的代码 1 中: 不调用 perform() 方法, 应该是

                   Actions builder = new Actions( _controls.getDriver());
                  
                   builder.dragAndDrop(sourceelement, destelement).perform();
                  

                  在您的代码 2 中:我认为您不需要调用 release()

                  发帖前请搜索similar questions。

                  【讨论】:

                  • 在代码 1 和代码 2 中进行了所需的更改后,它仍然无法正常工作。此外,我确实对拖放功能进行了很多研究,这就是我能够找到这么多代码的原因。当他们都没有工作时,只有我发布了我的问题。谢谢:)
                  【解决方案13】:
                  Actions act = new Actions(driver);
                  WebElement source = driver.findElement(By.id("XXX"));
                  WebElement destination = driver.findElement(By.id("XXX"));
                  
                  Action dragAndDrop =act.moveToElement(source,destination).build().perform();
                  

                  【讨论】:

                  • 试着解释你的答案,以便其他人利用它。
                  猜你喜欢
                  • 2018-01-22
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-31
                  • 2014-08-15
                  • 2018-02-26
                  • 1970-01-01
                  相关资源
                  最近更新 更多