Protractor Drag And Drop

2019-09-09 23:04发布

问题:

I have a list of elements so i want to write a function to drag those elements into a container that builds up an object. At the moment in my protractor tests I have found the element. The element is present and is displayed. The only place I'm running into problems is when I try to translate or drag and drop its position on the screen. At the moment i'm using

browser.actions().dragAndDrop(element1.getWebElement(), { x: -500, y: 20 }).perform();

In order to try drag it -500px to the left and 20px down i've also tried the following

browser.actions()
    .mouseDown(element1, {x:10, y:10}) //this show the hovered tool tip
    .mouseMove(element1, {x:11, y:11}) //do this to make it "grab" the element
    .mouseMove(element2, {x:50, y:50}) //translate its position into the container
    .mouseUp()
    .preform();
browser.sleep(3000)//allow time for it to drag and the animation to complete.

I'm not sure if i'm using the move elements wrong or if I have the wrong elements so any help would be appreciated.

Thanks.

回答1:

I also go through many to these solutions but none of those work for me. the solution that work for me is to import the new js file. there is my js file store this file as dragdrop_helper.js

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)
}

and use this code in your protractor file to drag and drop your element.

 var dragAndDropFn = require("../DraodropHelper/dragdrop_helper.js"); //this is your js file address
    var source = element(by.css('li[draggable="true"]'));
    var target = element(by.css('ul[class="dropElement"]'));
    browser.executeScript(dragAndDropFn, source.getWebElement(), target.getWebElement());

kindly change the selector as specific to your app. I hope that would help you



回答2:

Im new to protractor and I have been on every topic on this and saw to much of an bad sugestions and guides. So i figured out for my self how to do it. First of all there is no such a thing as a .dragAndDrop method in Protractor. You dont need x and y. This is my code:

 it('drag&drop', function() {
    var elem = element.all(by.css('.as-sortable-item-handle')).get(1);
    //select element as you find fit, you dont have to do it like me

    var target = element(by.css('[id="column1"]'));

   browser.driver.actions()
    .mouseDown(elem)
    .mouseMove(elem)
    .mouseMove(target)
    .mouseUp(target)
    .perform();
    browser.sleep(3000);
}); 


回答3:

The default drag and drop function did not work for me. So i have used this Javascript for drag and drop in Chrome using protractor

function doDnd(dragElement, dropElement) {
    const CUSTOM_JS_SCRIPT = 'function e(e,t,n,i){var r=a.createEvent("DragEvent");r.initMouseEvent(t,!0,!0,o,0,0,0,c,g,!1,!1,!1,!1,0,null),Object.defineProperty(r,"dataTransfer",{get:function(){return d}}),e.dispatchEvent(r),o.setTimeout(i,n)}var t=arguments[0],n=arguments[1],i=arguments[2]||0,r=arguments[3]||0;if(!t.draggable)throw new Error("Source element is not draggable.");var a=t.ownerDocument,o=a.defaultView,l=t.getBoundingClientRect(),u=n?n.getBoundingClientRect():l,c=l.left+(l.width>>1),g=l.top+(l.height>>1),s=u.left+(u.width>>1)+i,f=u.top+(u.height>>1)+r,d=Object.create(Object.prototype,{_items:{value:{}},effectAllowed:{value:"all",writable:!0},dropEffect:{value:"move",writable:!0},files:{get:function(){return this._items.Files}},types:{get:function(){return Object.keys(this._items)}},setData:{value:function(e,t){this._items[e]=t}},getData:{value:function(e){return this._items[e]}},clearData:{value:function(e){delete this._items[e]}},setDragImage:{value:function(e){}}});if(n=a.elementFromPoint(s,f),!n)throw new Error("The target element is not interactable and need to be scrolled into the view.");u=n.getBoundingClientRect(),e(t,"dragstart",101,function(){var i=n.getBoundingClientRect();c=i.left+s-u.left,g=i.top+f-u.top,e(n,"dragenter",1,function(){e(n,"dragover",101,function(){n=a.elementFromPoint(c,g),e(n,"drop",1,function(){e(t,"dragend",1,callback)})})})})';

    browser.executeScript(CUSTOM_JS_SCRIPT, dragElement.getWebElement(), dropElement.getWebElement());
}