Shyam Sundar
Shyam Sundar

Reputation: 131

Python selenium is not able to automate drag and drop after many attempts

In order to automate drag and drop functionality, I am using Python Webdriver. While it worked for some apps, it didn't work for the one below.

URL: https://www.w3schools.com/html/html5_draganddrop.asp enter image description here Trying to put this image into this empty div.

The following have been tried: everything has been imported, there is no syntax error in the code.

s = wait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='drag1']")))
d = wait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='div2']")))
action_chains.drag_and_drop(s, d).perform()

Some questions:

  1. Can't I do this without using Jquery ?
  2. When I place the cursor on an empty div during automation, it drops in the right place (empty div), why is that?
  3. Wherever my mouse cursor is, it drops there. Why?

Can anyone please help me figure out why this is happening? I have been trying to figure it out for 3 hours straight.

Upvotes: 2

Views: 213

Answers (1)

sound wave
sound wave

Reputation: 3537

I don't know why but sometimes action chains doesn't work. Luckily there is an alternative: pyautogui (pip install pyautogui). It always works but uses mouse coordinates instead of elements of the webpage, so it has the big drawback that it cannot interact with the elements found with selenium.

About the drag and drop task we have a couple of ways to do it.

First method

import pyautogui, time

# 200=horizontal displacement in pixels, 0=vertical displacement, 1=duration in seconds
pyautogui.drag(200, 0, 1, button='left')
time.sleep(1)
pyautogui.drag(-200, 0, 1, button='left')

The first command drags the mouse right 200 pixels over 1 seconds while holding down the left mouse button, then the second command drags the mouse left 200 pixels (here the documentation). The downside of this method is that before running the code you have to manually positionate the mouse over the starting element.

enter image description here

Second method

Alternatively, you can take a picture of the starting element enter image description here and a picture of the ending element enter image description here then pyautogui will search on the screen those elements (i.e. their coordinates) and drag the mouse from the center of the first one to the center of the second one.

element_start = pyautogui.locateOnScreen('start.png')
element_end = pyautogui.locateOnScreen('end.png')

# compute the coordinates (x,y) of the center
center_start = pyautogui.center(element_start)
center_end = pyautogui.center(element_end)

pyautogui.moveTo(center_start)
time.sleep(1)
pyautogui.dragTo(center_end.x, center_end.y, 1, button='left')
time.sleep(1)
pyautogui.dragTo(center_start.x, center_start.y, 1, button='left')

Both methods have obvious drawbacks with respect to the Action Chains' drag_and_drop(), but we can use them when it doesn't work.

Upvotes: 1

Related Questions