在Selenium WebDriver中拖放的JavaScript解决方法 [英] JavaScript workaround for drag and drop in Selenium WebDriver

查看:352
本文介绍了在Selenium WebDriver中拖放的JavaScript解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

clickAndHold对我不起作用。尝试使用高级用户交互执行时,我一直收到此错误:

clickAndHold is not working for me in my test environment setup. I keep getting this error when trying to execute it using the Advanced User Interactions:

无法按下多个按钮或已按下按钮。调用方法时:[ wdIMouse :: down]

"Cannot press more than one button or an already pressed button.' when calling method: [wdIMouse::down]"

我用硒版本2.31.0-2.35.0测试了多个版本的Firefox,而使用selenium 2.35的Firefox 21测试的问题最少。其他组合有问题,click()无声地失败,可见元素被视为不可见。

I've tested numerous versions of Firefox with selenium versions 2.31.0-2.35.0 and Firefox 21 with selenium 2.35 has the fewest issues. Other combinations have problems with click() failing silently and visible elements being treated as invisible.

我想使用JavaScript解决方法将一个元素拖放到另一个元素,但在google搜索之后我无法找到任何体面的例子。

I want to use a JavaScript workaround for drag and drop of one element to another, but I can't find any decent examples anywhere after googling extensively.

推荐答案

由于我发布了这个问题,我发现了一些不同的解决方案。我在这里发布它们以供参考,以便这个问题对其他人有用:

Since I posted this question, I've found a few different solutions to this problem. I'm posting them here for reference so that this question is useful to others:

当Selenium中的拖放无法用于HTML5时,针对Selenium输入了一个缺陷有些人通过建议的Javascript解决方案来评论缺陷:

When drag and drop in Selenium failed to work for HTML5, a defect was entered against Selenium and some people commented on the defect with suggested Javascript work around solutions:

http://code.google.com/p/selenium/issues/detail ?id = 3604#c9

这是一个基于ruby的解决方案,可以翻译成Java,C#或Selenium支持的任何其他语言。它需要JQuery在页面上,从其他尝试使用此解决方案的用户的许多评论中可以清楚地看出,它似乎只适用于HTML5页面:

This is a ruby-based solution, which could be translated into Java, C#, or any other language supported by Selenium. It requires JQuery to be on the page, as is clear from many of the comments from other users trying to use this solution, and it seems this only works for HTML5 pages:


我们整理的解决方法对我们有用。这是一款用于测试我们的Ember.js应用程序的b $ b b life。

The workaround we put together is working for us. It's been a life saver for testing our Ember.js app.

附件是我们正在使用的最新版本......

attached is the latest version of what we are using...

这就是我们在test_helper中的含义:

this is what we have in our test_helper:



  def drag_and_drop(source,target)

    js_filepath=File.dirname(__FILE__)+"/drag_and_drop_helper.js"
    js_file= File.new(js_filepath,"r")
    java_script=""

    while (line=js_file.gets)
      java_script+=line
    end

    js_file.close

    @driver.execute_script(java_script+"$('#{source}').simulateDragDrop({ dropTarget: '#{target}'});")

    rescue Exception => e
      puts "ERROR :" + e.to_s

  end

引用的Javascript拖放模拟的源代码在此处发布:

The source code for the referenced Javascript drag and drop simulation is posted here:

https://gist.github.com/rcorreia/2362544

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

另一位用户在完全没有为他工作时发布了额外的代码,还有一些注入说明JQuery进入页面:

Another user posted additional code when it didn't work completely for him, along with some instructions for injecting JQuery into the page:

http://code.google.com/p/selenium/issues/detail?id=3604#c25


我们在原始的drag_and_drop_helper.js上发布了这个问题的
解决方法。解决方法是99%正确,但我需要修改变通方法以将dropTarget包含在通过simulateDrag中的'coord'对象传播的
选项中。

We had trouble with the original drag_and_drop_helper.js posted as a workaround for this issue. The workaround is 99% correct, but I needed to modify the workaround to include the dropTarget in the options propagated via the 'coord' object in simulateDrag.

