Thursday, May 3, 2007

Automating Internet Explorer with Ruby: Watir

A reader has asked about automating Internet Explorer (IE) with Ruby. While you can do this using the win32ole library, I strongly recommend using the watir library instead.

WATIR (pronounced "water") stands for "Web Application Testing in Ruby". Watir is "a free, open-source functional testing tool for automating browser-based tests of web applications." Though it's designed for driving IE to test web applications, Watir is also very handy for automating IE in non-test scenarios. It leverages the win32ole library under the hood, but provides objects and methods that simplify the process.

To use Watir, first install the watir gem. Open up a Command Prompt and type the following...


gem install watir

...then, in your script, require the watir library...

require 'watir'

To create an instance of IE and navigate to a website...

ie = Watir::IE.new
ie.goto('http://rubyonwindows.blogspot.com')

To click on a link...

ie.link(:text, "win32ole").click
ie.link(:url, 'http://rubyonwindows.blogspot.com/search/label/win32ole').click

To input text into a text field...

ie.text_field(:name, 'login').set('MyLogin')

To select an option from a drop-down list...

ie.select_list( :name , "HallOfFame").select("Dave Concepcion")

To click a button...

ie.button(:value, 'Submit').click

To close the browser, call the close method...

ie.close

That's the basics. For further details and examples, you'll definitely want to check out the Watir User Guide.

For the complete Watir API reference, check out the rdocs here.

Various extensions for Watir have popped up, including WatirRecorder, WatirMaker, and WET Web Tester. Google for further details and updated links.

As always, post a comment here or send me an email with further questions or to request a topic for discussion.

Thanks for stopping by!

Digg my article

20 comments:

Walker said...

Wow, just yesterday I had the thought, I should write David and ask him about IE automation. Your blog is coming at the perfect time.

I had trouble getting gem install to work through my work proxy, but it was easy to download the watir.gem file from their site, and install it with "gem install watir.gem".

I also had to search to figure out how to hide the ie window. You can set the hide variable to true: $HIDE_IE=true, and when you connect to a new Watir::IE instance, it will be hidden. I could not figure out how to hide/unhide a window that's already open, like you can with the win32ole .visible call.

I experimented with win32ole for IE automation. From the perspective of the basics, watir does the same things as win32ole, and you don't have to keep track the whole DHTML (DOM) heirarchy.

Thanks for this tip.

Bret Pettichord said...

To hide an existing browser, use ie.visible = false. You can find this and other handy methods for Watir in the rdoc.

David Mullet said...

bret mentioned the rdoc (thanks, bret!), for which I forgot to include a link in my article. Here it is.

Anonymous said...

I am the one who asked if you could do automating IE with ruby.

Yes, I agree that Watir is easier than using win32ole directly. In fact, I use Watir for web scraping.
Normally, I go to a webpage and download the contents of a table.
For certain webpages, the browser fails to signal Watir that the page has been loaded, and the script just hangs.

My workaround was to add a goto_and_wait method to the IE class.

Now I think that knowing the IE wethods available through win32ole would be very benificial to understand Watir better. Sometimes it might better to use winole so that an application might no need to require watir and all the watir requires. This way your script does not get bloated with methods that are not used.

Thank you

Bernard Kenik
renard@nc.rr.com

Walker said...

Searched the rdoc, and I can't find a way to connect to an already open instance of IE. It seems to me that win32ole can do this. Any explanation?

Walker said...

Sorry, one more thing...I performed a word search for "visible" in the rdoc and found only one instance, which was for the -b command prompt option for making the browser invisible. From what I can see, there doesn't appear to be a "visible" method defined in watir. Sure enough:

ie = Watir::IE.new => true
ie.visible = false => method 'visible' not found

Am I missing something?

Charles Roper said...

Do you know if it is possible to take control of an existing window and refresh it using Watir? I've been having a look at Firewatir also (for controlling Firefox), but I can't see a way of attaching to an already open window.

David Mullet said...

@Charles:

yes, it is possible, using the IE.attach method:

