Right Click an Element

This example uses the getBoundingClientRect method and a Windows API method to 1) get the mouse coordinates of a particular object and 2) to click that element. This code is taken from Paul Rogers and Bill Agee (see links below) with a little help from me putting it in one place. There are two examples below. The first example goes to the TSA site and right clicks on a link that brings up a PDF. Although the send_keys method uses AutoIt, the rest of the example uses only Windows functions. The second example goes to the EXTJS site and uses the left_click method to click the tab. This has previously resisted many attempts at clicking since EXTJS needs an actual mouse click (not a simulated one). Possibly Watir will be extended soon to include these methods and other code being worked on by others. If this happens I will update this page.

I have not tested this code for Firefox and I have no reason to believe it will work (sorry).

RELATED THREADS:
From Paul Rogers
From Bill Agee
EXTJS issues
2nd major update to this code
Paul's initial thread on event code
Paul's event suggestions on the wiki

require 'watir'

module Watir
  class Element
    def top_edge
      assert_exists
      assert_enabled
      ole_object.getBoundingClientRect.top.to_i
    end

    def top_edge_absolute
      top_edge + page_container.document.parentWindow.screenTop.to_i
    end

    def left_edge
      assert_exists
      assert_enabled
      ole_object.getBoundingClientRect.left.to_i
    end

    def left_edge_absolute
      left_edge + page_container.document.parentWindow.screenLeft.to_i
    end

    def right_click
      x = left_edge_absolute
      y = top_edge_absolute
      #puts "x: #{x}, y: #{y}"
      WindowsInput.move_mouse(x, y)
      WindowsInput.right_click
    end

    def left_click
      x = left_edge_absolute
      y = top_edge_absolute
      #puts "x: #{x}, y: #{y}"
      # need some extra push to get the cursor in the right area
      WindowsInput.move_mouse(x + 2, y + 2)
      WindowsInput.left_click
    end
  end
end

module WindowsInput
  # Windows API functions
  SetCursorPos = Win32API.new('user32','SetCursorPos', 'II', 'I')
  SendInput = Win32API.new('user32','SendInput', 'IPI', 'I')
  # Windows API constants
  INPUT_MOUSE = 0
  MOUSEEVENTF_LEFTDOWN = 0x0002
  MOUSEEVENTF_LEFTUP = 0x0004
  MOUSEEVENTF_RIGHTDOWN = 0x0008
  MOUSEEVENTF_RIGHTUP = 0x0010

  module_function

  def send_input(inputs)
    n = inputs.size
    ptr = inputs.collect {|i| i.to_s}.join # flatten arrays into single string
    SendInput.call(n, ptr, inputs[0].size)
  end

  def create_mouse_input(mouse_flag)
    mi = Array.new(7, 0)
    mi[0] = INPUT_MOUSE
    mi[4] = mouse_flag
    mi.pack('LLLLLLL') # Pack array into a binary sequence usable to SendInput
  end

  def move_mouse(x, y)
    SetCursorPos.call(x, y)
  end

  def right_click
    rightdown = create_mouse_input(MOUSEEVENTF_RIGHTDOWN)
    rightup = create_mouse_input(MOUSEEVENTF_RIGHTUP)
    send_input( [rightdown, rightup] )
  end

  def left_click
    leftdown = create_mouse_input(MOUSEEVENTF_LEFTDOWN)
    leftup = create_mouse_input(MOUSEEVENTF_LEFTUP)
    send_input( [leftdown, leftup] )
  end
end

def main()
  # Open google index page, and send a right click to the logo image
  br = Watir::IE.new()
  br.bring_to_front
  br.goto('http://www.tsa.gov/travelers/airtravel/prohibited/permitted-prohibited-items.shtm')
  br.link(:text, 'Click here').focus
  br.link(:text, 'Click here').right_click
  # Then, bring up the properties menu (works with IE6, at least)
  br.send_keys("{DOWN}{DOWN}{DOWN}{ENTER}")

  br.goto('http://extjs.com/deploy/dev/examples/tabs/tabs.html')

  tabs_div = br.div(:id, 'ext-gen6')
  long_text_tab = tabs_div.li(:id, 'ext-comp-1001__ext-comp-1003')
  long_text_tab.left_click # sucess!!
end

if __FILE__ == $0
  main
end


Labels

