I am trying to drag and drop multiple elements using Python and Selenium.
I have an <li>
element inside an <ul>
which I need to move under another an <li>
...
the first move works well, but then some magic appears for the next movement I want to change the order of the items in the webpage.
Here is my python code
from selenium import webdriver
from selenium.webdriver import ActionChains
driver = webdriver.Chrome()
driver.get("https://jqueryui.com/sortable/")
print(driver.title)
move = ActionChains(driver)
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
item1= driver.find_element_by_xpath("//ul[@id='sortable']/li[text()='Item 3']")
before_y = item1.location.get('y')
item_height = item1.size.get('height')
move.drag_and_drop_by_offset(item1,0,item_height 10).perform()
item2= driver.find_element_by_xpath("//ul[@id='sortable']/li[text()='Item 1']")
before_y = item2.location.get('y')
item_height = item2.size.get('height')
move.drag_and_drop_by_offset(item2,0,item_height 10).perform()
item1= driver.find_element_by_xpath("//ul[@id='sortable']/li[text()='Item 3']")
before_y = item1.location.get('y')
item_height = item1.size.get('height')
move.drag_and_drop_by_offset(item1,0,item_height 10).perform()
My final goal is to sort these items as [2,3,1,5,6,4,7] or any other order
CodePudding user response:
Based on this answer - https://stackoverflow.com/a/40171414/16452840 applying .perform
at the end was enough. It dragged a Element
only once.
item1= driver.find_element_by_xpath("//ul[@id='sortable']/li[text()='Item 3']")
before1 = item1.location.get('y')
item_height = item1.size.get('height')
move.drag_and_drop_by_offset(item1,item_height,item_height 10)
time.sleep(5)
item2= driver.find_element_by_xpath("//ul[@id='sortable']/li[text()='Item 1']")
before2 = item2.location.get('y')
item_height = item2.size.get('height')
move.drag_and_drop_by_offset(item2,0,item_height 10)
time.sleep(5)
item1= driver.find_element_by_xpath("//ul[@id='sortable']/li[text()='Item 3']")
before_y = item1.location.get('y')
item_height = item1.size.get('height')
move.drag_and_drop_by_offset(item1,0,item_height 10).perform()
CodePudding user response:
The drag_and_drop_by_offset is cummulative. You can see in this example, to move first element from one position to the next, step by step you should move the first time 50 pixels to bottom, but the next times, to move again 50 pixels more to the bottom, you must put "0" in the Y axis:
i1=driver.find_elements_by_xpath("//ul[@id='sortable']/li")[0]
#Move i1 the first 50 pixels to bottom
move.drag_and_drop_by_offset(i1,0,50).perform()
#Move i1 the again 50 pixels to bottom
move.drag_and_drop_by_offset(i1,0,0).perform()
#Move i1 the again 50 pixels to bottom
move.drag_and_drop_by_offset(i1,0,0).perform()
best regards