Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@rcorreia
Last active August 11, 2023 06:41
Show Gist options
  • Star 75 You must be signed in to star a gist
  • Fork 23 You must be signed in to fork a gist
  • Save rcorreia/2362544 to your computer and use it in GitHub Desktop.
Save rcorreia/2362544 to your computer and use it in GitHub Desktop.
drag_and_drop_helper.js
(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);
/*Simulating drop*/
type = 'drop';
var dropEvent = this.createEvent(type, {});
dropEvent.dataTransfer = event.dataTransfer;
this.dispatchEvent($(options.dropTarget)[0], 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: {
},
setData: function(type, val){
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);
@Cst2989
Copy link

Cst2989 commented May 16, 2017

Hello, I used your script to make drag and drop work in codeception using webdriver. For anyone who was having the same problem, this is what I did:

Created a file dnd.js Added in the file the entire jquery library.(my app is in angular2 so it doesn't have jQuery). At the end of the app added This simulatedraganddrop js. And at the end end added jQuery('#style-0').simulateDragDrop({ dropTarget: '#dd-top'});

And in codeception:
$this->executeInSelenium(function(\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) { $script = file_get_contents('/Users/neciudan/Desktop/apps/codeception/tests/_support/Page/dnd.js'); $webdriver->executeScript($script); }); $this->wait(10);

Hope this helps other people who couldn't figure this out in Codeception.

@skducn
Copy link

skducn commented Jun 27, 2018

hello, How to use it in Python.

@anupamdas24
Copy link

Can some one please provide some code in Java for Drag and Drop operation using js helper.

@atulparate
Copy link

Hi All,
I am also facing the same issue. Unable to perform drag and drop operation using protractor on HTML 5 application.

I am using typescript as a language. Please suggest how to use above solution in my case i.e. in typescript. Anyone used above solution if yes then please let me know is that working or not.

Thanks in advance.

@sergsol
Copy link

sergsol commented Aug 16, 2018

If someone has an example how to use it with python, please share

@kelanmomo
Copy link

kelanmomo commented Sep 17, 2018

I tested a simple sample with Python,it works well.Thanks you very much for your share.
I also referred this : http://elementalselenium.com/tips/39-drag-and-drop

# coding = utf-8
from selenium import webdriver
import os
from time import sleep

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('http://the-internet.herokuapp.com/drag_and_drop')

with open(os.path.abspath('drag_and_drop_helper.js'), 'r') as js_file:
    line = js_file.readline()
    script = ''
    while line:
        script += line 
        line = js_file.readline()

driver.execute_script(script + "$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});")
sleep(2)
driver.quit()

@cnparmar
Copy link

I am trying to drag and drop using this JS file in JAVA for IE11 with below code but it is not working.

	// Drag and drop the hidden element
	WebElement targetElement = driver.findElement(By.xpath("//input[@id='User']"));
	WebElement sourceElement = driver.findElement(By.xpath("//input[@id='UserMenu']"));

    //Drag 1st control to layout
    String js_filepath = System.getProperty("user.dir") + "/lib/drag_and_drop_helper.js";
    String java_script="";
    String text;

    BufferedReader input = new BufferedReader(new FileReader(js_filepath));
    StringBuffer buffer = new StringBuffer();

    while ((text = input.readLine()) != null)
        buffer.append(text + " ");
        java_script = buffer.toString();

    input.close();

    java_script = java_script+"$('#"+sourceElement+"').simulate( '#" +targetElement+ "');" ;
    ((JavascriptExecutor)driver).executeScript(java_script);

Can anyone tell me what I am doing wrong here?

@cnparmar
Copy link

Thanks a bunch for the information.

I just want to know how to implement for xpath selectors for source and target?

Thank you!

Did you fine any solution for this?

@cnparmar
Copy link

I tested a simple sample with Python,it works well.Thanks you very much for your share.
I also referred this : http://elementalselenium.com/tips/39-drag-and-drop

# coding = utf-8
from selenium import webdriver
import os
from time import sleep

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('http://the-internet.herokuapp.com/drag_and_drop')

with open(os.path.abspath('drag_and_drop_helper.js'), 'r') as js_file:
    line = js_file.readline()
    script = ''
    while line:
        script += line 
        line = js_file.readline()

driver.execute_script(script + "$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});")
sleep(2)
driver.quit()

What if I don't have IDs for the elements? Is there any other way around?

@as3379
Copy link

as3379 commented Nov 7, 2019

@Poncheqa
Copy link

Poncheqa commented Jan 30, 2020

Thank you a lot!

I worked as follows in java:

  String filePath = "C://drag_and_drop_helper.js";
  StringBuffer buffer = new StringBuffer();

  String line;
  BufferedReader br = new BufferedReader(new FileReader(filePath));
  while((line = br.readLine())!=null)
      buffer.append(line);

  String javaScript = buffer.toString();
  javaScript = javaScript + "$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});";
  ((JavascriptExecutor)driver).executeScript(javaScript);

Remember that JQuery uses CSS-like syntax. Xpath won't work in this case. If you must use Xpath, you will have to convert the Xpath string to CSS before you append it into this JQuery string:

Pattern pattern = Pattern.compile("'(.*?)'");
  Matcher matcherSource = pattern.matcher("//div[@id='column-a']");

  Matcher matcherTarget = pattern.matcher("//div[@id='column-b']");
  String cssSource = "#" + matcherSource.group(1);

  String cssTarget = "#" + matcherTarget.group(1);
  javaScript = javaScript + "$('" + cssSource + "').simulateDragDrop({ dropTarget: '" + cssTarget + "'});";

@dhadawidhawryluk
Copy link

dhadawidhawryluk commented Apr 7, 2020

@Poncheqa I used your code, but it doesn't work in my case. Nothing changed after execute js script. Can you help me?

My code:

    String filePath = "path/drag_and_drop_helper.js";
    StringBuffer buffer = new StringBuffer();
    String line;
    BufferedReader br = new BufferedReader(new FileReader(filePath));
    while((line = br.readLine())!=null)
        buffer.append(line);

    String javaScript = buffer.toString();
    javaScript = javaScript + "$('#id1 > div > ul').simulateDragDrop({ dropTarget: '#id2 > div > div > div.classDiv'});";
    ((JavascriptExecutor)driver).executeScript(javaScript);

@jeansymolanza
Copy link

Does this work with sortable.js?

@mrjane26
Copy link

Please any one can help me through this code..I want to perform drag and drop of multiple images..The area i want to drop is a canvas area. i am able t0 drag and drop to that area but i cant drop into specified location or offset values..images are overlapping on each other in one location only..Below is the code snippet..i hav used both javascript executor and action class..

    WebElement source =oBrowser.findElement(By.xpath("//*[@id='tabImg']/ul/li[1]/img"));
    Thread.sleep(5000);
    WebElement target = oBrowser.findElement(By.xpath("//div[@id='canvas']/div/canvas"));
    Thread.sleep(5000);

    Actions actionBuilder=new Actions(oBrowser);          
    Action drawOnCanvas=actionBuilder
                    .moveToElement(source,223, 184)
                    .clickAndHold(source)
                    .moveToElement(target)
                    .moveToElement(target,326, 277)
                    .release(source)
                    .build();
    drawOnCanvas.perform();
    actionBuilder.dragAndDrop(source, target).build().perform();
    Thread.sleep(5000);

JavascriptExecutor js1=((JavascriptExecutor)oBrowser);
js1.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, target) {\n" +
" var dragStartEvent =createEvent('dragstart');\n" +
" dispatchEvent(element, dragStartEvent);\n" +
" var dropEvent = createEvent('drop');\n" +
" dispatchEvent(target, dropEvent,dragStartEvent.dataTransfer);\n" +
" var dragEndEvent = createEvent('dragend'); \n" +
" dispatchEvent(element, dragEndEvent,dropEvent.dataTransfer);\n" +
"}\n" +
"\n" +
"var source = arguments[0];\n" +
"var target = arguments[1];\n" +
"simulateHTML5DragAndDrop(source,target);", source, target);

Did you find a solution for this? I'm facing the same issue.

@czarteg
Copy link

czarteg commented Jul 30, 2020

Hi, for all of you who search how to drag and drop element found by XPath: https://sudonull.com/post/3102-How-we-tested-drag-drop-in-HTML5 . I did it in C#, Selenium Web Driver and worked perfect. Note that only the first element is searched by Xpath and the second by css.

@Rameshwar-Juptimath
Copy link

Rameshwar-Juptimath commented Aug 3, 2020

Hi All,

I have tried to use this but keep getting this error. Can anyone help what wrong I am doing?

testUtility.dragAndDropElementForHTML5(".e-card-header-title.e-tooltip-text","tr > td:nth-of-type(2)");

Source element CSS: .e-card-header-title.e-tooltip-text
Destination element CSS: tr > td:nth-of-type(2)

public void dragAndDropElementForHTML5(String source, String target)
			throws Exception {
		String js_filepath = System.getProperty("user.dir") + "/src/test/resources/drag_and_drop_helper.js";
		String java_script = "";
		String text;

		BufferedReader input = new BufferedReader(new FileReader(js_filepath));
		StringBuffer buffer = new StringBuffer();

		while ((text = input.readLine()) != null)
			buffer.append(text + " ");
		java_script = buffer.toString();

		input.close();
java_script = java_script + "$('#" + source + "').simulate( '#" + target + "');";
		((JavascriptExecutor) getDriver()).executeScript(java_script);
}

Error:

org.openqa.selenium.JavascriptException: javascript error: Syntax error, unrecognized expression: #.e-card-header-title.e-tooltip-text
  (Session info: chrome=84.0.4147.105)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'My-MacBook-Pro.local', ip: '2401:4900:33b5:7c07:fd71:548f:f938:f7b%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.15.5', java.version: '1.8.0_152'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 84.0.4147.105, chrome: {chromedriverVersion: 83.0.4103.39 (ccbf011cb2d2b..., userDataDir: /var/folders/83/1n1cg9mx25b...}, goog:chromeOptions: {debuggerAddress: localhost:56659}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: MAC, platformName: MAC, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true, webdriver.remote.sessionid: daf3cb9f97205a7bc0d6b0b163a...}
Session ID: daf3cb9f97205a7bc0d6b0b163abbed3

@rookieInTraining
Copy link

@Rameshwar-Juptimath - You're using an incorrect css selector in either your source or target. You'll need to change the code to :

Old :

java_script = java_script + "$('#" + source + "').simulate( '#" + target + "');";

New :

java_script = java_script + "$('" + source + "').simulate( '" + target + "');";

@Rameshwar-Juptimath
Copy link

@rookieInTraining - I tried with the above code but now I'm getting below exception

org.openqa.selenium.JavascriptException: javascript error: missing ) after argument list
  (Session info: chrome=92.0.4515.159)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Rameshwars-MacBook-Pro.local', ip: 'fe80:0:0:0:1cf0:c93e:fa9f:a663%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.15.7', java.version: '1.8.0_152'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 92.0.4515.159, chrome: {chromedriverVersion: 92.0.4515.43 (8c61b7e2989f2..., userDataDir: /var/folders/83/1n1cg9mx25b...}, goog:chromeOptions: {debuggerAddress: localhost:49645}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: MAC, platformName: MAC, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true, webdriver.remote.sessionid: d76aa1032649d438d6c60e71e90...}
Session ID: d76aa1032649d438d6c60e71e908c237

@rakaboy-s
Copy link

What if I don't have IDs for the elements? Is there any other way around?

@cnparmar Did you find a workaround for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment