13

I am using Python 2.7 and Selenium 2.44.

I want to automate drag and drop action in Selenium WD but according to other related posts Actions in HTML5 are not supported by Selenium yet. Is there any way to simulate drag and drop in Python?

Here is the code I tried:

driver = webdriver.Firefox()
driver.get("http://html5demos.com/drag")
target = driver.find_element_by_id("one")
source = driver.find_element_by_id("bin")
actionChains = ActionChains(driver)
actionChains.drag_and_drop(target, source).perform()

and it did not work.

1

2 Answers 2

28

Yes, HTML5 "drag&drop" is not currently supported by Selenium:

One of the suggested workarounds is to simulate HTML5 drag and drop via JavaScript:

  • download drag_and_drop_helper.js
  • execute the script via execute_script() calling simulateDragDrop() function on a source element passing the target element as a dropTarget

Sample code:

with open("drag_and_drop_helper.js") as f:
    js = f.read()

driver.execute_script(js + "$('#one').simulateDragDrop({ dropTarget: '#bin'});")

The problem is that it won't work in your case "as is" since it requires jQuery.


Now we need to figure out how to dynamically load jQuery. Thankfully, there is a solution.

Complete working example in Python:

from selenium import webdriver

jquery_url = "http://code.jquery.com/jquery-1.11.2.min.js"

driver = webdriver.Firefox()
driver.get("http://html5demos.com/drag")
driver.set_script_timeout(30)

# load jQuery helper
with open("jquery_load_helper.js") as f:
    load_jquery_js = f.read()

# load drag and drop helper
with open("drag_and_drop_helper.js") as f:
    drag_and_drop_js = f.read()

# load jQuery
driver.execute_async_script(load_jquery_js, jquery_url)

# perform drag&drop
driver.execute_script(drag_and_drop_js + "$('#one').simulateDragDrop({ dropTarget: '#bin'});")

where jquery_load_helper.js contains:

/** dynamically load jQuery */
(function(jqueryUrl, callback) {
    if (typeof jqueryUrl != 'string') {
        jqueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
    }
    if (typeof jQuery == 'undefined') {
        var script = document.createElement('script');
        var head = document.getElementsByTagName('head')[0];
        var done = false;
        script.onload = script.onreadystatechange = (function() {
            if (!done && (!this.readyState || this.readyState == 'loaded'
                    || this.readyState == 'complete')) {
                done = true;
                script.onload = script.onreadystatechange = null;
                head.removeChild(script);
                callback();
            }
        });
        script.src = jqueryUrl;
        head.appendChild(script);
    }
    else {
        callback();
    }
})(arguments[0], arguments[arguments.length - 1]);

Before/after result:

Sign up to request clarification or add additional context in comments.

8 Comments

Your example is still working. I have managed to translate it and use it in C#. Thank you for your help!
I converted this helper to native JS, removing the need for injecting jQuery: gist.github.com/druska/624501b7209a74040175
@DudumanBogdanVlad could you please share the C# version or any link?
@rahoolm I helped Raluca with this. She created a blog post. Here is the link ralucasuditu-softwaretesting.blogspot.ro/2015/08/…
Thanks @DudumanBogdanVlad, I am looking into it. But in my case I want to drag and drop to XY. Say drag element one in x direction by 20 px. Please suggest.
|
2

Found working example in python (without using jquery_load_helper.js) - https://gist.github.com/rcorreia/2362544#gistcomment-2708388

Credits: Kelanmomo

As alecxe mentioned: download drag_and_drop_helper.js

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

2 Comments

This seems to work perfectly on this page, the-internet.herokuapp.com/drag_and_drop. But a similar solution does not work on this page, crossbrowsertesting.github.io/drag-and-drop.html, using something like driver.execute_script(script +"$('#draggable').simulateDragDrop({ dropTarget: '#droppable'});"). I am trying to test pages like this, and cannot seem to get the drag/drop to happen.
Java version is in below commit github.com/vikramvi/Selenium-Java/commit/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.