Selenium Drag and Drop Bug Workaround

Have you ever met a widely known Selenium issue that drag and drop gesture doesn’t work for Selenium in some cases? This bug has been around for years and Dmitrii Bormotov will tell you how to resolve it, especially in just a few lines of code if you use Python.

Introduction

Drag and drop is an action when an element is being dragged on top of some other element or location. Selenium has a bug that makes that action impossible and it has been around for years. There is a workaround for such cases, but it wasn’t easy to find it and adapt for some projects. Dmitrii Bormotov, QA Automation Lead at Flow Health, wrote an article about this bug where you can find technical details and steps to fix it for Python [1].

The article is mostly about the origin of the bug and guide to resolve it on your own. Dmitrii told us about a Python package that he developed for Automation QA Engineers that uses Selenium with that programming language. His package is named Selenium Tools (seletools). It helps software testes that use Python + Selenium to bypass drag and drop bug without developing their own workaround if they would follow steps from the article.

Selenium Drag and Drop Bug Workaround

The Interview

Here is Q&A section with Dmitrii Bormotov about the drag androp bug, its workaround and his package seletools for Python.

Question: What causes the issue with drag and drop?

Answer: This gesture consists of 3 actions: click and hold, move mouse to other element/location, release mouse. The issue is all about the last action (release mouse). When Selenium sends a request to the webdriver API to release the mouse, in some cases it keeps holding it.

Q: Can you describe the cases when a webdriver doesn’t respond properly for release action?

A: David Burnes, one of the core Selenium committers, said that it is an issue for web elements that have a draggable attribute [2].

Q: How does your workaround work?

A: It sends JavaScript code via webdriver API to the browser. So the code simulates drag and drop action using JavaScript, not the webdriver method.

Q: So when does your package come in?

A: It comes in when an Automation QA Engineer that uses Python + Selenium stack wants to perform drag and drop for the elements that have issues with native Selenium methods (action chans). So all what engineers need to do is just download the seletools package, import it where a drag and drop needs to be performed and then simply call its method (drag_and_drop).

Q: It means that your package simply performs the workaround that you have mentioned in your article step by step?

A: Exactly, it takes browser instance and 2 web elements found by CSS selectors as arguments. Then, it executes JavaScript code on the browser side, providing it with those 2 web elements. The article shows the principle of how workaround works with Python as an example, but anyone can use the same technique for any other language. I wrapped it up as a Python package so any other Test Automation Engineer that works on Python could use my workaround.

Q: Is there something else that the Selenium Tools package does?

A: Not for now, but maybe it will contain something else in the future. This package is free to use in any way. Contribution is also appreciated.

Q: Why not to include the fix into the Selenium package?

A: The drag and drop bug is a webdriver issue, so all you can do on the Selenium side is to simply perform the same workaround that I did. I spoke with David Burnes (core Selenium committer) about pushing that workaround into Selenium, but he said that it is not a good idea to have any workarounds in Selenium itself. That is why I had to create a separate package to help the test automation community with this problem.

Installing seletools

You can install the seletools package using pip:

> pip install seletools

Next, you need to import the drag_and_drop method from this package where you need it to be performed:

> from seletools.actions import drag_and_drop

And then you simply find draggable and droppable elements using CSS selectors ONLY (JavaScript workaround works only with this type of selectors):

> source = driver.find_element(By.CSS_SELECTOR, "#column-a")
> target = browser.find_element(By.CSS_SELECTOR, "#column-b")

When web elements found, you have to call drag_and_drop method and give it browser instance, draggable and droppable elements as arguments:

> drag_and_drop(driver, source, target)

You can read the details about Selenium Tools package (seletools) here, in Python Package Indexhttps://pypi.org/project/seletools/

Here is an example how to perform drag and drop using this package (gist): https://gist.github.com/bormando/aeb6f8b42cafa5b69c839b64cfa724ba

References

  1. https://medium.com/python-pandemonium/how-to-bypass-selenium-drag-drop-bug-in-python-e33704a15761
  2. https://github.com/w3c/webdriver/issues/1488