javascript - 如何在 Python 中实现 Selenium HTML5 拖放解决方法

标签 javascript python html selenium drag-and-drop

使用 Selenium 和 Python,目标是将元素拖放到目标,如 HTML5 所示。测试网站。 Selenium 也应该能够通过简单调用 ActionChains(driver) 方法来做到这一点,如 here 所示。在第 3.3 节中: .然而,令我沮丧的是,基于 HTML5 的网站似乎没有实现该功能,如 explained在 Selenium 错误报告中。

好的,是时候找到解决方案了,有人似乎找到了一个不错的 workaround

问题是一个没有意义的错误。这是我的实现:

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# drag and drop not working with ActionChains and HTML5
from selenium.webdriver import ActionChains


class PythonDragAndDrop(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def test_search(self):

        driver = self.driver
        driver.get("http://html5demos.com/drag")
        self.assertIn("HTML5 Demo: Drag and drop", driver.title)

    # workaround
        jquery_url = "http://code.jquery.com/jquery-1.11.2.min.js"
        driver.set_script_timeout(30)

        # load jquery helper
        with open("/Users/me/Desktop/dragNDrop/jquery_load_helper.js") as f:
            load_jquery_js = f.read()

        # load drag and drop helper
        with open("/Users/me/Desktop/dragNDrop/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'});")


    def tearDown(self):
        self.driver.close() # closes one browser tab
        # driver.quit() # closes browser and all tabs

if __name__ == "__main__":
    unittest.main()

结果是错误:

Traceback (most recent call last):
File "testDragAndDrop.py", line 35, in test_search
driver.execute_async_script(load_jquery_js, jquery_url)
File "/Library/Python/2.7/site-packages/selenium-2.45.0-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 418, in execute_async_script
{'script': script, 'args':converted_args})['value']
File "/Library/Python/2.7/site-packages/selenium-2.45.0-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 175, in execute
self.error_handler.check_response(response)
File "/Library/Python/2.7/site-packages/selenium-2.45.0-py2.7.egg/selenium/webdriver/remote/errorhandler.py", line 166, in check_response
raise exception_class(message, screen, stacktrace)
WebDriverException: Message: illegal character
Stacktrace:
    at handleEvaluateEvent (http://html5demos.com/drag:69)

什么最有可能导致此错误,以及如何修复它?

注意:使用 Python in Xcode测试 Firefox 中的拖放功能。

最佳答案

通过 JavaScript 模拟 HTML5 拖放的建议方法如下。

  1. 您的项目目录中需要有“jquery_load_helper.js”和“drag_and_drop_helper.js”文件。
  2. 尝试提供文件的完整路径,如下面的代码所示。

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)
jquery_file = "D:\\projectfolder\\jquery_load_helper.js"
drag_file = "D:\\projectfolder\\drag_and_drop_helper.js"

# load jquery helper
with open(jquery_file) as f:
    load_jquery_js = f.read()

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

# load jquery
driver.execute_script(load_jquery_js, jquery_url)

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

“jquery_load_helper.js”的代码是:

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)
jquery_file = "D:\\Python\\Work\\robot ide\\jquery_load_helper.js"
drag_file = "D:\\Python\\Work\\robot ide\\drag_and_drop_helper.js"

# load jquery helper
with open(jquery_file) as f:
    load_jquery_js = f.read()

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

# load jquery
driver.execute_script(load_jquery_js, jquery_url)

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

“drag_and_drop_helper.js”的代码是:

(function( $ ) {
        $.fn.simulateDragDrop = function(options) {
                return this.each(function() {
                        new $.simulateDragDrop(this, options);
                });
        };
        $.simulateDragDrop = function(elem, options) {
                this.options = options;
                this.simulateEvent(elem, options);
        };
        $.extend($.simulateDragDrop.prototype, {
                simulateEvent: function(elem, options) {
                        /*Simulating drag start*/
                        var type = 'dragstart';
                        var event = this.createEvent(type);
                        this.dispatchEvent(elem, type, event);

                        /*Simulating drop*/
                        type = 'drop';
                        var dropEvent = this.createEvent(type, {});
                        dropEvent.dataTransfer = event.dataTransfer;
                        this.dispatchEvent($(options.dropTarget)[0], type, dropEvent);

                        /*Simulating drag end*/
                        type = 'dragend';
                        var dragEndEvent = this.createEvent(type, {});
                        dragEndEvent.dataTransfer = event.dataTransfer;
                        this.dispatchEvent(elem, type, dragEndEvent);
                },
                createEvent: function(type) {
                        var event = document.createEvent("CustomEvent");
                        event.initCustomEvent(type, true, true, null);
                        event.dataTransfer = {
                                data: {
                                },
                                setData: function(type, val){
                                        this.data[type] = val;
                                },
                                getData: function(type){
                                        return this.data[type];
                                }
                        };
                        return event;
                },
                dispatchEvent: function(elem, type, event) {
                        if(elem.dispatchEvent) {
                                elem.dispatchEvent(event);
                        }else if( elem.fireEvent ) {
                                elem.fireEvent("on"+type, event);
                        }
                }
        });
})(jQuery);

关于javascript - 如何在 Python 中实现 Selenium HTML5 拖放解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29982072/

相关文章:

javascript - Remove() 在 mongodb 中不起作用?

javascript - Bootstrap 和 jQueryUI 冲突

python - 打印时 Spyder 控制台出错

html - CSS :after is being pushed down by following elements

html - 在 firefox 或 ie10 中将转换应用于 img 时透视不起作用?

html - 我在 CSS 中的边框样式没有覆盖整个主体

javascript - 如何在回调中访问正确的“this”?

javascript - Angular js : set option value after filling options in select

python - 交换文本中的行

python - 如何使用 matplotlib 用 unicode 文本注释热图?