Recently, I was confronted with the necessity to perform drag and drop actions for a html5 element in a selenium webdriver test written in c #.
That is why In this article I will show you how we can simulate this action by inserting javascript code.
'Simple' approach
Normally, a drag and drop is performed in C# --> selenium webdriver by using Actions class, like this:
or
but for html5 elements, this may not work.
'Javascript' approach
That is why, an alternative is to simulate the drag and drop by inserting javascript code.
Copy this file, call it for example 'drag.js' somewhere on your your computer. The content of the file is:
(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);
Create a function like below:
Use this function like this:
where
- '.timelineList:nth-of-type(3)>div > div' is the CSS locator of the element from which the drag will be performed. Replace it with your css selector.
- '.bread-crumbs.bread-crumbs-home.btn.btn-default' is the CSS locator of the element to which the drop will be performed. Replace it with your css selector.
That's it! Don't forget to use CSS locators. It may not work with xpath, class name, etc.
Many thanks to Bogdan whose contribution in achieving this functionality was important.
Happy testing and... make it green, becomes a dream :).
For every post I'll recommend something to read. The link for today is: Selenium Design Patterns and Best Practices