Use Selenium Python’s ActionChains: locate the source and destination elements, call drag_and_drop(source, target), then execute the queued actions with .perform(). For a destination defined by a relative position rather than an element, use drag_and_drop_by_offset().
Drag an element onto a target element
With a configured WebDriver session and locators that match the page, the basic pattern is:
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
source = driver.find_element(By.ID, "source")
target = driver.find_element(By.ID, "target")
ActionChains(driver).drag_and_drop(source, target).perform()
Replace the example IDs with stable locators from your page. Selenium documents this gesture as holding the left mouse button on the source, moving to the target, and releasing. Selenium Python ActionChains API
What the call does
ActionChains queues input actions. The call to perform() sends them to the browser in order; constructing the chain without performing it does not execute the drag. The API documentation describes drag_and_drop(source, target) as a left-button drag between two WebElements. Selenium Actions API
#1 Best Overall
Drag by a relative offset
When the endpoint is best described as a displacement from the source, use integer X and Y offsets instead of locating a target element:
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
source = driver.find_element(By.ID, "source")
ActionChains(driver).drag_and_drop_by_offset(source, 120, 40).perform()
The offsets are the intended horizontal and vertical displacement. Choose values for the page layout and the drop area you need; this method does not identify a semantic destination element for you. Selenium Python ActionChains API
Rank #2
Verify the application accepted the drag
A completed Selenium input sequence proves that the browser received the actions, not that the page’s application logic accepted the drop. After the drag, assert an outcome that matters to the test, such as the item’s new parent, its updated position in a list, or a confirmation message. The expected result and the right wait condition depend on the page under test; Selenium’s general Actions documentation does not define a universal success signal for custom drag handlers.
Timing and interaction details
The current Python API documentation identifies Selenium version 4.50.0 and specifies a default pointer movement duration of 250 milliseconds for ActionChains; the duration can be overridden when constructing the chain. That value is an API default, not a guarantee that a particular page’s drag implementation will respond successfully. Selenium Python ActionChains API
Rank #3
Troubleshoot a drag that does not work
- Nothing happens: Confirm that the source and destination locators identify the intended elements and that the chain ends with
.perform(). - The chain runs but the page is unchanged: Check the page state with an application-level assertion. A dispatched mouse gesture is not proof that a custom handler accepted it.
- The drop lands in the wrong place: Prefer
drag_and_drop(source, target)when a destination element can be located. If using offsets, reassess the intended displacement and target region. - A custom drag interaction still fails: Investigate how that page implements dragging and what region accepts the drop. The general Selenium documentation does not establish a browser-by-browser compatibility matrix or a universally reliable workaround for custom JavaScript or HTML5 drag behavior. Do not assume that injecting JavaScript events will fix it.
Or skip the browser setup
If you need a screenshot of the page rather than an automated drag interaction, ScreenshotNeo returns a screenshot or PDF from one API request. For example, this cURL request saves a WebP screenshot of a page:
Quick Recap
Best Value
Rank #4
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for setup and options. ScreenshotNeo removes cookie banners, popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




