Last active
March 9, 2023 14:48
-
-
Save florentbr/60ef7cb8d9b1ae690cafc82aad52da73 to your computer and use it in GitHub Desktop.
Selenium - HTML5 drag and drop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from selenium import webdriver | |
import time | |
# JavaScript: HTML5 Drag and drop script | |
# param1 (WebElement): Source element to drag | |
# param2 (WebElement): Optional - target element for the drop | |
# param3 (int): Optional - Drop offset x relative to the target if any or source element | |
# param4 (int): Optional - Drop offset y relative to the target if any or source element | |
# param4 (int): Optional - Delay in milliseconds (default = 1ms) for dragging and dropping | |
# param5 (string): Optional - Key pressed (alt or ctrl or shilf) | |
JS_DRAG_AND_DROP = "var t=arguments,e=t[0],n=t[1],i=t[2]||0,o=t[3]||0,r=t[4]||1,a=t[5]||'',s='alt'===a||'\ue00a'===a,l='ctrl'===a||'\ue009'===a,c='shift'===a||'\ue008'===a,u=e.ownerDocument,f=e.getBoundingClientRect(),g=n?n.getBoundingClientRect():f,p=f.left+f.width/2,d=f.top+f.height/2,h=g.left+(i||g.width/2),m=g.top+(o||g.height/2),v=u.elementFromPoint(p,d),y=u.elementFromPoint(h,m);if(!v||!y){var E=new Error('source or target element is not interactable');throw E.code=15,E}var _={constructor:DataTransfer,effectAllowed:null,dropEffect:null,types:[],files:Object.setPrototypeOf([],null),_items:Object.setPrototypeOf([],{add:function(t,e){this[this.length]={_data:''+t,kind:'string',type:e,getAsFile:function(){},getAsString:function(t){t(this._data)}},_.types.push(e)},remove:function(t){Array.prototype.splice.call(this,65535&t,1),_.types.splice(65535&t,1)},clear:function(t,e){this.length=0,_.types.length=0}}),setData:function(t,e){this.clearData(t),this._items.add(e,t)},getData:function(t){for(var e=this._items.length;e--&&this._items[e].type!==t;);return e>=0?this._items[e]._data:null},clearData:function(t){for(var e=this._items.length;e--&&this._items[e].type!==t;);this._items.remove(e)},setDragImage:function(t){}};function w(t,e,n,i){for(var o=0;o<e.length;++o){var r=u.createEvent('MouseEvent');r.initMouseEvent(e[o],!0,!0,u.defaultView,0,0,0,p,d,l,s,c,!1,0,null),t.dispatchEvent(r)}i&&setTimeout(i,n)}function D(t,e,n,i){var o=u.createEvent('DragEvent');o.initMouseEvent(e,!0,!0,u.defaultView,0,0,0,p,d,l,s,c,!1,0,null),Object.setPrototypeOf(o,null),o.dataTransfer=_,Object.setPrototypeOf(o,DragEvent.prototype),t.dispatchEvent(o),i&&setTimeout(i,n)}'items'in DataTransfer.prototype&&(_.items=_._items),w(v,['pointerdown','mousedown'],1,function(){for(var t=v;t&&!t.draggable;)t=t.parentElement;if(t&&t.contains(v)){var e=y.getBoundingClientRect();D(v,'dragstart',r,function(){var t=y.getBoundingClientRect();p=t.left+h-e.left,d=t.top+m-e.top,D(y,'dragenter',1,function(){D(y,'dragover',r,function(){D(u.elementFromPoint(p,d),'drop',1,function(){D(v,'dragend',1,function(){w(u.elementFromPoint(p,d),['mouseup','pointerup'])})})})})})}})" | |
def drag_and_drop(driver, source, target=None, offsetX=0, offsetY=0, delay=25, key=None) : | |
driver.execute_script(JS_DRAG_AND_DROP, source, target, offsetX, offsetY, delay, key) | |
time.sleep(delay * 2 / 1000) | |
driver = webdriver.Chrome() | |
driver.get("http://react-dnd.github.io/react-dnd/examples-dustbin-copy-or-move.html") | |
# drag and drop Glass | |
source = driver.find_element_by_xpath("//*[not(./*)][normalize-space()='Glass']") | |
target = driver.find_element_by_xpath("//*[text()[contains(.,'Works with any drop effect')]]") | |
drag_and_drop(driver, source, target) | |
# drag and drop Banana with alt key pressed | |
source = driver.find_element_by_xpath("//*[not(./*)][normalize-space()='Banana']") | |
target = driver.find_element_by_xpath("//*[text()[contains(.,'Works with copy drop effect')]]") | |
drag_and_drop(driver, source, target, key='alt') | |
# drag and drop Paper by offset | |
source = driver.find_element_by_xpath("//*[not(./*)][normalize-space()='Paper']") | |
drag_and_drop(driver, source, offsetX=250, offsetY=-100) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var args = arguments, | |
elemSrc = args[0], | |
elemDst = args[1], | |
offsetX = args[2] || 0, | |
offsetY = args[3] || 0, | |
delay = args[4] || 1, | |
key = args[5] || '', | |
alt = key === 'alt' || key === '\uE00A', | |
ctrl = key === 'ctrl' || key === '\uE009', | |
shift = key === 'shift' || key === '\uE008', | |
doc = elemSrc.ownerDocument, | |
box1 = elemSrc.getBoundingClientRect(), | |
box2 = elemDst ? elemDst.getBoundingClientRect() : box1, | |
x = box1.left + (box1.width / 2), | |
y = box1.top + (box1.height / 2), | |
x2 = box2.left + (offsetX ? offsetX : box2.width / 2), | |
y2 = box2.top + (offsetY ? offsetY : box2.height / 2), | |
source = doc.elementFromPoint(x, y), | |
target = doc.elementFromPoint(x2, y2); | |
if (!source || !target) { | |
var ex = new Error('source or target element is not interactable'); | |
ex.code = 15; | |
throw ex; | |
} | |
var dataTransfer = { | |
constructor : DataTransfer, | |
effectAllowed : null, | |
dropEffect : null, | |
types : [ ], | |
files : Object.setPrototypeOf([], null), | |
_items : Object.setPrototypeOf([], { | |
add : function add(data, type) { | |
this[this.length] = { | |
_data : '' + data, | |
kind : 'string', | |
type : type, | |
getAsFile : function () { }, | |
getAsString : function (callback) { callback(this._data) } | |
}; | |
dataTransfer.types.push(type); | |
}, | |
remove : function remove(i) { | |
Array.prototype.splice.call(this, i & 65535, 1); | |
dataTransfer.types.splice(i & 65535, 1); | |
}, | |
clear : function clear(data, type) { | |
this.length = 0; | |
dataTransfer.types.length = 0; | |
} | |
}), | |
setData : function setData(format, data) { | |
this.clearData(format); | |
this._items.add(data, format); | |
}, | |
getData : function getData(format) { | |
for (var i = this._items.length; i-- && this._items[i].type !== format;); | |
return i >= 0 ? this._items[i]._data : null; | |
}, | |
clearData : function clearData(format) { | |
for (var i = this._items.length; i-- && this._items[i].type !== format;); | |
this._items.remove(i); | |
}, | |
setDragImage : function setDragImage(format) { } | |
}; | |
if ('items' in DataTransfer.prototype) | |
dataTransfer.items = dataTransfer._items; | |
emit_mouse(source, [ 'pointerdown', 'mousedown' ], 1, function () { | |
var elem = source; | |
while (elem && !elem.draggable) | |
elem = elem.parentElement; | |
if (!elem || !elem.contains(source)) | |
return; | |
var box2 = target.getBoundingClientRect(); | |
emit_drag(source, 'dragstart', delay, function () { | |
var box3 = target.getBoundingClientRect(); | |
x = box3.left + x2 - box2.left; | |
y = box3.top + y2 - box2.top; | |
emit_drag(target, 'dragenter', 1, function () { | |
emit_drag(target, 'dragover', delay, function () { | |
emit_drag(doc.elementFromPoint(x, y), 'drop', 1, function () { | |
emit_drag(source, 'dragend', 1, function () { | |
emit_mouse(doc.elementFromPoint(x, y), [ 'mouseup', 'pointerup' ]); | |
})})})})})}); | |
function emit_mouse(element, types, delay, callback) { | |
for (var i=0; i < types.length; ++i) { | |
var event = doc.createEvent('MouseEvent'); | |
event.initMouseEvent(types[i], true, true, doc.defaultView, 0, 0, 0, x, y, ctrl, alt, shift, false, 0, null); | |
element.dispatchEvent(event); | |
} | |
callback && setTimeout(callback, delay); | |
} | |
function emit_drag(element, type, delay, callback) { | |
var event = doc.createEvent('DragEvent'); | |
event.initMouseEvent(type, true, true, doc.defaultView, 0, 0, 0, x, y, ctrl, alt, shift, false, 0, null); | |
Object.setPrototypeOf(event, null); | |
event.dataTransfer = dataTransfer; | |
Object.setPrototypeOf(event, DragEvent.prototype); | |
element.dispatchEvent(event); | |
callback && setTimeout(callback, delay); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var t=arguments,e=t[0],n=t[1],i=t[2]||0,o=t[3]||0,r=t[4]||1,a=t[5]||'',s='alt'===a||'\ue00a'===a,l='ctrl'===a||'\ue009'===a,c='shift'===a||'\ue008'===a,u=e.ownerDocument,f=e.getBoundingClientRect(),g=n?n.getBoundingClientRect():f,p=f.left+f.width/2,d=f.top+f.height/2,h=g.left+(i||g.width/2),m=g.top+(o||g.height/2),v=u.elementFromPoint(p,d),y=u.elementFromPoint(h,m);if(!v||!y){var E=new Error('source or target element is not interactable');throw E.code=15,E}var _={constructor:DataTransfer,effectAllowed:null,dropEffect:null,types:[],files:Object.setPrototypeOf([],null),_items:Object.setPrototypeOf([],{add:function(t,e){this[this.length]={_data:''+t,kind:'string',type:e,getAsFile:function(){},getAsString:function(t){t(this._data)}},_.types.push(e)},remove:function(t){Array.prototype.splice.call(this,65535&t,1),_.types.splice(65535&t,1)},clear:function(t,e){this.length=0,_.types.length=0}}),setData:function(t,e){this.clearData(t),this._items.add(e,t)},getData:function(t){for(var e=this._items.length;e--&&this._items[e].type!==t;);return e>=0?this._items[e]._data:null},clearData:function(t){for(var e=this._items.length;e--&&this._items[e].type!==t;);this._items.remove(e)},setDragImage:function(t){}};function w(t,e,n,i){for(var o=0;o<e.length;++o){var r=u.createEvent('MouseEvent');r.initMouseEvent(e[o],!0,!0,u.defaultView,0,0,0,p,d,l,s,c,!1,0,null),t.dispatchEvent(r)}i&&setTimeout(i,n)}function D(t,e,n,i){var o=u.createEvent('DragEvent');o.initMouseEvent(e,!0,!0,u.defaultView,0,0,0,p,d,l,s,c,!1,0,null),Object.setPrototypeOf(o,null),o.dataTransfer=_,Object.setPrototypeOf(o,DragEvent.prototype),t.dispatchEvent(o),i&&setTimeout(i,n)}'items'in DataTransfer.prototype&&(_.items=_._items),w(v,['pointerdown','mousedown'],1,function(){for(var t=v;t&&!t.draggable;)t=t.parentElement;if(t&&t.contains(v)){var e=y.getBoundingClientRect();D(v,'dragstart',r,function(){var t=y.getBoundingClientRect();p=t.left+h-e.left,d=t.top+m-e.top,D(y,'dragenter',1,function(){D(y,'dragover',r,function(){D(u.elementFromPoint(p,d),'drop',1,function(){D(v,'dragend',1,function(){w(u.elementFromPoint(p,d),['mouseup','pointerup'])})})})})})}}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Were anyone able to drag and drop in this site with above piece od code?
https://app.appsmith.com/