如何在 Selenium Webdriver 中模拟 HTML5 拖放?

Posted

技术标签:

【中文标题】如何在 Selenium Webdriver 中模拟 HTML5 拖放?【英文标题】:How to simulate HTML5 Drag and Drop in Selenium Webdriver? 【发布时间】:2015-06-05 12:51:36 【问题描述】:

我正在使用 Python 2.7 和 Selenium 2.44。

我想在 Selenium WD 中自动拖放操作,但根据其他相关帖子 Selenium 不支持 HTML5 中的操作。有没有办法在 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】:

是的,Selenium 目前不支持 HTML5“拖放”

Issue 3604: HTML5 Drag and Drop with Selenium Webdriver

suggested workarounds 之一是通过 javascript 模拟 HTML5 拖放

下载drag_and_drop_helper.js 通过execute_script()source元素上调用simulateDragDrop()函数执行脚本,将target元素作为dropTarget传递

示例代码:

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

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

问题是它不能“按原样”在您的情况下工作,因为它需要jQuery


现在我们需要弄清楚如何动态加载jQuery。谢天谢地,there is a solution。

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]);

结果之前/之后:

【讨论】:

您的示例仍然有效。我已经设法翻译它并在 C# 中使用它。感谢您的帮助! 我将这个助手转换为原生 JS,不再需要注入 jQuery:gist.github.com/druska/624501b7209a74040175 @DudumanBogdanVlad 你能分享 C# 版本或任何链接吗? @rahoolm 我帮助了 Raluca。她创建了一篇博文。这是链接ralucasuditu-softwaretesting.blogspot.ro/2015/08/… 谢谢@DudumanBogdanVlad,我正在调查。但就我而言,我想拖放到 XY。说在 x 方向上拖动元素一个 20 像素。请提出建议。【参考方案2】:

在 python 中找到工作示例(不使用 jquery_load_helper.js) - https://gist.github.com/rcorreia/2362544#gistcomment-2708388

致谢:Kelanmomo

正如alecxe所说:下载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()

【讨论】:

这似乎在此页面上完美运行,the-internet.herokuapp.com/drag_and_drop。但是类似的解决方案在这个页面上不起作用,crossbrowsertesting.github.io/drag-and-drop.html,使用类似 driver.execute_script(script +"$('#draggable').simulateDragDrop( dropTarget: '#droppable');") 的东西。我正在尝试测试这样的页面,但似乎无法进行拖放。【参考方案3】:

Java 版本在下面提交

https://github.com/vikramvi/Selenium-Java/commit/a1354ca5854315fded8fc80ba24a4717927d08c7

【讨论】:

以上是关于如何在 Selenium Webdriver 中模拟 HTML5 拖放?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 在 Selenium WebDriver (Selenium 2) 中最大化浏览器窗口?

如何使用selenium webdriver来判断一个网页加载完毕

如何在 ruby​​ 中使用 Selenium WebDriver (selenium 2.0) 客户端设置选项

如何在python selenium chrome webdriver中设置标头

如何在 Java 中使用 Selenium WebDriver (Selenium 2) 输入文本框?

如何在 selenium-webdriver 中为 phantomjs 驱动程序设置一个用户代理?