views:

4643

answers:

5

Hi All, I am writing some UI tests using Selenium and i have a JavaScript Tree control, using the Dojo toolkit.

I have implemented a context menu for each node of the tree using the examples that Dojo provide, but I need the Selenium test to "invoke" the right click on the tree node, but I cannot get this to work. The tests simply do not simulate the right-click event through JavaScript, and the context menu does not show up.

Has anyone had any experience in invoking the right click on a context menu using Dojo and Selenium? Or have any ideas as to how to do it?

Thanks for any help that you can give.

Mark

+1  A: 

Great question!

I did some research, and it seems like you can fire a mouse event like is shown here, and make it a right-click by setting the button or which property to 2 (documented here).

Perhaps this code will work:

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);
  }
}
orip
A: 

Hi Orip, Great Answer! +1 Vote from me... but I am having trouble, it seems that your dispatch works fine, but it doesn't mimic the right-click event that Dojo fires.

(This may be a Dojo specific question) When I fire the event as you specified, it fires the onclick event (which is good) but when I right click on the tree node, the same onclick method doesn't fire, its almost like Dojo intercepts the onclick method somehow and dispatches a different event based on the right click or left click...

Any thoughts?

Mark
+5  A: 

Hi Mark,

try this instead, reason what things didn't quite work is that the context menu is in fact bound to the oncontextmenu event.

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);
    }
}
leiyou
Booo-Yaaa that did the trick, thanks Ieiyou.
Mark
A: 

Here is a more correct version if you do not care about where the context menu gets fired up

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)
  }
}

If you do, we may have to use the previous one, fix up it's behaviour in IE, and populate the screenX, screenY, clientX, clientY etc appropriately

leiyou
Thanks, I dont actually care where it happens, but it might be nice to do so in the future...
Mark
A: 

Just for good measure, here is a bit of doco on the parameters:

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