JavaScript模拟通过代码进行鼠标右键单击

30

我正在使用Selenium编写一些UI测试,其中涉及到使用Dojo工具包的JavaScript树控件。

我已经按照Dojo提供的示例为树的每个节点实现了一个上下文菜单,但是我需要Selenium测试程序能够在树节点上"调用"右键单击事件,但我无法使其正常工作。测试程序似乎无法通过JavaScript模拟右键单击事件,因此上下文菜单也无法显示。

有没有人在使用Dojo和Selenium时,有过调用上下文菜单中的右键单击事件的经验?或者有任何想法可以实现这个功能?

5个回答

28

尝试使用这个替代方案,原因是之前无法正常工作的原因在于上下文菜单实际上是绑定到oncontextmenu事件的。

function contextMenuClick(element){
    var evt = element.ownerDocument.createEvent('MouseEvents');

    var RIGHT_CLICK_BUTTON_CODE = 2; // the same for FF and IE

    evt.initMouseEvent('contextmenu', true, true,
         element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
         false, false, false, RIGHT_CLICK_BUTTON_CODE, null);

    if (document.createEventObject){
        // dispatch for IE
       return element.fireEvent('onclick', evt)
     }
    else{
       // dispatch for firefox + others
      return !element.dispatchEvent(evt);
    }
}

12

为了加强说明,这里是有关参数的文档:

var myEvt = document.createEvent('MouseEvents');
myEvt.initMouseEvent(
   'click'          // event type
   ,true           // can bubble?
   ,true           // cancelable?
   ,window      // the event's abstract view (should always be window)
   ,1              // mouse click count (or event "detail")
   ,100           // event's screen x coordinate
   ,200           // event's screen y coordinate
   ,100           // event's client x coordinate
   ,200           // event's client y coordinate
   ,false         // whether or not CTRL was pressed during event
   ,false         // whether or not ALT was pressed during event
   ,false         // whether or not SHIFT was pressed during event
   ,false         // whether or not the meta key was pressed during event
   ,1             // indicates which button (if any) caused the mouse event (1 = primary button)
   ,null          // relatedTarget (only applicable for mouseover/mouseout events)
); 

5

很好的问题!

我进行了一些研究,似乎您可以像这里所示一样触发鼠标事件,并将其设置为右键单击,方法是将buttonwhich属性设置为2(在此文档中有说明)。

也许这段代码可以起作用:

function rightClick(element){
  var evt = element.ownerDocument.createEvent('MouseEvents');

  var RIGHT_CLICK_BUTTON_CODE = 2; // the same for FF and IE

  evt.initMouseEvent('click', true, true,
      element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
      false, false, false, RIGHT_CLICK_BUTTON_CODE, null);

  if (document.createEventObject){
    // dispatch for IE
    return element.fireEvent('onclick', evt)
  }
  else{
    // dispatch for firefox + others
    return !element.dispatchEvent(evt);
  }
}

4
如果您不关心上下文菜单在哪里触发,以下是更正确的版本。
function fireContextMenu(el) {
  var evt = el.ownerDocument.createEvent("HTMLEvents")
  evt.initEvent('contextmenu', true, true) // bubbles = true, cancelable = true

  if (document.createEventObject) {
    return el.fireEvent('oncontextmenu', evt)
  }
  else {
    return !el.dispatchEvent(evt)
  }
}

如果您这样做,我们可能需要使用以前的版本,在IE中修复它的行为,并适当地填充screenX、screenY、clientX、clientY等。

谢谢,其实我不在乎它发生的地方,但将来这样做可能会很好。 - Mark
如果您正在使用jQuery,右键单击元素甚至更简单:$(your_element).trigger('contextmenu'); - sunaku

2

我正在尝试在Firefox和Chrome中进行此操作,但是分派contextmenu事件并没有使浏览器打开上下文菜单。该事件被触发,因为我的oncontextmenu回调被激活了,但上下文菜单仍然不见。有人有想法吗?因为我已使用以上所有代码示例。


就我所知,我有同样的问题--也许在一些近期版本中由于安全原因被禁用了? - Coderer
OP 实现了自己的上下文菜单,无法使用 JavaScript 触发浏览器的上下文菜单。 - automaton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接