Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create the `simulateDragDrop` function which can be used to simulate clicking and dragging one DOM Node onto another
function simulateDragDrop(sourceNode, destinationNode) {
var EVENT_TYPES = {
DRAG_END: 'dragend',
DRAG_START: 'dragstart',
DROP: 'drop'
}
function createCustomEvent(type) {
var event = new CustomEvent("CustomEvent")
event.initCustomEvent(type, true, true, null)
event.dataTransfer = {
data: {
},
setData: function(type, val) {
this.data[type] = val
},
getData: function(type) {
return this.data[type]
}
}
return event
}
function dispatchEvent(node, type, event) {
if (node.dispatchEvent) {
return node.dispatchEvent(event)
}
if (node.fireEvent) {
return node.fireEvent("on" + type, event)
}
}
var event = createCustomEvent(EVENT_TYPES.DRAG_START)
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_START, event)
var dropEvent = createCustomEvent(EVENT_TYPES.DROP)
dropEvent.dataTransfer = event.dataTransfer
dispatchEvent(destinationNode, EVENT_TYPES.DROP, dropEvent)
var dragEndEvent = createCustomEvent(EVENT_TYPES.DRAG_END)
dragEndEvent.dataTransfer = event.dataTransfer
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_END, dragEndEvent)
}
@readingtype

This comment has been minimized.

Copy link

@readingtype readingtype commented Aug 27, 2015

