0

I am trying to drag and drop an element from side panel to form. Drag and drop code what I wrote is like below.

Actions builder = new Actions(driver);
builder.dragAndDrop(source, target).build().perform();

This works fine in all browser except IE11.

I tried other approaches like

Approach 1 -

builder.clickAndHold(source)
        .moveToElement(target)
        .release(target)
        .build()
        .perform();

Approach 2 -

builder.clickAndHold(source)
    .pause(Duration.ofSeconds(1))
    .moveByOffset(-1, -1)
    .pause(Duration.ofSeconds(1))
    .moveToElement(target)
    .pause(Duration.ofSeconds(1))
    .moveToElement(target)
    .pause(Duration.ofSeconds(1))
    .release(target)
    .build()
    .perform();

but nothing works.

Above all options do nothing on the page but they are getting executed without any error. I have also tried all the javascript solutions given in different stackoverflow/gitHub links but nothing is working.

Can anyone help me on this?

Edit 1-

As I mentioned earlier, I have tried all the possible/mentioned solutions but none of there are working. Here is my code.

package dragAndDrop;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.testng.annotations.Test;

public class DryRunIE{

    WebDriver driver;

    @Test
    public void dragAndDrop() {

        System.setProperty("webdriver.ie.driver", System.getProperty("user.dir") + "/Drivers/IEDriverServer.exe");
        driver = new InternetExplorerDriver();

        driver.get("https://jqueryui.com/droppable/");
        driver.manage().window().maximize();
        driver.switchTo().frame(0);

        try {
            //simulateDragAndDrop(driver.findElement(By.id("draggable")), driver.findElement(By.id("droppable")));
            //simulateDragDrop(driver.findElement(By.id("draggable")), driver.findElement(By.id("droppable")));
            dragAndDropHelper();
        } catch (Exception e) {
            e.printStackTrace();
        }

        driver.quit();
        try {
            Runtime.getRuntime().exec("taskkill /F /IM IEDriverServer.exe");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void simulateDragAndDrop(WebElement elementToDrag, WebElement target) throws Exception {

        JavascriptExecutor js = (JavascriptExecutor) driver;
        String script = "function createEvent(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 simulateHTML5DragAndDrop(element,target) { "
                + "var dragStartEvent =createEvent('dragstart'); " + "dispatchEvent(element, dragStartEvent); "
                + "var dropEvent = createEvent('drop'); "
                + "dispatchEvent(target, dropEvent,dragStartEvent.dataTransfer); "
                + "var dragEndEvent = createEvent('dragend'); "
                + "dispatchEvent(element, dragEndEvent,dropEvent.dataTransfer);" + "}" + ""
                + "var elementToDrag = arguments[0];" + "var targetElem = arguments[1];" + ""
                + "simulateHTML5DragAndDrop(elementToDrag,targetElem);";
        js.executeScript(script, elementToDrag, target);
    }

    private void simulateDragDrop(WebElement ele_source, WebElement ele_target) {
        final String JS_DnD =
                "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);";

                // drag and drop item two into the bin
                ((JavascriptExecutor)driver).executeScript(JS_DnD, ele_source, ele_target);
    }

    private void dragAndDropHelper() {

        String script = null;
        try {
            script = readFile(System.getProperty("user.dir") + "\\drag_and_drop_helper.js");
        } catch (IOException e) {
            e.printStackTrace();
        }

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript(script + "$('#draggable').simulateDragDrop({ dropTarget: '#droppable'});");
        System.out.println();
    }

    // helper method
    private static String readFile(String file) throws IOException {
        Charset cs = Charset.forName("UTF-8");
        FileInputStream stream = new FileInputStream(file);
        try {
            Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
            StringBuilder builder = new StringBuilder();
            char[] buffer = new char[8192];
            int read;
            while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
                builder.append(buffer, 0, read);
            }
            return builder.toString();
        } finally {
            stream.close();
        }
    }
}

I have tried below function one by one uncommenting and executing but all of them gets executed successfully and nothing happens on page.

Note : I got drag_and_drop_helper.js from https://gist.github.com/rcorreia/2362544.

Is there anything I am missing or doing wrong here?

Thanks, Chandresh Parmar

4 Answers4

2

Seems like a known issue with IE11 that no one has been able to fix.

There's a relevant GitHub issue opened in the Selenium repository, but it's been closed due to lack of a working, reproducible example:

https://github.com/SeleniumHQ/selenium/issues/6354

Other users on StackExchange have been seeing this problem since 2016, with no real resolution:

Unable to Automate Drag and Drop for IE11 : Selenium WebDriver (no working resolution)

https://sqa.stackexchange.com/questions/22534/why-drag-and-drop-is-not-working-in-selenium-webdriver/26500 (no accepted answer, but a few upvotes on one)

My guess is IE driver is just flaky, and drag and drop may work on some websites, but not others, for unknown reasons. You may have better luck opening a GitHub issue in the Selenium repository, and provide a working code sample / URL where drag and drop is absolutely not working, all of the time.

CEH
  • 5,701
  • 2
  • 16
  • 40
  • You mentioned _...IE driver is just flaky..._ without any proof. That is quite unjustified. For the record, if drag and drop works with other browsers, it would work with IE too. – undetected Selenium Nov 20 '19 at 20:21
  • 1
    I mentioned it's a guess, and that's based on multiple reports of drag&drop working successfully on Chrome/Firefox but not IE -- some of these issues are dating back to 2015, 2016, and many of the reports are the same, most lack any resolution whatsoever. The language of my answer does not suggest what I say is canon, it's just a guess based on repeated observation in addition to my personal troubles with IE driver. – CEH Nov 20 '19 at 20:30
0

Drag and drop is problematic now with Selenium. Here a simulation of drag and drop is described: How to simulate HTML5 Drag and Drop in Selenium Webdriver?

Frank
  • 831
  • 1
  • 11
  • 23
  • This issue is specific to _HTML5 drag and drop issue_. JS based drag and drop still works. – undetected Selenium Nov 20 '19 at 20:24
  • @Frank - Thanks for your inputs. Please see my post below. I have already tried every javascript solutions posted on different threads but none of them works. Please review the code and let me know if I am missing anything. – Chandresh Parmar Nov 22 '19 at 08:53
0

I tried with the answer in this thread: Unable to Automate Drag and Drop for IE11 : Selenium WebDriver (which also mentioned by Christine). It can work well in IE11 with the test page in the code and the drag and drop page of w3schools. You only need to replace the website url of your owns and the two elements' ids with your owns in the code.

----------------------------------------------------------------Edit--------------------------------------------------------------

The website you provided is about jQuery drag&drop. It's different from HTML5 drag&drop. Besides, the drag&drop elements is in an iframe. We need to use switchTo() to reach the iframe at first. You could check the code below, it can work well in IE:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.ie.InternetExplorerDriver; 
import org.openqa.selenium.WebElement; 
import org.openqa.selenium.interactions.Actions;

public class IEauto {
    public static void main(String[] args) { 

     //add the IE web driver path here.. 
      System.setProperty("webdriver.ie.driver","C:\\yourpath\\IEDriverServer_x64_3.14.0\\IEDriverServer.exe");             
      WebDriver driver = new InternetExplorerDriver(); 

     //replace the URL of the web page here.. 
      driver.get("https://jqueryui.com/droppable/"); 
     //int size = driver.findElements(By.tagName("iframe")).size();
      driver.switchTo().frame(0);

      WebElement ele_source = driver.findElement(By.id("draggable"));
      WebElement ele_target = driver.findElement(By.id("droppable"));

      Actions builder = new Actions(driver);
      builder.dragAndDrop(ele_source, ele_target).build().perform();
    } 
}

The result is like this: enter image description here

Yu Zhou
  • 11,532
  • 1
  • 8
  • 22
  • Thanks for your inputs. Please see my post below. I have already tried every javascript solutions posted on different threads but none of them works. Please review the code and let me know if I am missing anything. – Chandresh Parmar Nov 22 '19 at 08:53
  • 1
    From the website in your code, you're simulating jQuery drag and drop, it's different from HTML5 drag and drop. You could also refer to [this thread](https://stackoverflow.com/questions/45084311/selenium-drag-and-dropping-a-jquery-element) for solutions of simulating jQuery drag and drop. – Yu Zhou Nov 22 '19 at 09:55
  • @ChandreshParmar I updated my answer. Please check my sample code, it can work well in IE 11. – Yu Zhou Nov 26 '19 at 08:58
0

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

Note: For Java - Convert above C# code into Java and try it. I have tried above code and it is working for IE, Edge, and Chrome browsers.

atul parate
  • 760
  • 5
  • 5