You are currently viewing When NightWatch Annoyingly Prevents Drag And Drop Testing

When NightWatch Annoyingly Prevents Drag And Drop Testing

Why doesn’t this work?

I went to test a drag and drop feature using NightWatch.  If you are like me, you tried something like the following:

module.exports = {
    "Drag and drop": function(browser) {
        // here's the pseudocode
        browser.moveToElement('#draggable')
        browser.mouseButtonDown(...)
        browser.moveToElement('#drop')
        browser.mouseButtonUp(...)
    }
}

When you run this test, you don’t get the results you expected. No drag and drop happens.

The Fix: html-dnd

The problem is due to Selenium. It doesn’t properly expose HTML5 drag and drop functionality. (I tried to find the main bug report to share, but I couldn’t find it.)

The fix is to use the following npm package: html-dnd. This package enables drag and drop testing in NightWatch by triggering the drag and drop events directly in a web page.

Install

npm install html-dnd --save-dev

Usage

// pull in the dragAndDrop function from the package
const dragAndDrop = require('html-dnd').codeForSelectors
// ...
// Then, in your test, inject the drag and drop script into the page
browser.execute(dragAndDrop, ['#draggable', '#drop'])

Code Example

I hacked a small example drag and drop page for you to test against. Just run the following code to see how your tests work.

I added a couple of browser.pause calls so you can see what’s happening when the code runs. Otherwise, it’s way too fast.

const dragAndDrop = require('html-dnd').codeForSelectors
module.exports = {
    "Drag and drop": function(browser){
        browser.url('http://tutorials.actionqa.com/yt/nw/dndexample.htm')
        browser.pause(2000)
        browser.execute( dragAndDrop, ['#drag1', '#div1'])
        browser.pause(2000)
        browser.end()
    }
}

Remaining Problems

Even though html-dnd let’s you drag-and-drop, other types of testing are still not doable. You can’t “drag and hold”. If you want to verify any behavior of your app while you are in the process of dragging, I haven’t found a way to simulate that.

You can’t slowly drag something, either. You aren’t getting control of the mouse moving the element.

html-dnd simply triggers the web page’s drag and drop events.

How do we solve this? I’m not sure. The real solution needs to be enabled with Selenium and WebDriver. Until then, I’ll keep looking for hacks.