Selenium WebDriver中拖放的JavaScript变通方法

Selenium WebDriver中拖放的JavaScript变通方法,java,javascript,selenium,selenium-webdriver,Java,Javascript,Selenium,Selenium Webdriver,clickAndHold在我的测试环境设置中不适用。在尝试使用高级用户交互执行时,我不断遇到此错误: “不能按多个按钮或已按的按钮。'调用方法:[wdIMouse::down]时” 我已经测试了很多版本的Firefox,其中selenium版本为2.31.0-2.35.0,而Firefox21和selenium版本为2.35的问题最少。其他组合存在click()无声失败和可视元素被视为不可见的问题 我想使用JavaScript解决方法将一个元素拖放到另一个元素上,但在谷歌搜索之后,我找不到任何合

clickAndHold在我的测试环境设置中不适用。在尝试使用高级用户交互执行时,我不断遇到此错误:

“不能按多个按钮或已按的按钮。'调用方法:[wdIMouse::down]时”

我已经测试了很多版本的Firefox,其中selenium版本为2.31.0-2.35.0,而Firefox21和selenium版本为2.35的问题最少。其他组合存在click()无声失败和可视元素被视为不可见的问题


我想使用JavaScript解决方法将一个元素拖放到另一个元素上,但在谷歌搜索之后,我找不到任何合适的例子。

我认为你应该这样做,就像Richard在对原始问题的评论中建议的那样。使用Action类。只要在这个论坛上搜索“行动硒”。如果出现无声故障,那么您所需要做的就是确保您使用的是最新的Selenium(您引用的2.35不是最新的)。此外,如果您使用IE或Chrome,请确保您使用的二进制文件也对应于最新版本

IE11、Chrome和Firefox都会自动升级,因此,如果不进行驱动程序更新,则可能会从Actions类中获得wierd行为,而不会引发任何人类可读的错误。例如,在最新的Chrome 31上使用2.30驱动程序将打开浏览器,.get()将挂起。

试试这个

动作动作=新动作(驱动);
点击并按住(滚动).moveByOffset(x200.build().perform();似乎是因为我和Firefox有着完全相同的问题,而这正是我来到这里的原因。通过在Stack上使用建议,我终于能够使用

actions.DragAndDropToOffset(element, x, y).Perform();

我知道这不是你要求的Javascript解决方案,但希望它能对你起作用,就像对我一样。这些离奇的问题确实令人沮丧。

自从我发布了这个问题后,我找到了一些不同的解决方案。我将它们发布在这里以供参考,以便此问题对其他人有用:

当Selenium中的拖放操作无法用于HTML5时,针对Selenium输入了一个缺陷,一些人使用建议的Javascript变通解决方案对该缺陷进行了评论:

JQuery/HTML5解决方案

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

我们共同制定的解决方案正在为我们发挥作用。这是一种生活 用于测试我们的Ember.js应用程序的保护程序

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

这是我们的测试辅助程序中的内容:

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

另一位用户在不完全适用于他的情况下发布了附加代码,以及将JQuery注入页面的一些说明:

我们在发布原始drag_和drop_helper.js作为 此问题的解决方法。解决方法99%正确,但我 需要修改变通方法以将dropTarget包含在 通过simulateDrag中的“coord”对象传播的选项

i、 e.我需要改变:

致:

此外,如果应用程序处于以下状态,请注意以下示例用法 测试尚未将jQuery函数别名为$,您需要 请拼出jQuery:

i、 例如,在将拖放辅助程序注入页面之后,我们 一种接受jQuery选择器以使用模拟拖放的方法 删除函数(Java):

在这篇文章的后面,我正在测试一个剑道应用程序,并尝试了赛琳娜答案中的解决方案,但这是一个不同的解决方案,最终对我有效

(使用WebElements而不是CSS字符串的小改动):

按照Selena上述答案中的解决方案注入javascript(将文件读入变量
java\u script
)。针对现有WebElements(
拖动
拖放
)执行以下操作:


您从哪里获得
单击并按住
?我没有在Selenium2或Actions包中的Selenium1中看到它:Actions Actions=new Actions(驱动程序);操作。单击并按住(元素)。移动到元素(目标元素)。释放(元素)。执行();可能有两个按钮具有相同的定位器,或者您在前面的拖放中没有释放元素。我将代码拆分为单独执行每个操作。调用clickAndHold操作时引发错误。没有两个元素具有相同的id——它绝对是唯一的。您是否尝试过
actions.dragandrop(元素,targetElement.perform()
  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
(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);
  coord = { clientX: x, clientY: y }
coord = { clientX: x, clientY: y , dropTarget: options.dropTarget || undefined }
/**
 * 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");
}
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);
}
var triggerDragAndDrop = function (elemDrag, elemDrop) {
  /* function for triggering mouse events */
  var fireMouseEvent = function (type, elem, centerX, centerY) {
    var evt = document.createEvent('MouseEvents');
    evt.initMouseEvent(
      type,
      true,
      true,
      window,
      1,
      1,
      1,
      centerX,
      centerY,
      false,
      false,
      false,
      false,
      0,
      elem
    );
    elem.dispatchEvent(evt);
  };

  /* calculate positions*/
  var pos = elemDrag.getBoundingClientRect();
  var center1X = Math.floor((pos.left + pos.right) / 2);
  var center1Y = Math.floor((pos.top + pos.bottom) / 2);
  pos = elemDrop.getBoundingClientRect();
  var center2X = Math.floor((pos.left + pos.right) / 2);
  var center2Y = Math.floor((pos.top + pos.bottom) / 2);

  /* mouse over dragged element and mousedown*/
  fireMouseEvent('mousemove', elemDrag, center1X, center1Y);
  fireMouseEvent('mouseenter', elemDrag, center1X, center1Y);
  fireMouseEvent('mouseover', elemDrag, center1X, center1Y);
  fireMouseEvent('mousedown', elemDrag, center1X, center1Y);

  /* start dragging process over to drop target*/
  fireMouseEvent('dragstart', elemDrag, center1X, center1Y);
  fireMouseEvent('drag', elemDrag, center1X, center1Y);
  fireMouseEvent('mousemove', elemDrag, center1X, center1Y);
  fireMouseEvent('drag', elemDrag, center2X, center2Y);
  fireMouseEvent('mousemove', elemDrop, center2X, center2Y);

  /* trigger dragging process on top of drop target*/
  fireMouseEvent('mouseenter', elemDrop, center2X, center2Y);
  fireMouseEvent('dragenter', elemDrop, center2X, center2Y);
  fireMouseEvent('mouseover', elemDrop, center2X, center2Y);
  fireMouseEvent('dragover', elemDrop, center2X, center2Y);

  /* release dragged element on top of drop target*/
  fireMouseEvent('drop', elemDrop, center2X, center2Y);
  fireMouseEvent('dragend', elemDrag, center2X, center2Y);
  fireMouseEvent('mouseup', elemDrag, center2X, center2Y);

  return true;
};
    String js =  "var src = arguments[0];var dest = arguments[1];";
    js += "triggerDragAndDrop(src, dest);";
    JavascriptExecutor executor = (JavascriptExecutor) webdriver;
    executor.executeScript(java_script + js, drag, drop);