Gavi
Gavi

Reputation: 1478

How to test Angular Material Drag and Drop with Protractor

I'm working with an angular 7 application, and I'm using angular material (v7.3.7 at the moment) but I'm not able to test the drag and drop with protractor.

I've tried to download the angular material source code in order to know how to do it, but I've found any e2e test related to the drag and drop.

I'm trying with the following code, and I'm sure that the elements are in the dom, and they are clickable and visible.

browser.actions().dragAndDrop(justCreatedActivity,nextColumn);

I'm sure I'm wrong in some way. Someone can help me?

Thank you

Upvotes: 1

Views: 3700

Answers (4)

corolla
corolla

Reputation: 5656

I got the following working with Angular and Material drag and drop:

private async dragAndDrop(element: WebElement, destination: WebElement) {
    await browser.actions().mouseDown(element).perform();
    await browser.actions().mouseMove(destination).perform();
    await browser.actions().mouseUp(destination).perform();
  }

Also the non-async version (as some are reporting issues with async and browser actions here):

private dragAndDrop(element: WebElement, destination: WebElement) {
    return browser.actions().mouseDown(element).perform()
      .then(() => browser.actions().mouseMove(destination).perform())
      .then(() => browser.actions().mouseUp(destination).perform());
  }

But change anything ever so slightly and it falls apart. Also, destination is found using css selector .cdk-drop-list. Hope it helps someone.

Upvotes: 2

Vaibhav Jagdale
Vaibhav Jagdale

Reputation: 242

Some times drag and drop not work with HTML 5 element using protractor API. An alternative is use j Query or java script function:

Identify source and target element with proper locators and pass to below function.

 async PerformDragAndDrop(source: ElementFinder, target: ElementFinder){

browser.executeScript("function createEvent(typeOfEvent) {\n" +

"var event = document.createEvent('CustomEvent');\n" +

"event.initCustomEvent(typeOfEvent, true, true, null);\n" +

" event.dataTransfer = {\n" +

" data: {},\n" +

" setData: function (key, value) {\n" +

" this.data[key] = value;\n" +

" },\n" +

 " getData: function (key) {\n" +

" return this.data[key];\n" +

 " }\n" +

 " };\n" +

 " return event;\n" +

 "}\n" +

"\n" +

 "function dispatchEvent(element, event, transferData) {\n" +

 " if (transferData !== undefined) {\n" +

 " event.dataTransfer = transferData;\n" +

" }\n" +

" if (element.dispatchEvent) {\n" +

" element.dispatchEvent(event);\n" +

" } else if (element.fireEvent) {\n" +

" element.fireEvent('on' + event.type,event);\n" +

 " }\n" +

"}\n" +

 "\n" +

 "function simulateHTML5DragAndDrop(element, target) {\n"

 " var dragStartEvent =createEvent('dragstart');\n" +

 " dispatchEvent(element, dragStartEvent);\n" +

" var dropEvent = createEvent('drop');\n" +

" dispatchEvent(target, dropEvent,dragStartEvent.dataTransfer);\n" +

" var dragEndEvent = createEvent('dragend'); \n" +

" dispatchEvent(element, dragEndEvent,dropEvent.dataTransfer);\n" +

 "}\n" +

"\n" +

"var source = arguments[0];\n" +

 "var target = arguments[1];\n" +

"simulateHTML5DragAndDrop(source,target);", source, target);

 }

Upvotes: 0

tehbeardedone
tehbeardedone

Reputation: 2858

There is a known issue with drag and drop and Chrome. See the protractor api docs for more info.

Mouse actions do not work on Chrome with the HTML5 Drag and Drop API due to a known Chromedriver issue

I have successfully used html-dnd for more than a year now to drag and drop elements in my tests. It is super easy to setup and works great.

Upvotes: 0

Jordan Stubblefield
Jordan Stubblefield

Reputation: 523

Try adding .perform() to the end of the chain: browser.actions().dragAndDrop(justCreatedActivity,nextColumn).perform();

From the Protractor API:

// Dragging one element to another.
browser.actions().
    mouseDown(element1).
    mouseMove(element2).
    mouseUp().
    perform();

// You can also use the `dragAndDrop` convenience action.
browser.actions().
    dragAndDrop(element1, element2).
    perform();

// Instead of specifying an element as the target, you can specify an offset
// in pixels. This example double-clicks slightly to the right of an element.
browser.actions().
    mouseMove(element).
    mouseMove({x: 50, y: 0}).
    doubleClick().
    perform();

Upvotes: 0

Related Questions