The solution I found to this is problem is to execute the function in JavaScript. It's not a perfect solution, but it works for us.
The script does not work for IE9, and it has caused some assertion errors in Chrome/Firefox. Which is weird but completely besides the point; It works perfectly in IE10 and IE11. Worst case scenario I have to use this solution for IE10/11 and the other in IE9/Firefox/Chrome.
My drag and drop method now looks like this:
dragAndDrop: function (elem, x, y, id, className) {
var i = 0,
offsetX,
offsetY,
pos, offsetPos,
size;
this.sleep(2000);
offsetPos = this.getLocationInView(elem);
size = this.getSize(elem);
pageX = offsetPos.x + ~~(size.width / 2);
pageY = offsetPos.y + ~~(size.height / 2);
// No linebreaks
this.execute('var mousedown=document.createEvent("MouseEvent"),mouseup=document.createEvent("MouseEvent"),elem=document.getElementById("' + id + '"),result=[],elems=elem.getElementsByTagName("*"),k=0,i,interval;for(i in elems){if((" "+elems[i].className+" ").indexOf(" ' + className + ' ")>-1){result.push(elems[i]);}}mousedown.initMouseEvent("mousedown",true,true,window,0,0,0,' + pageX + ',' + pageY +',0,0,0,0,0,null);result[0].dispatchEvent(mousedown);interval=setInterval(function(){k++;iter(k);if(k===' + x + '+1){clearInterval(interval);mouseup.initMouseEvent("mouseup",true,true,window,0,' + pageX + '+k,' + pageY +',' + pageX + '+k,' + pageY +',0,0,0,0,0,null);result[0].dispatchEvent(mouseup);}},100);function iter(y){var mousemove=document.createEvent("MouseEvent");mousemove.initMouseEvent("mousemove",true,true,window,0,0,0,' + pageX + '+y,' + pageY +',0,0,0,0,0,null);result[0].dispatchEvent(mousemove);}');
// Give the script time to execute and take a nap
this.sleep(x*100+3000);
}
There can be no linebreaks in the executed JS. Cleaned up it looks like this:
var mousedown = document.createEvent("MouseEvent"),
mouseup = document.createEvent("MouseEvent"),
elem = document.getElementById(id),
result = [],
elems = elem.getElementsByTagName("*"),
k = 0,
i, interval;
for(i in elems){
if((" " + elems[i].className + " ").indexOf(" " + className + " ") > -1){
result.push(elems[i]);
}
}
mousedown.initMouseEvent("mousedown", true, true, window, 0, 0, 0, clientX, clientY, 0, 0, 0, 0, 0, null);
result[0].dispatchEvent(mousedown);
interval = setInterval(function(){
k++;
iter(k);
if(k === distance + 1){
clearInterval(interval);
mouseup.initMouseEvent("mouseup", true, true, window, 0, screenX + k, screenY, clientX + k, clientY, 0, 0, 0, 0, 0, null);
result[0].dispatchEvent(mouseup);
}
}, 100);
function iter(y){
var mousemove = document.createEvent("MouseEvent");
mousemove.initMouseEvent("mousemove", true, true, window, 0, 0, 0, clientX + y, clientY, 0, 0, 0, 0, 0, null);
result[0].dispatchEvent(mousemove);
}
What the parameters for initMouseEvent()
means you can check https://developer.mozilla.org/en-US/docs/Web/API/event.initMouseEvent
For mouseup
I had to set screenX/Y
, and I've made the assumption that the client is always the full size of the screen. The code contains a lot of assumptions of what environment it's run in, but it shouldn't be too hard to modify it for yours.
It was @JimEvans comment that ultimately led me to the answer.