How I implement drag-and-drop in my Cypress tests

Sam E. Lawrence - Mar 26 - - Dev Community

Drag and drop interactions can be one of the more challenging things to get right in Cypress tests. I've used several different methods myself and eventually settled on a pattern which, while dependent on a third-party plugin, has proven reliable and stable for my needs.

My implementation relies on the cypress-real-events plugin (NPM), which you can learn more about in my article "Essential Cypress Plugins I can't live without".

With this plugin installed, I just have a custom command with the following logic:

const dragAndDrop = (dragLocator, dropLocator) => {
  cy.get(dragLocator)
    .realMouseDown({ button: 'left', position: 'center' })
    .realMouseMove(0, 10, { position: 'center' })
    .wait(200);
  cy.get(dropLocator)
    .realMouseMove(0, 0, { position: 'center' })
    .realMouseUp();
};
Enter fullscreen mode Exit fullscreen mode

Because I'm just passing in the dragLocator and dropLocator values to cy.get() commands, I can use IDs, CSS classes, or cy-data locators, just like I would in my normal test logic.

Notice that after issuing the .realMouseDown() command, I move the mouse cursor 10px before moving to the element I want to target for the .realMouseUp() event. That is just to give the UI a little "wiggle" to make sure that the element is picked up by the mouse cursor. Under the hood, I'm honestly not sure why this works, but it has improved reliability for me.

Also note that I then insert a hard 200ms wait. This is normally considered a bad practice, but in this case it's there as an extra guarantee that everything works smoothly. I don't think waiting 1/5th of a second is much of a price to pay for something as complicated as a drag and drop action.

I hope this helps you use drag and drop in your codebase more effectively, or if you have another method that you prefer, let me know down in the comments. Thanks for reading!

. . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player