即我需要更改:



  coord = { clientX: x, clientY: y }




to:

to:



coord = { clientX: x, clientY: y , dropTarget: options.dropTarget || undefined }




此外,还有一个注释,用于示例用法后面的那些,如果
测试下的应用程序尚未将jQuery函数别名为$,你需要
拼写jQuery:

Also, a note for those following the example usage, if the app under test does not already alias the jQuery function to $, you will need to spell-out jQuery:

即注入后将拖放帮助器放到页面上,我们有
a方法接受jQuery选择器来使用模拟拖动和
拖放函数(Java):

i.e., after injecting the drag and drop helper onto the page, we have a method that accepts jQuery selectors to use the simulated drag and drop functions (Java):



/**
 * Drag and drop via the JQuery-based drag and drop helper -- the helper
 * must have been injected onto the page prior to calling this method.
 *
 * @param dragSourceJQuerySelector a JQuery-style selector that identifies the source element to drag;
 * <em>will be passed directly to jQuery(), perform all quoting yourself</em>
 * @param dropTargetJQuerySelector a JQuery-style selector that identifies the target element to drop the source onto;
 * <em>will be passed directly to jQuery(), perform all quoting yourself</em>
 */
protected void dragAndDropViaJQueryHelper(String dragSourceJQuerySelector, String dropTargetJQuerySelector) {
    String javascript =
        "var dropTarget = jQuery(" + dropTargetJQuerySelector + ");" +
        "\n" +
        "jQuery("+ dragSourceJQuerySelector + ").simulate('drag', { dropTarget: dropTarget });";

    getLogger().info("executing javascript:\n" + javascript);
    this.executeScript(javascript);
    getLogger().info("executed drag-n-drop action via javascript");
}



另一种非jQuery解决方案



http:// ynot408 .wordpress.com / 2011/09/22 / drag-and-drop-using-selenium-webdriver /


Javascript基于浏览器的拖放操作。

Javascript based drag and drop which works across browsers.

鼠标移动在版本2.3之后停止工作,而在selenium中使用
RemoteWebDriver。下面的函数将元素1拖动到
元素2位置并释放鼠标。

Mouse move stopped working after version 2.3 while using RemoteWebDriver in selenium. The below function drags element 1 to element 2 position and releases the mouse down.



public void dragdrop(By ByFrom, By ByTo) {
    WebElement LocatorFrom = driver.findElement(ByFrom);
    WebElement LocatorTo = driver.findElement(ByTo);
    String xto=Integer.toString(LocatorTo.getLocation().x);
    String yto=Integer.toString(LocatorTo.getLocation().y);
    ((JavascriptExecutor)driver).executeScript("function simulate(f,c,d,e){var b,a=null;for(b in eventMatchers)if(eventMatchers[b].test(c)){a=b;break}if(!a)return!1;document.createEvent?(b=document.createEvent(a),a==\"HTMLEvents\"?b.initEvent(c,!0,!0):b.initMouseEvent(c,!0,!0,document.defaultView,0,d,e,d,e,!1,!1,!1,!1,0,null),f.dispatchEvent(b)):(a=document.createEventObject(),a.detail=0,a.screenX=d,a.screenY=e,a.clientX=d,a.clientY=e,a.ctrlKey=!1,a.altKey=!1,a.shiftKey=!1,a.metaKey=!1,a.button=1,f.fireEvent(\"on\"+c,a));return!0} var eventMatchers={HTMLEvents:/^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,MouseEvents:/^(?:click|dblclick|mouse(?:down|up|over|move|out))$/}; " +
    "simulate(arguments[0],\"mousedown\",0,0); simulate(arguments[0],\"mousemove\",arguments[1],arguments[2]); simulate(arguments[0],\"mouseup\",arguments[1],arguments[2]); ",
    LocatorFrom,xto,yto);
}

这篇关于在Selenium WebDriver中拖放的JavaScript解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