Как имитировать HTML5 Drag and Drop в Selenium Webdriver?

Я использую Python 2.7 и Selenium 2.44.

Я хочу автоматизировать действие перетаскивания в Selenium WD, но в соответствии с другими связанными сообщениями Действия в HTML5 еще не поддерживаются Selenium. Есть ли способ имитации перетаскивания в Python?

Вот код, который я пробовал:

driver = webdriver.Firefox()
driver.get("http://html5demos.com/drag")
target = driver.find_element_by_id("one")
source = driver.find_element_by_id("bin")
actionChains = ActionChains(driver)
actionChains.drag_and_drop(target, source).perform()

и это не сработало.

Ответ 1

Да, HTML5 "перетаскивание" в настоящее время не поддерживается Selenium:

Одним из предлагаемых обходных путей является симуляция перетаскивания HTML5 с помощью JavaScript:

  • скачать drag_and_drop_helper.js
  • выполнить скрипт с помощью execute_script() вызвав функцию simulateDragDrop() для source элемента, передав target элемент как dropTarget

Образец кода:

with open("drag_and_drop_helper.js") as f:
    js = f.read()

driver.execute_script(js + "$('#one').simulateDragDrop({ dropTarget: '#bin'});")

Проблема в том, что он не будет работать в вашем случае "как есть", так как требует jQuery.


Теперь нам нужно выяснить, как динамически загружать jQuery. К счастью, есть решение.

Полный рабочий пример на Python:

from selenium import webdriver

jquery_url = "http://code.jquery.com/jquery-1.11.2.min.js"

driver = webdriver.Firefox()
driver.get("http://html5demos.com/drag")
driver.set_script_timeout(30)

# load jQuery helper
with open("jquery_load_helper.js") as f:
    load_jquery_js = f.read()

# load drag and drop helper
with open("drag_and_drop_helper.js") as f:
    drag_and_drop_js = f.read()

# load jQuery
driver.execute_async_script(load_jquery_js, jquery_url)

# perform drag&drop
driver.execute_script(drag_and_drop_js + "$('#one').simulateDragDrop({ dropTarget: '#bin'});")

где jquery_load_helper.js содержит:

/** dynamically load jQuery */
(function(jqueryUrl, callback) {
    if (typeof jqueryUrl != 'string') {
        jqueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
    }
    if (typeof jQuery == 'undefined') {
        var script = document.createElement('script');
        var head = document.getElementsByTagName('head')[0];
        var done = false;
        script.onload = script.onreadystatechange = (function() {
            if (!done && (!this.readyState || this.readyState == 'loaded'
                    || this.readyState == 'complete')) {
                done = true;
                script.onload = script.onreadystatechange = null;
                head.removeChild(script);
                callback();
            }
        });
        script.src = jqueryUrl;
        head.appendChild(script);
    }
    else {
        callback();
    }
})(arguments[0], arguments[arguments.length - 1]);

До/после результата:

FQ33Ab.pngau7sOb.png

Ответ 3

Нашел рабочий пример в python (без использования jquery_load_helper.js) - https://gist.github.com/rcorreia/2362544#gistcomment-2708388

Кредиты: Kelanmomo

Как уже упоминалось: скачать drag_and_drop_helper.js

# coding = utf-8
from selenium import webdriver
import os
from time import sleep

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('http://the-internet.herokuapp.com/drag_and_drop')

with open(os.path.abspath('drag_and_drop_helper.js'), 'r') as js_file:
    line = js_file.readline()
    script = ''
    while line:
        script += line 
        line = js_file.readline()

driver.execute_script(script + "$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});")
sleep(2)
driver.quit()