5

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

Browser :- IE

asked Sep 12, 2016 at 11:03
8
  • 1
    dragAndDrop function does't work with java 1.8 or later. Commented Sep 12, 2016 at 11:22
  • Really ? Never heard about this issue in the internet. Also, I am able to drag and drop on the different site. Facing issue with this specific site. Commented Sep 12, 2016 at 11:25
  • Naseem, can you add exact error you are facing? Commented Sep 12, 2016 at 16:32
  • @NarendraC ... Code is running without any error but drag and drop is not happening in the application Commented Sep 12, 2016 at 16:54
  • :) That means we are yet to reach to correct step or method, isn't it? Commented Sep 19, 2016 at 13:53

2 Answers 2

4

I have used the following solution (only tested with Chrome, but should be compatible with IE):

The javascript was borrowed from: https://www.packtpub.com/books/content/javascript-execution-selenium

Save the following javascript in a file somewhere in your solution - it makes reuse easier.

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

I have used the following code to read in the javascript and execute the drag and drop.

protected void JavascriptDragAndDrop(IWebElement source, IWebElement target)
{
 string script = System.IO.File.ReadAllText("<Path To Javascript File>");
 script += "simulateHTML5DragAndDrop(arguments[0], arguments[1])";
 IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;
 executor.ExecuteScript(script, source, target);
}

This is C# code, and it looks like you are working with Java, but it should be easy enough to translate. Just read the javascript file into a string, concatenate the line that actually calls the javascript function, and use a JavaScriptExecutor to execute the script.

The linked guide also provides an example of a wrapper method written in Java.

I've tried most of the methods you listed in the question, and this has been the only solution I found that is both reliable and concise.

answered Mar 29, 2017 at 23:02
3
  • Can't try this out right now, but upvote nonetheless. Looking forward to the day I'll be needing this! The Selenium dragAndDrop has never worked except on canvas elements, which is not really applicable in a business environment. Commented May 29, 2017 at 5:35
  • This worked smoothly. Commented Nov 30, 2018 at 10:03
  • I tried this on ag-Grid but it did not work. I got following error: e.dataTransfer.setDragImage is not a function. Am I doing something wrong? Commented Mar 6, 2020 at 2:00
0

(function( $ ) { $.fn.simulateDragDrop = function(options) { return this.each(function() { new $.simulateDragDrop(this, options); }); }; $.simulateDragDrop = function(elem, options) { this.options = options; this.simulateEvent(elem, options); }; $.extend($.simulateDragDrop.prototype, { simulateEvent: function(elem, options) { /Simulating drag start/ var type = "dragstart"; var event = this.createEvent(type); this.dispatchEvent(elem, type, event);

 type = 'dragover';
 var dragOverEvent2 = this.createEvent(type, {pageX: 200, pageY: 300});
 var $dragOverTarget2 = $(options.dropTarget);
 this.dispatchEvent($dragOverTarget2[0], type, dragOverEvent2);
 /*Simulating drop*/
 type = "drop";
 var dropEvent = this.createEvent(type, {});
 dropEvent.offsetX =800;
 dropEvent.offsetY =500;
 dropEvent.dataTransfer = event.dataTransfer;
 var target;
 if (options.dropTargetFrame) {
 target = $(document.querySelector(options.dropTargetFrame).contentDocument.querySelector(options.dropTarget))[0];
 }
 else {
 target = $(options.dropTarget)[0];
 }
 this.dispatchEvent(target, type, dropEvent);
 /*Simulating drag end*/
 type = "dragend";
 var dragEndEvent = this.createEvent(type, {});
 dragEndEvent.dataTransfer = event.dataTransfer;
 this.dispatchEvent(elem, type, dragEndEvent);
 },
 createEvent: function(type) {
 var event = document.createEvent("CustomEvent");
 event.initCustomEvent(type, true, true, null);
 event.dataTransfer = {
 data: {
 },
 types: [],
 setData: function(type, val){
 this.types.push(type)
 this.data[type] = val;
 },
 getData: function(type){
 return this.data[type];
 }
 };
 return event;
 },
 dispatchEvent: function(elem, type, event) {
 if(elem.dispatchEvent) {
 elem.dispatchEvent(event);
 }else if( elem.fireEvent ) {
 elem.fireEvent("on"+type, event);
 }
 }
});

})(jQuery);

answered Jul 8, 2019 at 10:00
1
  • This solution worked for drag and drop web element to canvas Commented Jul 8, 2019 at 10:01

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.