savetargetas savetargetas Delete
autoit autoit Delete
click click Delete
right right Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jun 09, 2008

    anomaly says:

    Kept getting this error "initialize': unknown OLE server: `AutoItX3.Control' (WI...

    Kept getting this error
    "initialize': unknown OLE server: `AutoItX3.Control' (WIN32OLERuntimeError)
    HRESULT error code:0x800401f3
    Invalid class string"

    I guess its bcos of this

    Is there a work around to this? Or am i doin it all wrong?
    Pls Advice

  2. Jun 10, 2008

    Alan Baird says:

    you have 2 or 3 options here I think: 1) re-install Watir with admin privileges ...

    you have 2 or 3 options here I think:
    1) re-install Watir with admin privileges

    or

    2) install AutoIt independent of Watir (not bad because you get the helpfile for the API and the Window Info tool)

    or

    3) you may be able to just register AutoIt from the command line. See this post from Charley Baker here
    "You need to register AutoIt. In a command window, navigate to the directory
    where you've put AutoIt and type:
    regsvr32 AutoItX3.dll"

  3. Jun 10, 2008

    anomaly says:

    Thanks a Lot Alan!! It works now

    Thanks a Lot Alan!! It works now

  4. Jun 20, 2008

    Bill Agee says:

    Hi Alan - After we discussed a solution that doesn't use a magic number, I got a...

    Hi Alan - After we discussed a solution that doesn't use a magic number, I got an example working. It also uses SendInput for the mouse motion bits. Let me know what you think:

    http://pastie.org/218919

  5. Jul 14, 2008

    chethan says:

    Hi Alan, I have tried with this code for right clicking on a link but i was inc...

    Hi Alan,

    I have tried with this code for right clicking on a link but i was inconstantly getting following error

    NameError: uninitialized constant WindowsInput::API

    Can you tell me what is the problem.

    Thanks,
    Chethan

  6. Jul 14, 2008

    Alan Baird says:

    Chethan - I ran this on my computer tonight with no problems. The error you ar...

    Chethan -

    I ran this on my computer tonight with no problems. The error you are getting leads me to believe that you might have a cut and paste mistake. I have changed the example so it is executable for anyone (I had to get creative with the example, having traveled recently - it was the first downloadable pdf example I could think of).

    Let me know if you are still getting the error message after making sure that you have completely pasted the example correctly.

    Alan

  7. Jul 15, 2008

    chethan says:

    Alan, I tried with modified script you have provided, Still unable to resolve t...

    Alan,

    I tried with modified script you have provided, Still unable to resolve the error message.
    I tried with IRE even, same error message getting popped-up.
    do I need to add any more require other than 'watir' or any other windows plugins..?

    Suggest me on this.

    Chethan

  8. Aug 06, 2008

    Alan Baird says:

    Chethan - Sorry I didn't see this earlier, I don't always see updates to the wi...

    Chethan -

    Sorry I didn't see this earlier, I don't always see updates to the wiki. I'm not sure how else to help. Maybe you can post to watir-general on the google groups list and let me know what specific problems you are having so I can help. You shouldn't need to require anything else other than what is normally required for watir. Also, can you tell me what line number in the above code is generating the error?

    Alan

  9. Oct 22, 2008

    raj_onwatir says:

    Hello Chethan I too received similar issue with this code. After days of troub...

    Hello Chethan

    I too received similar issue with this code.

    After days of troubleshooting, I found out this,

    change this,
    SetCursorPos = API.new('SetCursorPos', 'II', 'I', 'user32')
    SendInput = API.new('SendInput', 'IPI', 'I', 'user32')

    to,
    SetCursorPos = Win32API.new('user32','SetCursorPos', 'II', 'I')
    SendInput = Win32API.new('user32','SendInput', 'IPI', 'I')

    works flawless to me

    Alan,
    thank you for the code. I am a fresher to watir, so i dont understand the logic behind your code. However, I tried my best to troubleshoot using my guess and guts method

    Thank you

  10. Oct 23, 2008

    Alan Baird says:

    Raj - Sounds like you got it to work. I'm not sure why the previous example di...

    Raj -

    Sounds like you got it to work. I'm not sure why the previous example didn't though. If you still have questions let me know and I will try and answer.

    Alan

  11. Jul 13, 2009

    chengwg says:

    why I always got the error:" 'method_missing': screenLeft <WIN32OLERuntimeErr...

    why I always got the error:" 'method_missing': screenLeft <WIN32OLERuntimeError> OLE error code:80070005 in <Unknow>"

  12. Aug 14, 2009

    Alan Baird says:

    chengwg - not sure, I've never seen that error before.  Alan

    chengwg - not sure, I've never seen that error before.

     Alan

  13. May 13, 2010

    Lokesh says:

    I am also getting the error `method_missing': screenLeft (WIN32OLERuntimeError) ...

    I am also getting the error `method_missing': screenLeft (WIN32OLERuntimeError)

    coordinate.rb:23:in `method_missing': screenLeft (WIN32OLERuntimeError)
        OLE error code:80070005 in <Unknown>
          Access is denied.

        HRESULT error code:0x80020009
          Exception occurred.
     from coordinate.rb:23:in `left_edge_absolute'
     from coordinate.rb:27:in `coordinate'
     from coordinate.rb:42

    line 23 is

    top_edge + page_container.document.parentWindow.screenTop.to_i

  14. Jul 14, 2010

    yalehu says:

    If you have "error `method_missing': screenLeft (WIN32OLERuntimeError)" , the so...

    If you have "error `method_missing': screenLeft (WIN32OLERuntimeError)" , the solution is changing the IE setting.

    Add the site into your  "Trusted sites" .

    中文是: 修改IE的Internet选项,添加该站点到IE的安全站点里面,可解决此问题。

  15. Aug 24, 2010

    Patrick M Neve says:

    Almost everything works except the mouse up/down actions.... am running IE6.&nbs...

    Almost everything works except the mouse up/down actions.... am running IE6.   Any ideas?   Will post this in google group as well

  16. Sep 27, 2010

    Mariusz Kaczmarczyk says:

    Hi. I have one question about this example. Did someone run it on Firefox or so...

    Hi.

    I have one question about this example. Did someone run it on Firefox or someone have a code for firefox which works? I''ll be very greatfull !!!!

    Thanks a lot for help :)

  17. Jan 27, 2011

    Liz Trojan says:

    For convenience I've been using watir-webdriver. I attempted to use right_click ...

    For convenience I've been using watir-webdriver. I attempted to use right_click for a pulldown menu and got an error - "NotImplementedError"

    =====>>>>> Try clicking on the "Error" row...
    C:/Ruby187/lib/ruby/gems/1.8/gems/watir-webdriver-0.1.8/lib/watir-webdriver/elements/element.rb:83:in `right_click': need support in WebDriver (NotImplementedError) from tryWatir_15.rb:53

    Does anyone have any suggestions for a work-around for 'right_click' for watir-webdriver? 

    Liz

  18. Jan 28, 2011

    Zeljko says:

    Liz, we do not offer support via comments here, please take a look at http://wat...

    Liz, we do not offer support via comments here, please take a look at http://watir.com/support/