How to simulate HTML5 Drag and Drop in Selenium Webdriver?
Yes, HTML5 "drag&drop" is not currently supported by Selenium:
- Issue 3604: HTML5 Drag and Drop with Selenium Webdriver
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()
callingsimulateDragDrop()
function on asource
element passing thetarget
element as adropTarget
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:
HTML5 Drag and Drop using Selenium Webdriver for Ruby
This is still a bug in Selenium, so the JavaScript workaround noted above is a good one.
I built an example HTML drag and drop page and wrote a test to exercise it using the drag_and_drop_helper.js gist Ryan provided. You can see my full write-up here.
Cheers,
Dave H
@TourDeDave
Related Topics
Render HTML to Pdf in Django Site
Python Script as Linux Service/Daemon
How to Split a List into Equally-Sized Chunks
How to Count the Occurrences of a List Item
How to Sort a Dictionary by Key
Why Isn't the 'Global' Keyword Needed to Access a Global Variable
List Comprehension Without [ ] in Python
How to Read a Large CSV File With Pandas
How to Install Pygame on Python Via Pip (Windows 10)
Remove HTML Tags Not on an Allowed List from a Python String
How to Set Your Pythonpath in an Already-Created Virtualenv
Show Matplotlib Plots (And Other Gui) in Ubuntu (Wsl1 & Wsl2)
How to Pass a Variable by Reference
Are Global Variables Thread-Safe in Flask? How to Share Data Between Requests
Understanding Python Super() With _Init_() Methods
Adding a Scrollbar to a Group of Widgets in Tkinter
Tkinter Creating Buttons in For Loop Passing Command Arguments