简体   繁体   English

为什么在 Selenium Webdriver 中拖放不起作用?

[英]Why drag and drop is not working in Selenium Webdriver?

I am trying to drag an element into another element using Selenium WebDriver but it's not working.我正在尝试使用 Selenium WebDriver 将一个元素拖到另一个元素中,但它不起作用。 I tried all the solutions which I can find on internet but none of the solutions seems to be working for me.我尝试了所有可以在互联网上找到的解决方案,但似乎没有一个解决方案对我有用。

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

Code1:-代码 1:-

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

Code2:-代码2:-

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

Code3:-代码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);

Code4:-代码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);

None of the above code is working for me.以上代码都不适合我。 All the above runs without any error but drag and drop is not happening in the application.以上所有运行都没有任何错误,但在应用程序中没有发生拖放。 Anyone having any other solution ?任何人有任何其他解决方案? Thanks.谢谢。

Can you try Java Script Executor for this您可以为此尝试 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);

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

It works for me on web application which are angular based.它适用于基于角度的 Web 应用程序。

I have also faced the same issue.我也遇到过同样的问题。 Please find below custom java-script function for drag & drop.请在下面找到用于拖放的自定义 java 脚本函数。

1) Create DragDrop.js file and paste below code in it 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) Using below code we can call above custom function(Below is C# code) 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);

If the known cases do not work, you can try this solution如果已知情况不起作用,您可以尝试此解决方案

        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();

In your code 1: Not calling perform() method, it should be在您的代码 1 中:不调用 perform() 方法,应该是

 Actions builder = new Actions( _controls.getDriver());

 builder.dragAndDrop(sourceelement, destelement).perform();

In your code 2: I don't think you need to call release()在您的代码 2 中:我认为您不需要调用 release()

Please search for similar question s before posting.发帖前请搜索类似问题

You might want to check if webelement is enabled or displayed prior performing desired action over it.在对其执行所需操作之前,您可能需要检查 webelement 是否已启用或显示。 You may give it a try with below code你可以试试下面的代码

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();
    }
}

I would suggest you try the following solution:我建议您尝试以下解决方案:

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();

You may then use Robot to drag and drop the element然后您可以使用 Robot 拖放元素

I would suggest you to use Touch Action to perform drag and drop.我建议您使用 Touch Action 来执行拖放操作。

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

I have face similar problem way back, I have used dragAndDropBy to move slider but it didn't worked for me but later I found help and below the snippet for my working code:我以前也遇到过类似的问题,我使用过 dragAndDropBy 来移动滑块,但它对我没有用,但后来我找到了帮助,并在我的工作代码片段下方找到了帮助:

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");
}

You can refer the link here你可以参考这里的链接

You may try executing the following javascript to perform drag and drop您可以尝试执行以下 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);

Please find more details here .在此处找到更多详细信息。

It works perfectly for all the browsers and devices.它适用于所有浏览器和设备。

This is working for me :这对我有用:

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();

There are sometimes bugs in some version of selenium.某些版本的 selenium 有时会出现错误。 Make sure you use the lastest one and play around with clicking.确保您使用最新的并点击播放。 Would be easier of you can send a link of what you are trying to drag/drop您可以发送您尝试拖放的内容的链接会更容易

I've tried a bunch of workarounds, this one seems to work for me using macOS and chromedriver我尝试了很多变通方法,这个方法似乎对我使用 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);
}

Please refer this Java Script based solution with sample web application given By Dmitrii Bormotov in Medium.请参考此基于 Java Script 的解决方案以及Dmitrii Bormotov在 Medium 中给出的示例 Web 应用程序。 It's in python (With little tweak you can use it in java)它在python中(只需稍作调整,您就可以在java中使用它)

I tried using plain selenium Actions DragAndDrop method, with different combinations and it was not at all working for me.我尝试使用具有不同组合的普通 selenium Actions DragAndDrop方法,但对我来说根本不起作用。

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM