Drag and Drop Elements with Selenium & Python
This guide shows you how to automate drag-and-drop interactions in a web browser using Selenium with Python. You’ll learn to move elements from one location to another, reorder lists, and interact with HTML5 drag-and-drop interfaces. By the end, you’ll have reusable code snippets and troubleshooting knowledge for common pitfalls.
What You’ll Need
- Python 3.6 or later installed on your system.
- The Selenium package:
pip install selenium - A WebDriver for your browser (e.g., ChromeDriver for Chrome, GeckoDriver for Firefox). Ensure the driver version matches your browser version.
- A basic understanding of Python and HTML DOM (elements, attributes, selectors).
Step-by-Step
- Set up the WebDriver – Import the necessary modules and create a driver instance. For Chrome:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() # or webdriver.Firefox() - Navigate to your target page – Use
driver.get('https://example.com/drag-drop')and wait for the page to load completely (implicit or explicit waits are recommended). - Locate the source element – Find the element you want to drag. Use any Selenium locator (ID, CSS selector, XPath, etc.). For example:
source = driver.find_element(By.ID, "draggable") - Locate the target element – Similarly, find the drop zone or destination element:
target = driver.find_element(By.ID, "droppable") - Create an ActionChains object – This object allows you to chain multiple actions (like click, move, release) together:
actions = ActionChains(driver) - Perform the drag and drop – Use the
drag_and_drop()method, passing the source and target elements:actions.drag_and_drop(source, target).perform() - Verify the action – Check that the drop occurred as expected. For example, assert that a success message appears or that the element’s position changed:
assert "Dropped!" in driver.page_source - Clean up – Close the browser when done:
driver.quit()
If the simple drag_and_drop() doesn’t work (common with HTML5 drag-and-drop), you may need a manual approach using mouse events:
- Manual drag with mouse events – Instead of
drag_and_drop(), useclick_and_hold(),move_to_element(), andrelease():actions.click_and_hold(source).move_to_element(target).release().perform() - For stubborn HTML5 implementations – Sometimes you need to simulate drag events with JavaScript. Use
execute_script()to dispatch dragstart, dragover, and drop events manually. This is more advanced but often necessary for frameworks like React DnD.
Common Mistakes
- Not waiting for the element to be interactable – elements may be hidden or not yet loaded.
- Using the wrong locator – ensure the source and target selectors are unique and correct.
- Assuming
drag_and_drop()works for all sites – many modern sites use HTML5 drag events that Selenium’s native actions don’t trigger correctly. - Forgetting to call
.perform()– without it, the actions are queued but not executed. - Not handling iframes – if the draggable elements are inside an iframe, you must switch to that iframe first.
Tips
- Use explicit waits (WebDriverWait) to ensure the source and target are visible and enabled before interacting.
- If the element is not in the viewport, scroll it into view using
driver.execute_script("arguments[0].scrollIntoView();", element). - For complex drag-and-drop (e.g., sorting a list), consider using the
drag_and_drop_by_offset()method to move by pixel offsets. - When manual mouse events fail, try using
ActionChainswithpause()to give the page time to react. - Keep your WebDriver updated – browser updates often break driver compatibility.
Troubleshooting
Drag and drop does nothing – First, try the manual mouse event approach. If that fails, inspect the page’s JavaScript to see what events it listens for. You may need to trigger those events via JavaScript. For example, for HTML5 drag-and-drop, you can use:
driver.execute_script("""
var src = arguments[0];
var tgt = arguments[1];
var dataTransfer = new DataTransfer();
src.dispatchEvent(new DragEvent('dragstart', {dataTransfer}));
tgt.dispatchEvent(new DragEvent('dragover', {dataTransfer}));
tgt.dispatchEvent(new DragEvent('drop', {dataTransfer}));
src.dispatchEvent(new DragEvent('dragend', {dataTransfer}));
""", source, target)
Element moves but doesn’t drop – The target may not accept drops due to its event handlers. Ensure you are moving to the correct coordinates – sometimes you need to move to the center of the target, not the top-left corner. Use move_to_element_with_offset() if needed.
StaleElementReferenceException – The element reference is no longer valid (page refreshed or DOM changed). Re-locate the element right before the action.
Element not interactable – The element may be covered by another element. Use WebDriverWait and check for visibility, or use JavaScript to force the action.
ActionChains not working in headless mode – Some headless browsers have quirks with drag events. Try running in headed mode for debugging, or use the JavaScript approach.
Frequently Asked Questions
Why does drag_and_drop() not work on some websites?
Many modern sites use HTML5 drag-and-drop API, which Selenium’s native actions do not fully support. The browser’s native drag events are not fired correctly. You need to simulate the events manually via JavaScript or use a library that does that.
Can I drag an element to a specific coordinate?
Yes, use drag_and_drop_by_offset(source, x_offset, y_offset) to move by pixel offsets, or use move_to_element_with_offset() to move to a relative position within the target.
How do I handle drag-and-drop inside an iframe?
First, switch to the iframe using driver.switch_to.frame(iframe_element). Then locate the source and target within that iframe. After the action, switch back to the default content if needed.
Is there a way to make drag-and-drop more reliable?
Yes, using JavaScript to dispatch drag events is often more reliable. Also, adding small pauses between actions (e.g., actions.pause(0.5)) can help the page process the events.
Can I drag and drop files (e.g., upload)?
Dragging files from the OS to the browser is not possible with Selenium. You can simulate file upload by sending keys to an <input type="file"> element. For internal drag-and-drop of file elements, you can use the same techniques but with file data.
What if the element is not draggable via mouse events?
Some elements require keyboard or touch events. You can try using ActionChains with send_keys() to simulate keyboard shortcuts, or use the browser’s touch emulation if supported.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.