ie = Watir::IE.attach(:title, 'Ruby on Windows')

- OR -

ie = Watir::IE.attach(:url, 'http://rubyonwindows.blogspot.com')

Then call the IE.refresh method:

ie.refresh

David

Shalini said...

watir-1[1].5.1.1192.gem automatically hide internet explorer.If i don't want to hide this.Then what should i do??
Please tell..

Unknown said...

I tried to use the property ie.visible = false and got the message that the method dont exist. Than using $HIDE_IE=true it works. So shalini, try to set it to false: $HIDE_IE=false

Unknown said...

Can i read the Error messages coming on the browser using ruby.
If possible please tell me.

David Mullet said...

@Ajeet:

You can check the contents of ie.title or ie.text. Examples:

if ie.title =~ /Cannot find server/

if ie.text=~ /cannot be displayed/

David

Mario Ruiz said...

I'm trying to do this:

-----------------------------
require 'Watir'

class Navigator < Watir::IE
def initialize(maxim)
@maxim=maxim
@iex=Watir::IE.new
end
def go(url)
@iex.goto(url)
if @maxim==1 then
@iex.maximize()
end
end
end

naveg=Navigator.new(1)
naveg.go("http://www.google.es")

puts naveg.url
--------------------------------
I want my 'naveg' object can display the properties of wakir. What am I doing wrong?

David Mullet said...

@Mariovsky-

It looks like your question has since been answered on the Ruby forum.

David

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...

automating Outlook webaccess:

I am trying to automate some of the OWA cases like (send mail, receive mail,...etc..). I am accessing OWA through IE browser. When we are accessing OWA through IE browser, I can't find object Id's of OWA in view source page. Please let me know if anyone has any ideas on how to do this.

Anonymous said...

I haven't seen mention of the Internet Explorer Developer Toolbar. This allows you to examine the gory details of web pages. Very helpful when writing Watir apps.

http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en

..Strast

Unknown said...

Hey David. I'm brand new to using win32ole and automation objects. I'm trying to get watir to work with an embedded browser but having no luck. Passing the hwnd of the embedded browser to the Watir::IE.attach does not work because watir will iterate over the open windows from
WIN32OLE.new('Shell.Application')
and check if one of those hwnd matches the one you passed. However my application is not a internet explorer window so it doesn't show up in that list.
Here is the each method watir uses to find IE instances:

def self.each
shell = WIN32OLE.new('Shell.Application')
shell.Windows.each do |window|
next unless (window.path =~ /Internet Explorer/ rescue false)
next unless (hwnd = window.hwnd rescue false)
ie = IE.bind(window)
ie.hwnd = hwnd
yield ie
end
end

So basically what i need to do is get the corresponding window and bind it using IE.bind, and then I should be able to use watir like normal. This is proving challenging. I have no trouble getting the hwnd of the application i'm using, getting the hwnd of the embedded browser is easy too.. Unfortunately I don't know how to get the corresponding com/ole object (the terminology is killing a newbie like me).
I did find that autoit's IE.au3 has a function called: __IEControlGetObjFromHWND
which takes a hwnd and returns the control.. I don't think i can call that function from ruby (any ideas). Its pretty complicated and I haven't been able to figure out how to write it in ruby either.

If your curious the source for IE.au3 is here:
http://www.therks.com/autoit/install/Include/IE.au3

Any help would be greatly appreciated

Unknown said...

Hey. Anyway we can open / close new tabs in IE using Watir?

Unknown said...

Hi

while following the above commands got the following error, Can anyone help me regarding this issue.
C:\Windows\System32>gem install watir
Successfully installed watir-5.0.0
Parsing documentation for watir-5.0.0
Done installing documentation for watir after 0 seconds
1 gem installed

C:\Windows\System32>irb
DL is deprecated, please use Fiddle
irb(main):001:0> require 'watir'
=> true
irb(main):002:0> ie = Watir::IE.new
NameError: uninitialized constant Watir::IE
from (irb):2
from C:/Ruby200-x64/bin/irb:12:in `'
irb(main):003:0>