Селен Python - перетаскивание не работает в поле - PullRequest
0 голосов
/ 16 января 2020

Я использую последнюю версию Selenium Webdriver, и мне нужно перетащить ссылку на элемент в поле аннотации из CKeditor, но это не IFrame. Из моего предыдущего тестирования он работал с Java и Selenium2 с FF47 с помощью функции перетаскивания роботов.

Теперь мне нужно выполнить это действие с последней версией Selenium с Python3. Я поместил этот проверенный код, который должен работать, но он застрянет в моей мыши с удерживающим элементом с перетаскиваемой ссылкой, поэтому остальная часть теста пройдет с удерживающей заголовочной ссылкой, которая не сбрасывается в CKeditor, но когда я имитирую щелчок мыши в поле аннотации, оно станет активным после операции, но удерживающий элемент не будет вставлен. Только ручной щелчок мышью сбрасывает ссылку в аннотацию и сбрасывает удерживание мыши. Протестировано с Ubuntu 18.04 amd64 Firefox 70 и G Chrome 77 - одинаковые результаты.

Вот код:

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get(URL)
alink_from = driver.find_element_by_xpath(TITLE)
anotation_body = driver.find_element_by_xpath(TFIELD)
# 1. alternative
ActionChains(driver).drag_and_drop(alink_from, anotation_body).click(anotation_body).perform()
# 2. alternative
ActionChains(driver).click_and_hold(alink_from).move_to_element(anotation_body).release().click(anotation_body).perform()

Также пробовал нажать клавишу Enter, двойной щелчок мыши, перемещение по смещению, сброс действия, переключение в кадр, Javascript нажатие - ничего не работает, все так же. Может кто-нибудь помочь мне с этой операцией, пожалуйста? Мышь все еще удерживает перетаскиваемый элемент до тех пор, пока тест не закончится или я не нажму вручную где-нибудь.

Ответы [ 2 ]

0 голосов
/ 29 января 2020

ОК, поэтому я попробовал все, в основном, с решением Javascript. Попытка simulateDragDrop с селектором элемента или идентификатора, попытка simulateDragDrop с JQuery, попытка executeAsyn c для JQuery и ничего не произошло. Пробовал это даже для другого случая перетаскивания, и он не работал.

Ближайшим решением было перетаскивание JS, которое перетаскивает элемент, но оно не будет отбрасывать, что: https://ynot408.wordpress.com/2011/09/22/drag-and-drop-using-selenium-webdriver/

driver.execute_script(js + "simulate(arguments[0],'mousedown',0,0);",alink_from)
driver.execute_script(js + "simulate(arguments[0],'mousemove',arguments[1],arguments[2]);",alink_from,xto,yto)
driver.execute_script(js + "simulate(arguments[0],'mouseup',arguments[1],arguments[2]);",alink_from,xto,yto)

Наконец-то через пару часов я принял решение с использованием библиотеки PyAuto GUI! Но для этого нужно получить разные координаты, потому что PyAuto GUI использует координаты окна, а Selenium - координаты браузера. Проблема в том, что вам нужно сосредоточиться на целевом элементе, который будет перетаскиваться в цель, но для этого нужно будет навести курсор мыши на цель вверх и затем щелкнуть вверх до цели.

Также эта библиотека потребует установки (в Ubuntu например):

sudo apt-get install python3-tk
pip3 install pyautogui

Вот код:

import time
import pyautogui

height=driver.get_window_size()['height']
browser_navigation_panel_height = driver.execute_script('return window.outerHeight - window.innerHeight;')
xf = alink_from.location['x']
yf = alink_from.location['y']
act_y_from = yf%height
scroll_Y_from= yf/height
try:
    driver.execute_script("window.scrollTo(0, "+str(scroll_Y_from*height)+")")
except Exception as err:
    print("Exception")
pyautogui.moveTo(xf,act_y_from+browser_navigation_panel_height)

xto = anotation_body.location['x']
yto = anotation_body.location['y']
act_y_to = yto%height
scroll_Y_to = yto/height
pyautogui.dragTo(xto+1,act_y_to+browser_navigation_panel_height)
time.sleep(2)
pyautogui.mouseUp()
time.sleep(2)
pyautogui.click()
0 голосов
/ 16 января 2020

ActionChains выполнить действия в том порядке, в котором они были вставлены: щелкните и удерживайте элемент, поместите его в целевое поле и только затем щелкните это поле. Если поле стало активным после нажатия, сначала сделайте это

ActionChains(driver).click(anotation_body).drag_and_drop(alink_from, anotation_body).perform()
# or
anotation_body.click()
ActionChains(driver).drag_and_drop(alink_from, anotation_body).perform()
...