Arguably clearer than the original (https://gist.github.com/rcorreia/2362544). Thanks for providing a native version :)

@jmcollin78

This comment has been minimized.

Copy link

@jmcollin78 jmcollin78 commented Sep 3, 2015

Can you explain how to use this script in a Protractor test please ?
I'm trying to test DragAndDrop with Protractor without success and I see your script below but I can't figure out how to use it.

@andrey5555

This comment has been minimized.

Copy link

@andrey5555 andrey5555 commented Oct 5, 2015

Hi, could you please explain how to use this script in java script (code snippet).
I would like to try it in Protractor.
Thank you.
Andrey

@andrey5555

This comment has been minimized.

Copy link

@andrey5555 andrey5555 commented Oct 5, 2015

I am getting ReferenceError: CustomEvent is not defined - error

line var event = new CustomEvent("CustomEvent")

@davewood

This comment has been minimized.

Copy link

@davewood davewood commented Nov 24, 2015

Is the simulation supposed to work with all drag&drop libs?

http://jsbin.com/bupeqavaca/1/edit?html,js,output

No drag and drop is taking place, no error messages in the console either. any ideas?

@ewashbourne

This comment has been minimized.

Copy link

@ewashbourne ewashbourne commented Dec 10, 2015

Has anyone figured out how to use this script in Protractor?

@minmur

This comment has been minimized.

Copy link

@minmur minmur commented Jan 7, 2016

I did such things to make it work in Protractor:

  1. changed 1st line to module.exports = function simulateDragDrop(sourceNode, destinationNode) {;
  2. then in spec:
var dragAndDropFn = require(path + '/native_js_drag_and_drop_helper.js');

/* ... */

it('should drag', function () {
  var field = element.all(by.className('drag-handle')).get(0);
  var src = element.all(by.className('box-list-compact-hover')).get(0);

  browser.executeScript(dragAndDropFn, field.getWebElement(), src.getWebElement());
});
@nvega-ms

This comment has been minimized.

Copy link

@nvega-ms nvega-ms commented Jan 8, 2016

Hi @minmur, Could you please tell me the selenium version that you are using? Thanks

@satyasrikanth

This comment has been minimized.

Copy link

@satyasrikanth satyasrikanth commented Jan 20, 2016

Hi, Its working on chrome and firefox, but failing on IE11. Should I need to change anything for this to work on IE11? Please help

@satyasrikanth

This comment has been minimized.

Copy link

@satyasrikanth satyasrikanth commented Jan 22, 2016

For the script to work in IE11,
I just changed a line
var event = new CustomEvent("CustomEvent") (As IE dont support CustomEvent Constructor)
with
var event=document.createEvent("CustomEvent"); (Now all browsers including IE supports).

Please commit the same in the original too

@EvanBurbidge

This comment has been minimized.

Copy link

@EvanBurbidge EvanBurbidge commented Jan 28, 2016

Hey @minmur did you include the script as a separate file or was it in your test file? Also could you tell me where the path variable is defined? Or is this a build in function in protractor?

@digicom1978

This comment has been minimized.

Copy link

@digicom1978 digicom1978 commented Feb 2, 2016

Hello, @minmur. Thank you for your converting. But, still I don't know how to use it with protractor.
Below code is my spec.js. Is there anything I missed?

var dragAndDropFn = require('./native_js_drag_and_drop_helper.js');

describe('Drag and Drop Test', function() {
it('should drag', function () {

    browser.get("http://html5demos.com/drag");

    var field = element.all(by.className('drag-handle')).get(0);
    var src = element.all(by.className('box-list-compact-hover')).get(0);

    browser.executeScript(dragAndDropFn, field.getWebElement(), src.getWebElement());

}, 60000);

});

Thanks in advance.

@pidupuis

This comment has been minimized.

Copy link

@pidupuis pidupuis commented Mar 1, 2016

I try to move an element by dragging and droping it through a list of draggable elements.
In my case, it causes a duplication of the draggable element into the list. Any idea ?

@kodayashi

This comment has been minimized.

Copy link

@kodayashi kodayashi commented Mar 4, 2016

Hi there,

Trying to get this working in a Java project. I've loaded this JS and am trying to execute it with
((JavascriptExecutor) driver).executeScript(html5Helper + "simulateDragDrop(arguments[0], arguments[1]);", dragTarget, dropTarget);

In the code above, html5Helper is a string representation of the source above, and dragTarget/dropTarget are selenium WebElements. The JS is executing, and events are dispatching, but drag-and-drop isn't working. Any thoughts?

@marinatouceda

This comment has been minimized.

Copy link

@marinatouceda marinatouceda commented Mar 17, 2016

I was able to make it work in Java:
try {
String jquerySimulator = new String(Files.readAllBytes(Paths.get("/drag_and_drop_helper.js")));

          js.executeScript(jquerySimulator);

          js.executeScript("$('#"+element.getAttribute("id")+"').simulateDragDrop({ dropTarget: '#"+target.getAttribute("id")+"'});");

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
@douglaslise

This comment has been minimized.

Copy link

@douglaslise douglaslise commented Apr 18, 2016

Forked in https://gist.github.com/douglaslise/884692bb54cdf8e76702c01bc18defbd with a fix, making it running in IE11 and also in automated tests using PhantomJS on CircleCI

@vickyzeng

This comment has been minimized.

Copy link

@vickyzeng vickyzeng commented Apr 30, 2016

I tried the file but got the error: java.util.HashMap cannot be cast to java.lang.String. Any idea?
var textToSelect_begin = element.all(by.css('.numberingLevel1')).get(0);
var textToSelect_end = element.all(by.css('.numberingLevel1')).get(1);
browser.executeScript(dragNDrop, textToSelect_begin.getWebElement(), textToSelect_end.getWebElement());

@Nikhil0538

This comment has been minimized.

Copy link

@Nikhil0538 Nikhil0538 commented May 25, 2016

I don't a element where i need to drop, it is a canvas and i need to drop at particular location, how can i achieve this?
droppable location is something "{x:-950, y:50}" like this.
I did try this way but it is navigating to droppable location but it could not drop:
browser.actions().mouseDown(element(by.css('.dragableElement'))).mouseMove({x:-950, y:50}).mouseUp().perform();

Help would be greatly appreciated.

@kymmeh

This comment has been minimized.

Copy link

@kymmeh kymmeh commented Jun 29, 2016

Amazing! Thank you for this script, I finally have a test passing. I adapted it slightly to reflect the exact events I was using in my drag/drop component (I also needed 'dragover').

@sekhar4

This comment has been minimized.

Copy link

@sekhar4 sekhar4 commented Jul 28, 2016

Hi Marina,
Is there a solution for the same when using selenium ? The Drag and Drop action doesn't work in selenium for html5 ( firefox driver ). I wish to code a custom drag and drop action using java for html5; I have tried these 3 methods and none of them work, (a) Trying to click-and-hold then release onto the drop co-ordinates (b) Using iframes ( works only with frames, but I want a general solution ) (c) Saving all the drag and drop helper code in a js file and then calling this in the main java program ( this seems to be the most hyped solution to this problem in stackoverflow and github; doesn't work or maybe I messed up ).
Is there a work around to this ? Using selenium in RedwoodHQ, custom actions coded in java , any help would be appreciated.

@hughes

This comment has been minimized.

Copy link

@hughes hughes commented Oct 21, 2016

cool beans

@elenatosheva

This comment has been minimized.

Copy link

@elenatosheva elenatosheva commented Nov 2, 2016

@pidupuis - did you resolve the duplication of elements?
I have the similar issue with the script above..

@leesaxby

This comment has been minimized.

Copy link

@leesaxby leesaxby commented Nov 3, 2016

@elenatosheva - Not sure what your exact setup is but i was getting the same duplication issue when using https://github.com/marceljuenemann/angular-drag-and-drop-lists.
This was due to the dnd-moved callback not firing so not removing the original element.
Looking at the source code this is due to dropEffect of move not being specified in the dataTransfer object.
Adding dropEffect: 'move' to the object fixed the issue, however this has only been tested on chrome 54 / linux.


        event.dataTransfer = {
            data: {
            },
            setData: function(type, val) {
                this.data[type] = val
            },
            getData: function(type) {
                return this.data[type]
            },
            dropEffect: 'move'
        }

@elenatosheva

This comment has been minimized.

Copy link

@elenatosheva elenatosheva commented Nov 9, 2016

@leesaxby - Thank very much for the reply. I'm using protractor on windows/chrome to test an angular application, which
have html 5 drag and drop implementation.
I'll try your suggestion soon in the coming days, because now we are busy with testing :(
Otherwise I searched everywhere for a similar problem, but to no avail :(
I'll inform you about the results.

Regards,
Elena

@elenatosheva

This comment has been minimized.

Copy link

@elenatosheva elenatosheva commented Dec 1, 2016

Many thanks, @leesaxby , your solution appears to work in my case too.

Now I can continue writing drag&drop tests.

Regards,
Elena

@kkrishan

This comment has been minimized.

Copy link

@kkrishan kkrishan commented Apr 4, 2017

@leesaxby @elenatosheva
While using above gist to automate https://github.com/marceljuenemann/angular-drag-and-drop-lists only click is happening on source div.

Issue
Even after event.dataTransfer.setData(mimeType, angular.toJson(item));

dataTransfer.types is not set or probably not allowed to read in dragstart and drop event

Observation : during manual drag drop dragstart event

dataTransfer {dropEffect: "none", effectAllowed: "move", items: DataTransferItemList, types: Array(1), files: FileList}
    dropEffect:"move"
    effectAllowed:"move"
    files:FileList
    items:DataTransferItemList
    types:Array(0)
    __proto__:DataTransfer

DataTransferItemList {0: DataTransferItem, length: 1}
    length: 0
    __proto__: DataTransferItemList

 DataTransferItem {kind: "string", type: "application/x-dnd"}
    kind: ""type: ""
    __proto__: DataTransferItem

**Observation : when using above script - custom event **

dataTransfer:Object
    data:Object
        application/x-dnd:"[{"id":"706","title":"Ab 2","drag":false,"selected":true}]"
        __proto__:Object
    dropEffect:"move"
    effectAllowed:"move"
   getData:function (type)
    setData:function (type,val)
    files:Object
    items:Object
    types:Array(0)	

I am using

	 var event = new CustomEvent("CustomEvent", {"cancelable": true})
        event.initCustomEvent(type, true, true, null);
        event.dataTransfer = {
            data: {
            },
            setData: function(type,val) {
                this.data[type] = val
            },
            getData: function(type) {
                return this.data[type]
            },
			dropEffect: 'move',
			effectAllowed:'move',
			types: [],
			items:{},
			files:{}
				
			
        }
@kkrishan

This comment has been minimized.

Copy link

@kkrishan kkrishan commented Apr 18, 2017

Solved above issue by changing . Now working fine in chrome for ruby for angular drag drop lists

    setData: function(type,val) {
        this.data[type] = val
        this.types[0] = type
    }
@mike123vn

This comment has been minimized.

Copy link

@mike123vn mike123vn commented May 27, 2017

it does not work with dragular:
http://valor-software.com/ng2-dragula/

     p_Login.openUrl("http://valor-software.com/ng2-dragula/");
            let ele1=element(by.xpath("//example-app//div[contains(text(),'You can move')]"));
            let ele2=element(by.xpath("//example-app//div[contains(text(),'This is the default use case')]/.."));
            browser.driver.executeScript(dragAndDropFn, ele1.getWebElement(), ele2.getWebElement());
@leesaxby

This comment has been minimized.

Copy link

@leesaxby leesaxby commented Jul 27, 2017

As of angular-drag-and-drop-lists version >= 2.0.0 the above work around no longer seems to work as is, due to the directive using a custom MIME type.

Iv'e forked the gist and updated it, allowing drag and drop of html elements in protractor tests.
https://gist.github.com/leesaxby/fabc59c82569a225f8d833b5924e23c6

Basic app to test the fix.
https://github.com/leesaxby/protractor-drag-drop/blob/master/README.md

@jcsmit17

This comment has been minimized.

Copy link

@jcsmit17 jcsmit17 commented Sep 26, 2017

@druska What is the licensing on this code?

@sergsol

This comment has been minimized.

Copy link

@sergsol sergsol commented Aug 20, 2018

Can someone give me an example how to use it in Python script please

@ElliotPalmer-94

This comment has been minimized.

Copy link

@ElliotPalmer-94 ElliotPalmer-94 commented Jun 2, 2019

Thank you, the solution above works fine in Protractor

@sridattasp

This comment has been minimized.

Copy link

@sridattasp sridattasp commented Nov 6, 2019

Amazing! Thank you for this script, I finally have a test passing. I adapted it slightly to reflect the exact events I was using in my drag/drop component (I also needed 'dragover').

Can you share the dragover event changes done in javascript?

@lpnam0201

This comment has been minimized.

Copy link

@lpnam0201 lpnam0201 commented Jan 29, 2020

Brilliant solution. Thanks a lot.
I was simulating dropping files onto Facebook's chat window and adding files: [] property to event.dataTransfer with arbitrary File() objects actually upload these files.

@vitobotta

This comment has been minimized.

Copy link

@vitobotta vitobotta commented Feb 26, 2020

Hi! I am trying to use this with Sortable.js but nothing happens. No errors and the drag and drop doesn't happen. Is this supposed to work with current browsers?

@eudoxyz

This comment has been minimized.

Copy link

@eudoxyz eudoxyz commented Mar 24, 2020

Hi! I am trying to use this with Sortable.js but nothing happens. No errors and the drag and drop doesn't happen. Is this supposed to work with current browsers?

Same here. Doesn't seem to work with Sortable.js.

@hdanske

This comment has been minimized.

Copy link

@hdanske hdanske commented Apr 3, 2020

Great. Works fine with selenium + java

@EugeneShchur

This comment has been minimized.

Copy link

@EugeneShchur EugeneShchur commented May 12, 2020

This is amazing! Works perfectly with Selenium JavascriptExecutor =)

@nehasuman24

This comment has been minimized.

Copy link

@nehasuman24 nehasuman24 commented Aug 12, 2020

Can anybody please help me to know how can we drag and drop by offset using Javascript executor in Python?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.