Creating custom Drag & Drop in WebDriver

In case you need custom drag & drop (or similar actions) performed you should implement a custom helper following commands from webdriverio api.

There are two versions of API:

So for compatibility, you should implement Drag & Drop for both using different methods.

Here is my sample function to drag by a specific offset:

  // inside a helper
  async dragToPoint(el, x, y) {
    const browser = this.helpers.WebDriver.browser;
    await this.helpers.WebDriver.moveCursorTo(el);

    if (browser.isW3C) {
      // W3C version
      return browser.performActions([
        {"type": "pointerDown", "button": 0},
        {"type": "pointerMove", "origin": "pointer", "duration": 1000, x, y },
        {"type": "pointerUp", "button": 0}
    // JSON Wire version
    await browser.buttonDown(0);
    await browser.moveToElement(null, x, y);
    await browser.buttonUp(0);

Hey, I tried to run this code on the sandbox site like this:


Scenario('Probe Drug&Drop', async  (I) => {
    await I.dragToPoint('#todrag > span:nth-child(2)', 578, 460);

But I am having the next error:

  1) Concept
   Probe Drug&Drop:
 invalid argument

from invalid argument: ‘type’ must be one of the strings ‘key’, ‘pointer’ or ‘none’
(Session info: chrome=81.0.4044.138)

Am I doing it wrong?

I checked the issue and discovered that the actions object should contain other required attribues, as:

      type: 'pointer',
      id: 'finger1',
      parameters: { pointerType: 'mouse' },
      actions: [
        { type: 'pointerMove', duration: 0, x: location.x, y: location.y },
        { type: 'pointerDown', button: 0 },
        { type: 'pointerMove', duration: 0, x: location.x + x, y: location.y + y },
        { type: 'pointerUp', button: 0 },

However, there is also a known issue, when the ‘pointerMove’ stays appended to the origin (real) mouse cursor and that is why cannot be performed on some OS/browsers, which I faced later myself.