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
Comments (18)
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
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"
Jun 10, 2008
anomaly says:
Thanks a Lot Alan!! It works nowThanks a Lot Alan!! It works now
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
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
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
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
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
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
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
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>"
Aug 14, 2009
Alan Baird says:
chengwg - not sure, I've never seen that error before. Alanchengwg - not sure, I've never seen that error before.
Alan
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
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的安全站点里面,可解决此问题。
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
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 :)
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
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/