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

时间:2016-09-11 14:02:15

标签: java selenium

我正在尝试使用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);

Code2: -

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

CODE3: -

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

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

13 个答案:

答案 0 :(得分:1)

如果已知情况不起作用,您可以尝试此解决方案

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

答案 1 :(得分:0)

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

  

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

     

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

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

请在发布前搜索similar question

答案 2 :(得分:0)

您可能想要在对其执行所需操作之前检查是否已启用或显示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();
    }
}

答案 3 :(得分:0)

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

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

然后您可以使用Robot拖放元素

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

我面对类似的问题回来了,我使用了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");
}

您可以参考链接here

答案 6 :(得分:0)

您可以尝试执行以下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

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

答案 7 :(得分:0)

这对我有用:

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

某些版本的硒有时会出现错误。确保您使用的是最新版本,然后单击以进行播放。您可以更轻松地发送要拖放内容的链接

答案 8 :(得分:0)

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

'%d/%m/%Y'

答案 9 :(得分:0)

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

答案 10 :(得分:0)

您可以为此尝试Java脚本执行器吗?

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应用程序上对我有用。

答案 11 :(得分:0)

我也面临同样的问题。请在下面找到自定义Java脚本函数以进行拖放。

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

@pytest.mark.usefixtures('celery_session_app')
@pytest.mark.usefixtures('celery_session_worker')
class MyTest():
    def test(self):
        assert mul.delay(4, 4).get(timeout=10) == 16

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

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

答案 12 :(得分:0)

请参考此基于 Java Script 的解决方案以及由 Dmitrii Bormotov 在 Medium 中提供的示例 Web 应用程序。它是在 python 中的(稍作调整,你就可以在 java 中使用它)

我尝试使用普通 selenium Actions DragAndDrop 方法,使用不同的组合,但对我来说根本不起作用。