i've got an issue with drag and drop in my protractor tests (like some other people), but not in general - only within an angular app using HTML5.
For demonstration i wrote a little protractor test-suite using two webpages demonstrating drag-and-drop functionality. The fist page (used in first test-case) demonstrates an implementation of jQueryUI drag and drop functionality in AngualarJS. This one is working just fine. The second page (used in second test-case) uses Angular drag & drop with HTML5. This one does not work within my test.
My next try was to use a helper-function this posting brought me too: https://gist.github.com/druska/624501b7209a74040175 Unfortunaly this didn't not work for me neighter as my 3rd test shows
Can anyone tell me why drag & drop with HTML 5 does not work and what i've got to do to get this running?
Many thanks in advance
Akki
My system:
My testsuite:
describe('Protractor drag-and-drop test', function() {
afterEach(function(){
browser.sleep(5000);
});
it('1st test - jQueryUI drag and drop for AngularJS', function() {
//found here: http://stackoverflow.com/questions/24315571/drag-drop-with-protractor-by-repeater
browser.get('http://codef0rmer.github.io/angular-dragdrop/#!/');
var elem = element(by.css('.ui-draggable'));
var target = element(by.css('.thumbnail'));
browser.sleep(3000);
elem.click();
browser.actions().dragAndDrop(elem, target).perform();
});
it('2nd test - Angular drag & drop with HTML5', function() {
browser.get('http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/simple');
var elem =element.all(by.xpath("/html/body/div[2]/div[2]/div[2]/div[1]/div[1]/div[2]/div/div[2]/ul/li[1]")).first();
var target = $('ul[dnd-list=list]');
expect(elem.getText()).toEqual("Item B1"); //Item that should be dragged and dropped
expect(target.getText()).toContain("Item A1"); //element sorrounding "ItemA1", "Item A2", "ItemA3"
elem.click();
browser.actions().dragAndDrop(elem, target).perform();
});
it('3rd test - Angular drag & drop with HTML5 with native_js_drag_and_drop_helper', function() {
browser.get('http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/simple');
var dragAndDropFn = require('./native_js_drag_and_drop_helper.js');
var elem =element.all(by.xpath("/html/body/div[2]/div[2]/div[2]/div[1]/div[1]/div[2]/div/div[2]/ul/li[1]")).first();
var target = $('ul[dnd-list=list]');
expect(elem.getText()).toEqual("Item B1"); //Item that should be dragged and dropped
expect(target.getText()).toContain("Item A1"); //element sorrounding "ItemA1", "Item A2", "ItemA3"
elem.click();
browser.executeScript(dragAndDropFn, target.getWebElement(), elem.getWebElement());
});
xit(' 4th test - Test of native drag and drop helper ', function() {
// test found on https://gist.github.com/druska/624501b7209a74040175 failing with "Angular could not be found on the page http://html5demos.com/drag : retries looking for angular exceeded"
var dragAndDropFn = require('./native_js_drag_and_drop_helper.js');
browser.get("http://html5demos.com/drag");
var field = element.all(by.className('drag-handle')).get(0);
var src = element.all(by.className('box-list-compact-hover')).get(0);
browser.executeScript(dragAndDropFn, field.getWebElement(), src.getWebElement());
}, 120000);
});
My configuration file:
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['spec.js'],
capabilities: {
//browserName: 'internet explorer'
browserName: 'chrome'
//browserName: 'firefox'
},
};
The native_js_drag_and_drop_helper:
module.exports = function simulateDragDrop(sourceNode, destinationNode) {
var EVENT_TYPES = {
DRAG_END: 'dragend',
DRAG_START: 'dragstart',
DROP: 'drop'
}
function createCustomEvent(type) {
var event = new CustomEvent("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
}
function dispatchEvent(node, type, event) {
if (node.dispatchEvent) {
return node.dispatchEvent(event)
}
if (node.fireEvent) {
return node.fireEvent("on" + type, event)
}
}
var event = createCustomEvent(EVENT_TYPES.DRAG_START)
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_START, event)
var dropEvent = createCustomEvent(EVENT_TYPES.DROP)
dropEvent.dataTransfer = event.dataTransfer
dispatchEvent(destinationNode, EVENT_TYPES.DROP, dropEvent)
var dragEndEvent = createCustomEvent(EVENT_TYPES.DRAG_END)
dragEndEvent.dataTransfer = event.dataTransfer
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_END, dragEndEvent)
}
I had the same issue with various dnd simulate libaries not seeming to work with angular-drag-and-drop-lists.
In the end I forked html-dnd simpling just adding a dragover event, something angular-drag-and-drop-lists requires as it calculates the index of the element being dropped upon via the dragover event. It also sticks in a temp li element which the code uses as the actual drop point before removing it. This is what the user sees as the shifting list points on the screen.
The fork is at forked html-dnd. I include it via a git pull in the dependancies in my package.json file
"html-dnd": "git://github.com/PloughingAByteField/html-dnd.git"
For usage in protractor
// at the top of the spec
var dragAndDrop = require('html-dnd').code;
<snip>
it('should dragover and drop', function() {
var draggable = browser.findElement(by.id('id1'));
var droppable = browser.findElement(by.id('id2'));
browser.driver.executeScript(dragAndDrop, draggable, droppable);
);
Update: The html-dnd project has merged in the dragover event so you can use that instead of my not maintained fork.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With