Naseem
Naseem

Reputation: 961

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. I tried all the solutions which I can find on the 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:-

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

Code4:-

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 codes is working for me. All the above runs without any error but drag and drop is not happening in the application. Does anyone have any other solution? Thanks.

Upvotes: 18

Views: 27942

Answers (13)

Norayr Sargsyan
Norayr Sargsyan

Reputation: 1868

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

If you want to drag the element in a different area(not to drag the element to another one) you can use this scenario for that:

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

Actions actions = new Actions(driver);
actions.moveToElement(source)
            .pause(Duration.ofSeconds(1))
            .clickAndHold(source)
            .pause(Duration.ofSeconds(1))
            .moveByOffset(0,50) //change the x, y values to be applicable for your cases
            .moveByOffset(0,50)
            .pause(Duration.ofSeconds(1))
            .release().build().perform();
}

Upvotes: 6

Anver Sadhat
Anver Sadhat

Reputation: 3240

Please refer this Java Script based solution with sample web application given By Dmitrii Bormotov in Medium. It's in python (With little tweak you can use it in java)

I tried using plain selenium Actions DragAndDrop method, with different combinations and it was not at all working for me.

Upvotes: 1

FayazMd
FayazMd

Reputation: 386

In your code 1: Not calling perform() method, it should be

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

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

In your code 2: I don't think you need to call release()

Please search for similar questions before posting.

Upvotes: 0

atul parate
atul parate

Reputation: 780

I have also faced the same issue. Please find below custom java-script function for drag & drop.

1) Create DragDrop.js file and paste below code in it

    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)

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

Upvotes: 2

Gaurav_QA
Gaurav_QA

Reputation: 131

Can you try Java Script Executor for this

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/

It works for me on web application which are angular based.

Upvotes: 13

gautam
gautam

Reputation: 1

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

Upvotes: -1

Nathaniel Yearwood
Nathaniel Yearwood

Reputation: 1

I've tried a bunch of workarounds, this one seems to work for me using macOS and 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);
}

Upvotes: 0

mosaad
mosaad

Reputation: 2381

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. 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

Upvotes: 0

Kenil Fadia
Kenil Fadia

Reputation: 234

You may try executing the following javascript to perform drag and drop

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.

Upvotes: 0

Karim Narsindani
Karim Narsindani

Reputation: 454

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:

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

Upvotes: 0

badal16
badal16

Reputation: 509

I would suggest you to use Touch Action to perform drag and drop.

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

Upvotes: 0

BountyHunter
BountyHunter

Reputation: 1411

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

Upvotes: 1

nandesh kalyankar
nandesh kalyankar

Reputation: 302

You might want to check if webelement is enabled or displayed prior performing desired action over it. 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();
    }
}

Upvotes: 0

Related Questions