Sie sind auf Seite 1von 118

Homebrewers Guide to Watir

eljko Filipin
This book is for sale at http://leanpub.com/watirbook This version was published on 2012-11-27 This is a Leanpub book. Leanpub helps authors to self-publish in-progress ebooks. We call this idea Lean Publishing. To learn more about Lean Publishing, go to http://leanpub.com/manifesto. To learn more about Leanpub, go to http://leanpub.com.

2009 - 2012 Leanpub

Tweet This Book!


Please help eljko Filipin by spreading the word about this book on Twitter! The suggested hashtag for this book is #watirbook. Find out what other people are saying about the book by clicking on this link to search for this hashtag on Twitter: https://twitter.com/search/#watirbook

Contents
License About the Book Prerequisites About Watir What can it do? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . What it can not do? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Recorders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Installation Windows 7, Vista and XP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mac OS X 10.8, 10.7, 10.6 and 10.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ubuntu Linux 11.04 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Watir in Five Minutes HTML Elements Supported by Watir Link HTML tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Href . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . URL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Title . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i ii iii 1 2 2 2 2 3 5 5 30 52 68 77 78 78 81 82 84 84 85 86 87

CONTENTS

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . After . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XPath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Multiple Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Img Src . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Alt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Button Checkbox Click . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Radio Click . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

88 90 91 91 92 93 93 94 94 95 96 97 97 97 98 99 99 99

Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Collections Nested Elements 101 102

Simple Nesting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 More nesting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 About Watir, Extended Version 104

History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Today . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

License
Creative Commons License

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

http://creativecommons.org/licenses/by-nc-sa/3.0/

About the Book


Homebrewers Guide to Watir is a book on Watir. It is not finished. We are working on it.

Book source code is at github.com/watir/watirbook. You can discuss the book at groups.google.com/group/watirboo HTML version of the book is at watir.github.com/watirbook. The book is available as PDF, EPUB (iPad, iPhone, iPod) and MOBI (Kindle) file at leanpub.com/watirbook. Suggested price is $9.99, but you can get the book for free! Click Buy the ebook now! button and move the You pay slider to the left hand side until the amount goes down to $0.00. Of course, you can move the slider to the right hand side and pay more for the book. I will not keep the money, all of it goes to Watir project. More information about the book is available at my blog. Money that you have donated to the Watir project == $43.98 (Updated 2012-11-23. For more stats see stats page.)

https://leanpub.com/watirbook http://watir.com/ https://github.com/watir/watirbook http://groups.google.com/group/watirbook/ http://watir.github.com/watirbook/ http://en.wikipedia.org/wiki/Portable_Document_Format http://en.wikipedia.org/wiki/EPUB http://en.wikipedia.org/wiki/Mobipocket https://leanpub.com/watirbook http://filipin.eu/homebrewers-guide-to-watir-0-8-0/ https://github.com/watir/watirbook/blob/master/stats.md

ii

Prerequisites
I will not assume that you know Ruby, but I will assume you know the basics of programming. For example, you should know what a variable is, or a loop. It is possible to write Watir tests with almost no Ruby knowledge, but the more you know Ruby, the easier it will be for you. If you grow to like Ruby, there is plenty of literature that will help you learn more. I will not assume that you know a lot about HTML, CSS, JavaScript, AJAX, DOM and stuff like that, but you will have to know the basics. For example, you will have to understand what a HTML tag is, what tag attributes are and stuff like that. I have not made up the prerequisites. I have just listed everything I knew when I started using Watir.

iii

About Watir

Watir Logo

What is this thing Watir, that I have decided to write a book about? Bret Pettichord (Watir co-creator) would say that it is family of Ruby libraries that drive browsers. A bit more verbose: Watir project is a collection of open source tools (RubyGems) that drive browsers and help you automate boring and repetitive parts of functional testing of web applications, so you have more time to test with your brain. Watir is pronounced water, and it stands for Web Application Testing in Ruby. It is implemented in Ruby, programming language. You have probably heard about web framework Ruby on Rails. Rails is also implemented in Ruby. Both Ruby and Watir (and Rails) are open source projects. If you do not know what open source is, all you need to know fow now is that you do not have to pay anything to use it. Really, anything. Today Watir can drive Microsoft Internet Explorer, Mozilla Firefox, Apple Safari, Google Chrome and Opera. Watir works on all major operating systems: Microsoft Windows, Apple Mac OS X and Linux. The fact that Watir is implemented in Ruby does not mean that it can only drive web applications written in Ruby. Since Watir gems drive browsers, it does not matter at all which operating system (Windows, Linux, Mac), programming language (C#, Java, PHP, Ruby) or framework your web applications uses. Since Watir is just a family of Ruby libraries, that means Watir code is in fact Ruby code. Why is that important? Because it means you have full access to all nice Ruby features in your tests. It also
http://en.wikipedia.org/wiki/Open_source

About Watir

means that if you need to access databases, read or write Excel files (or any other file type), send or receive mail, you can do it from your scripts. Watir can not do all that stuff, but that functionality is either included in Ruby (reading or writing to files, for example) or there are Ruby gems that cover that functionality (databases, Excel files, sending or receiving mail).

What can it do?


Watir can do almost anything that user can manually do with the browser. Open a page, click a link, button, radio button, checkbox, enter text in a text field Of course, just driving the browser does not mean it is useful for testing. It can also inspect the page currently opened in the browser. For example it can tell you the URL from the address bar, page title, list all links from the page, or just specific set of links (that have text click, for example), or just one link (that has id link1, for example) Is a checkbox present on the page, is the radio button visible, what text is entered in the text field

What it can not do?


It is important to say that Watir CAN NOT control browser plugins like Java applets, Adobe Flash or Microsoft Silverlight. There are open source projects that can control some browser plugins.

Recorders
Lets make it explicit at the very beginning of the book. Watir project does not have a recorder. You will even find that Watir community does not like recorders. Really does not like recorders. There are a few recorders available that will create Watir code, but none of them does a great job, and therefore none of them is included in the Watir project. If you are using a recorder and you have a problem, the problem is most likely in the recorder, and not in Watir. Please report all such problems to the recorder support forum or mailing list.

Gems
Software written in Ruby is usually distributed as RubyGems file. You can just call it a gem. Watir project is consisted of a few gems. The project started with watir gem (the whole project was named after it). It can only drive Internet Explorer on Windows. At the moment it is the best Internet Explorer driver. If you need to drive Internet Explorer, I would recommend watir gem.

About Watir

The next gem that appeared was firewatir. It runs on Windows, Mac and Linux and drives Firefox, but only up to Firefox 3.6, so if you need to run Firefox 4 or newer, you can not use it. The gem is deprecated since Watir 2.0. If you want to drive Firefox, use watir-webdriver gem. After it came safariwatir. It drives Safari, but only on Mac. There is no Windows version. Safariwatir works, but it is not in active development. There is a chance that watir-webdriver will be able to drive Safari soon. If you need to drive Safari on Mac, safariwatir is your only choice. If you need to drive Safari on Windows, you are out of luck. For a short period of time, there was chromewatir gem. It was able to drive Chrome, but only on Windows, I think. It was back in the day when Chrome was available only on Windows. It does not work with the recent Chrome releases. If you want to drive Chrome, use watir-webdriver gem. Celerity is the only gem that does not drive a real browser, but it emulates one. That means it is way faster but does not use your application in a way a real user would. At the moment, celerity works but it is not in active development. If you want your test to run faster, I think it would be better to drive a few headless Firefox instances. For even more speed, use more than one machine to run the tests. Watir-webdriver gem is new and shiny. It uses WebDriver (part of Selenium project) to drive browsers. It works on Windows, Mac and Linux and can drive Internet Explorer, Firefox, Chrome and Opera. If you want to drive any of the supported browsers, I would recommend this gem. The only exception is Internet Explorer. I think watir gem has better support for it. Operawatir is the newest gem. It is developed by Opera Software, the same company that develops Opera browser. It works on Windows, Mac and Linux and can drive Opera. It needs JRuby to run, so it complicates installation a bit. If you already have Ruby MRI installed and you want to drive Opera, I would recommend watir-webdriver gem. In short: if you want to drive Internet Explorer, use watir gem; if you want to drive Safari, use safariwatir gem; if you want to drive Firefox, Chrome or Opera, use watir-webdriver gem.

Alternatives
If you like the idea of testing web applications by driving real browsers, but for some reason just can not use Ruby (or you do not want to), I have good news. The success of Watir project has inspired people to create similar projects using different programming languages: WatiN, .NET Framework, http://watin.org/ Watij, Java, http://watij.com/ Win32-Watir, Perl, http://search.cpan.org/dist/Win32-Watir/ win-control, Gambit (Lisp/Scheme), http://code.google.com/p/win-control/

WatiN and Watij are active projects. If you would prefer to drive browsers with .NET or Java, I would recommend them.

About Watir

I have tried to contact authors of Win32-Watir and win-control, but did not get any response, so I could not recommend them. Another popular tool for driving browsers is Selenium (http://seleniumhq.org/). Watir-webdriver uses WebDriver (part of Selenium project) to drive browsers, so Selenium and Watir communities are now closer than ever.

Installation
Installation is not complicated, but unfortunately, it is not trivial either. I have already said that Watir is just a piece of software written in Ruby, so to install it, you have to install Ruby first. Since both Ruby and Watir are available on Windows, Mac and Linux and each of them has several releases currently in use (or in case of Linux, both distributions and releases), I will cover what I think is the relevant ones. I will use the most recent stable Ruby release, 1.9.2. I am installing everything in VMware Fusion 3.1.3 virtual machines, except Mac OS, since it does not want to be virtualized. Host OS for VMware Fusion is Mac OS X 10.6.8. You will probably be bored to tears if you read all installation chapters. A lot of stuff is repeated. I suggest that you read only the chapters you need. Feel free to read the rest of the book in the whole.

Windows 7, Vista and XP


You will need internet access if you want to follow examples in this chapter.

Windows 7 default desktop

Machine is a clean installation of: 5

Installation

Microsoft Windows 7 Professional 32-bit, Service Pack 1, Microsoft Windows Vista Ultimate 32-bit, Service Pack 1, Microsoft Windows XP Professional, Version 2002, Service Pack 3. Windows 7 and Vista machines have 1 GB RAM, XP has 512 MB. All machines are fully patched, including Internet Explorer 9 on Windows 7 and Vista. I left Internet Explorer on version 6 at XP machine, just for fun. I did not notice any difference in installing or using Watir on any version on Windows, so I have decided to put them in one chapter.

Ruby
You probably do not have Ruby installed. To make sure, open command prompt and type ruby -v. On 7 and Vista open command prompt with Start > Search programs and files > cmd > Enter, and on XP with Start > Run > cmd > Enter.

Installation

1 2 3

>ruby -v 'ruby' is not recognized as an internal or external command, operable program or batch file.

If you get the same thing as I did, you do not have Ruby installed. Download the latest Ruby 1.9. from rubyinstaller.org/downloads. At the moment it is Ruby 1.9.3p0. Execute the file.

Ruby Installation

You can leave all settings at default values, except at the Installation Destination and Optional Tasks screen check both Add Ruby executables to your PATH and Associate .rb and .rbw files with this Ruby installation checkboxes. Installation should take you just a few seconds. Lets check if Ruby is installed. You will have to open another command prompt, because the one you have opened does not see Ruby.
1 2

>ruby -v ruby 1.9.3p0 (2011-10-30) [i386-mingw32]

Congratulations! You now have the latest and greatest Ruby, 1.9.3!
http://rubyinstaller.org/downloads

Installation

RubyGems
Software written in Ruby is usually distributed as RubyGems (colloquial name is gem), Ruby package manager. Sometimes Ruby installations do not have the latest versions of RubyGems, so we will first update it. RubyGems is also a gem, (a bit recursive, right?) and we get its version with gem -v.
1 2

>gem -v 1.8.11

You should update it with gem update --system:


1 2 3

>gem update --system (...) RubyGems system software updated

Ask RubyGems again for its version, just to make sure:


1 2

>gem -v 1.8.12

DevKit
Watir and watir-webdriver gems needs ffi gem, and it needs RubyInstaller Development Kit (DevKit) . Do not worry, it is not complicated as it sounds. If you do not have DevKit installed, you will get this error message while installing watir or watir-webdriver gems:
1 2 3 4 5 6 7

Fetching: ffi-1.0.11.gem (100%) ERROR: Error installing watir: The 'ffi' native gem requires installed build tools. Please update your PATH to include build tools or download the DevKit from 'http://rubyinstaller.org/downloads' and follow the instructions at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'

The solution is easy. Go to http://rubyinstaller.org/downloads and download the latest version of DevKit. At the moment it is DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe. Execute the file. It tried to install in the folder where the file was located, in my case it was C:\Documents and Settings\zeljko\Desktop\. The documentation says spaces in path could cause trouble, as is often the case. Install it to C:\devkit. It will actually just extract itself there and DevKit window will disappear. There will be no Installation OK popup.

Installation

Where to extract DevKit

DevKit extracting

Go to C:\devkit in command prompt and type ruby dk.rb init:


1 2 3 4 5 6

C:\devkit>ruby dk.rb init [INFO] found RubyInstaller v1.9.3 at C:/Ruby193 Initialization complete! Please review and modify the auto-generated 'config.yml' file to ensure it contains the root directories to all of the installed Rubies you want enhanced by the DevKit.

And the final step is ruby dk.rb install:

Installation

10

1 2 3 4

C:\devkit>ruby dk.rb install [INFO] Installing 'C:/Ruby193/lib/ruby/ site_ruby/1.9.1/rubygems/defaults/operating_system.rb' [INFO] Installing 'C:/Ruby193/lib/ruby/site_ruby/devkit.rb'

That is it, you are ready to install watir and watir-webdriver gems.

Internet Explorer with watir

Internet Explorer 9 on Windows 7

Lets install Watir, finally. It is also done from the command line, the command is gem install watir. I prefer to add --no-ri --no-rdoc options, because I do not use either ri (Ruby Index) or RDoc (Ruby Documentation), and it cuts installation time to one third. So, if you want ri or Rdoc, use gem install watir, else use gem install watir --no-ri --no-rdoc. Watir gem (the whole Watir project got named after this gem) can drive Internet Explorer. It has better Internet Explorer support than watir-webdriver gem. Install it with gem install watir --no-ri --no-rdoc.

Installation

11

1 2 3 4

>gem install watir --no-ri --no-rdoc (...) Successfully installed watir-2.0.4 (...)

Lets drive Internet Explorer with it:

Installation

12

1 2 3 4 5 6 7 8 9 10

>irb > require "watir" => true > browser = Watir::Browser.new => #<Watir::IE:0x..f8169d746 url="about:blank" title=""> > browser.goto "watir.com" => 16.998912

watir gem drives Internet Explorer 9 on Windows 7

Installation

13

watir-webdriver
If you are just starting with Watir, start with watir-webdriver gem. It can drive Internet Explorer, Firefox, Chrome, and Opera. Install it with gem install watir-webdriver --no-ri --no-rdoc:
1 2 3 4

>gem install watir-webdriver --no-ri --no-rdoc (...) Successfully installed watir-webdriver-0.4.1 (...)

Internet Explorer with watir-webdriver


Since Internet Explorer is already installed, we will start with it. Lets see if watir-webdriver can drive Internet Explorer:

Installation

14

1 2 3 4 5 6 7 8 9 10

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :ie Selenium::WebDriver::Error::NoSuchDriverError: Unexpected error launching Internet Explorer. Protected Mode must be set to the same value (enabled or disabled) for all zones. (...)

On 7 and Vista I got Protected Mode must be set to the same value (enabled or disabled) for all zones error message (does not appear for Internet Explorer 6 on Windows XP) and Windows Firewall popup appeared letting me know that it has blocked C:\ruby192\bin\ruby.exe. So, XP/IE6 users can skip enabling protected mode.

Windows Firewall has blocked some features of this program

For now just close the popup, lets see how to fix the error message. Open Internet Explorer > wrench > Internet Options > Security. There are four zones: Internet, Local intranet, Trusted sites and Restricted sites. Protected Mode is enabled by default in Internet and Restricted sites. Enable it for Local intranet and Trusted sites and close the browser.

Installation

15

Enable Protected Mode for all zones

Let try again:


1 2 3 4 5 6 7 8 9 10 11

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :ie => #<Watir::Browser:0x..fcf3d4bb8 url="http://localhost:5555/" title="WebDriver"> > browser.goto "watir.com" => "http://watir.com/"

It works!

Installation

16

watir-webdriver gem drives Internet Explorer 9 on Windows 7

Installation

17

Firefox with watir-webdriver

Firefox 5 on Windows 7

Firefox 5 on Windows 7 Can it drive Firefox? It can! (If you do not have it installed, download it from mozilla.com/firefox.)
1 2 3 4 5 6 7 8 9 10

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :ff => #<Watir::Browser:0x62d8c4a6 url="about:blank" title=""> > browser.goto "watir.com" => "http://watir.com/"
http://www.mozilla.com/firefox/

Installation

18

watir-webdriver gem drives Firefox 5 on Windows 7

Installation

19

Chrome with watir-webdriver

Chrome 13 on Windows 7

Could it be that it can drive Chrome too? Lets find out. (You can get Chrome at google.com/chrome.)
1 2 3 4 5 6 7 8 9 10 11 12

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :chrome Selenium::WebDriver::Error::WebDriverError: Unable to find the chromedriver executable. Please download the server from http://code.google.com/p/chromium/downloads/list and place it somewhere on your PATH. More info at http://code.google.com/p/selenium/wiki/ChromeDriver. (...)
http://www.google.com/chrome

Installation

20

Looks like there is a problem. You have to download chromedriver_win32_14.0.836.0.zip (or newer version) from http://code.google.com/p/chromium/downloads/list. Unzip the file (you will get chromedriver.exe) and put it in any folder that is in your PATH. To check which folders are in PATH, open command prompt and type path:
1 2 3

>path PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem; C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Ruby192\bin

Folders are separated with ;. C:\Ruby192\bin looks like a good place, so I will put chromedriver.exe there. Lets try again:

Installation

21

1 2 3 4 5 6 7 8 9 10 11 12 13

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :chrome Started ChromeDriver port=49522 => #<Watir::Browser:0x..fdbf27548 url="about:blank" title="about:blank"> > browser.goto "watir.com" => "http://watir.com/"

Installation

22

watir-webdriver gem drives Chrome 12 on Windows 7

I got Windows Firewall popup again letting me know that it has blocked C:\ruby192\bin\chromedriver.exe. Just close it for now, I have no idea what to do with it.

Java
To drive Opera, you will have to install Java first. Lets check if Java is already installed with java -version:

Installation

23

1 2 3

>java -version 'java' is not recognized as an internal or external command, operable program or batch file.

Looks like we will have to install Java. There is big Free Java Download button at http://www.java.com/en/download. Execute download file and install Java. Lets check if Java is really installed with java -version:
1 2 3 4

>java -version java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03) Java HotSpot(TM) Client VM (build 20.1-b02, mixed mode, sharing)

Looks good to me!

Opera with watir-webdriver on 7 and Vista

Opera on Windows 7

And finally, lets drive Opera. If you do not have it installed, you can get it at opera.com.
http://www.opera.com/

Installation

24

1 2 3 4 5 6 7 8 9 10 11

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera Selenium::WebDriver::Error::WebDriverError: Unable to find the Selenium server jar. Please download the standalone server from http://code.google.com/p/selenium/downloads/list and set the SELENIUM_SERVER_JAR environmental variable to its location. More info at http://code.google.com/p/selenium/wiki/OperaDriver.

Download selenium-server-standalone-2.5.0.jar (or newer version) from http://code.google.com/p/selenium/downloads/list and put it in C:\Ruby192\bin. Then make SELENIUM_SERVER_JAR environmental variable and set it to C:\Ruby192\bin\selenium-server-standalone-2.5.0.jar. To create environmental variable, right click computer and click Properties > Advanced system
settings > Environmental Variables > User variables > New... > Variable name: SELENIUM_SERVER_JAR > Variable value: C:\Ruby192\bin\selenium-server-standalone-2.5.0.jar > OK > OK > OK.

Open new command prompt, the old one will not see SELENIUM_SERVER_JAR variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera Selenium::WebDriver::Error::UnhandledError: No response in a timely fashion. Build info: version: '2.3.0', revision: '13158', time: '2011-08-01 18:13:39' System info: os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1', java.version: '1.6.0_26' Driver info: driver.version: OperaDriver (com.opera.core.systems.scope.exceptions. ResponseNotReceivedException)

IRB said No response in a timely fashion. Then I got Windows Firewall popup. Since I do not know what to do with it, just close the popup.

Installation

25

Windows Firewall blocking Java

And finally I got Opera startup error popup saying: Opera has failed to access or upgrade
your profile. This may have occurred because your computer has insufficient resources available or because some files are locked by other applications. You may have to restart your computer before Opera will start again.

Opera startup error

Well, rebooting did not help. Not even reinstalling Opera (and then rebooting). What did help is running command prompt as administrator. So, instead of Start > Search programs and files > cmd > Enter, right click cmd and select Run as administrator.

Installation

26

Run command prompt as administrator

Finally, lets drive Opera:

Installation

27

1 2 3 4 5 6 7 8 9 10 11

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera => #<Watir::Browser:0x..fef436832 url="http://www.google.hr/" title="Google"> > browser.goto "watir.com" => "http://watir.com/"

watir-webdriver gem drives Opera 11.50 on Windows 7

Installation

28

Opera with watir-webdriver on XP


And finally, lets drive Opera. If you do not have it installed, you can get it at opera.com.
1 2 3 4 5 6 7 8 9 10 11

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera Selenium::WebDriver::Error::WebDriverError: Unable to find the Selenium server jar. Please download the standalone server from http://code.google.com/p/selenium/downloads/list and set the SELENIUM_SERVER_JAR environmental variable to its location. More info at http://code.google.com/p/selenium/wiki/OperaDriver.

Download selenium-server-standalone-2.5.0.jar (or newer version) from http://code.google.com/p/selenium/downloads/list and put it in C:\Ruby192\bin. Then make SELENIUM_SERVER_JAR environmental variable and set it to C:\Ruby192\bin\selenium-server-standalone-2.5.0.jar. To create environmental variable right click My Computer and then Properties > Advanced >
Environment Variables > User variables > New > Variable name: SELENIUM_SERVER_JAR > Variable value: C:\Ruby192\bin\selenium-server-standalone-2.5.0.jar > OK > OK > OK

Open new command prompt, the old one will not see SELENIUM_SERVER_JAR variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera Selenium::WebDriver::Error::UnhandledError: Could not start the process: Cannot run program "C:\Documents and Settings\zeljko\.launcher\ launcher-win32-i86pc.exe": CreateProcess error=14001, This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem Build info: version: '2.5.0', revision: '13516', time:
http://www.opera.com/

Installation

29

17 18 19 20 21

'2011-08-23 18:29:57' System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_26' Driver info: driver.version: OperaDriver (org.openqa.selenium.WebDriverException)

I got Windows Firewall popup. Since I do not know what to do with it, just close the popup.

Windows Firewall blocking Java

I also got This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem error message. Well, rebooting did not help. Not even reinstalling Opera (and then rebooting). What did help is installing Microsoft Visual C++ 2008 Redistributable Package (x86). Finally, lets drive Opera:
http://www.microsoft.com/download/en/details.aspx?id=29

Installation

30

1 2 3 4 5 6 7 8 9 10 11

>irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera => #<Watir::Browser:0x..fef436832 url="http://www.google.hr/" title="Google"> > browser.goto "watir.com" => "http://watir.com/"

Mac OS X 10.8, 10.7, 10.6 and 10.5


You will need internet access if you want to follow examples in this chapter.

Mac OS X 10.7 default desktop

Machine is a clean installation of Mac OS X 10.7.2, 10.6.8 or 10.5.8, fully patched, with 4 GB RAM. 10.7 has Safari 5.1.2, 10.6 has Safari 5.1 and 10.5 has Safari 5.0.6. Firefox is 9.0.1, Chrome 16, Opera

Installation

31

11.60. All browsers are English (US) version. All steps for Mac OS X 10.7 should also work on 10.8 (Mountain Lion), tested on 10.8.1.

Ruby
Regarding installing Ruby on Mac, I have good news and bad news. Good news is that Ruby is already installed by default, so you can skip this step if you just want to try Watir. Bad news is that you have an old version of Ruby installed. It will be good enough for trying Watir, but if you decide you want to use it, you will probably want to install a newer version. So, for now, I will skip Ruby installation. I will cover it later. To check if Ruby is installed on your Mac, open Terminal application (located in /Applications/Utilities) any type ruby -v. On 10.7 you should get this:
1 2

$ ruby -v ruby 1.8.7 (2010-01-10 patchlevel 249) [universal-darwin11.0]

On 10.6 you should get this:


1 2

$ ruby -v ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]

On 10.5 you should get this:


1 2

$ ruby -v ruby 1.8.6 (2009-06-08 patchlevel 369) [universal-darwin9.0]

RubyGems on 10.7 and 10.6


With RubyGems, the same story as with Ruby. It is already installed, but an old version. Lets see which version is here with gem -v. On 10.7 you should get this:
1 2

$ gem -v 1.3.6

On 10.6 you should get this:

Installation

32

1 2

$ gem -v 1.3.5

Both versions are pretty old. Watir needs never version. Fortunately, it is easy to upgrade RubyGems with sudo gem update --system:
1 2 3 4

$ sudo gem update --system (...) RubyGems 1.8.12 installed (...)

RubyGems on 10.5
With RubyGems, the same story as with Ruby. It is already installed, but an old version. Lets see which version is here with gem -v:
1 2

$ gem -v 1.0.1

RubyGems 1.0.1 is pretty old. Watir needs newer version. Fortunately, it should be easy to upgrade RubyGems with sudo gem update --system:
1 2 3 4 5

$ sudo gem update --system (...) Updating RubyGems... ERROR: While executing gem ... (Gem::RemoteSourceException) HTTP Response 302 fetching http://gems.rubyforge.org/yaml

Now you see why I said should be easy. RubyGems 1.0.1 is so old, it could not even be updated the easy way. See how lucky you are to have this book? Of course there is a way to upgrade to the newer version of RubyGems. The latest version I could install or Ruby 1.8.6 is RubyGems 1.4.2. Download rubygems-update-1.4.2.gem (click Download link), open Terminal window in folder where you have downloaded it (/Users/zeljko/Downloads in my case) and install it:
https://rubygems.org/gems/rubygems-update/versions/1.4.2

Installation

33

1 2 3 4 5 6 7 8 9

$ sudo gem install -l rubygems-update-1.4.2.gem Successfully installed rubygems-update-1.4.2 1 gem installed Installing ri documentation for rubygems-update-1.4.2... Installing RDoc documentation for rubygems-update-1.4.2... $ sudo update_rubygems RubyGems 1.4.2 installed File not found: README

Ignore File not found: README error message. Check if RubyGems is updated:
1 2

$ gem -v 1.4.2

Everything is as it should be.

Installation

34

OSX GCC Installer

OSX GCC Installer

You will need OSX GCC Installer or Xcode if you want to install watir-webdriver gem. OSX GCC Installer is way smaller than Xcode (287 MB instead of 1.68 GB for 10.7, 180 MB instead of 4.1 GB for 10.6). If you want to install safariwatir gem, OSX GCC Installer is not enough, you will have to install Xcode. There is no OSX GCC Installer for 10.5, you will have to install Xcode 3.1 (just 1 GB). Download OSX GCC Installer from https://github.com/kennethreitz/osx-gcc-installer and install it.

Installation

35

Xcode 4.2.1 for 10.7

Install Xcode 4.2.1 from App Store

To install Xcode 4.2.1 on 10.7, open App Store application, search for Xcode and download it. Please notice it is 1.68 GB. After the download is complete, you will find Install Xcode.app file in /Applications. Install it.

Xcode 3.2 for 10.6


Xcode 3.2 does not work on Mac OS 10.5. It works on 10.6. You will need Xcode from Apple if you want to install watir-webdriver or safariwatir gems. The easiest way to install Xcode is from Mac OS DVD. Insert the DVD, go to Optional Installs folder and double click Xcode.mpkg file.

Installation

36

Install Xcode 3.2 from Mac OS DVD

You can get a newer version from Apple web site. You will need Apple ID. It is username and password you already use for iTunes Store or Mac App Store. If you do not have Apple ID, you can create one for free. Sign in with your Apple ID at Xcode site and on the bottom right you will see Looking for Xcode 3? Download Now. Download Xcode 3.2.6 and iOS SDK 4.3 (Disk Image). Please notice it is 4.1 GB. You can get the newest Xcode 3.2 without Apple ID and without downloading 4 GB file. Install Xcode 3.2 from Mac OS DVD and run Software Update. It will update Xcode to 3.2.6, and downloaded file will be just about 600 MB.

Xcode 3.1 for 10.5


Xcode 3.1 is for Mac OS 10.5. On 10.6 install Xcode 3.2 or Xcode 4. You will need Xcode from Apple for watir-webdriver and safariwatir gems. The easiest way to install Xcode is from Mac OS DVD. Insert the DVD, go to Optional Installs/Xcode Tools folder and double click XcodeTools file. Leave all settings at default values.
http://developer.apple.com/xcode/

Installation

37

Install Xcode 3.1.2 from Mac OS DVD

Optionally, after Xcode is installed, run Software Update. At the moment, there is no update. If you do not have Mac OS 10.5 DVD, you can download Xcode 3.1.4 from Apple. Log in to http://connect.apple.com/ with your Apple ID. Click Developer Tools link (at the right hand side, under Downloads) and download Xcode 3.1.4 Developer DVD (Disk Image). Please note it is 993 MB.

Xcode 4 for 10.6


Xcode 4 does not work on Mac OS 10.5. It works on 10.6. According to Xcode site, Xcode 4 is a free download for all members of the iOS and Mac Developer Programs. Both programs are $99/year. If you are not a member of mentioned programs (I am not), you can buy it from Mac App Store for $4.99. But, since you can install Xcode 3 for free, there is no need to buy anything.

Installation

38

Safari with safariwatir

Safari 5.1 on Mac 10.6

Safari is installed by default on Mac OS X, so you do not have to install it. You do have to install Xcode 3 or 4 (see previous chapters). If you do not have Xcode installed, you will get this error message if you try to install safariwatir:

Installation

39

1 2 3 4 5 6 7 8 9 10 11 12 13 14

$ sudo gem install safariwatir --no-ri --no-rdoc (...) Fetching: rb-appscript-0.6.1.gem (100%) Building native extensions. This could take a while... ERROR: Error installing safariwatir: ERROR: Failed to build gem native extension. /System/Library/Frameworks/Ruby.framework/Versions/1.8/ usr/bin/ruby extconf.rb mkmf.rb can't find header files for ruby at /System/Library/ Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/ruby.h Gem files will remain installed in /Library/Ruby/Gems/1.8/gems/ rb-appscript-0.6.1 for inspection. Results logged to /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/ ./gem_make.out

Install Xcode 3 or 4 and try again:


1 2 3 4

$ sudo gem install safariwatir --no-ri --no-rdoc (...) Successfully installed safariwatir-0.4.0 (...)

Lets try safariwatir.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

$ irb > require "safariwatir" => true > browser = Watir::Safari.new => #<Watir::Safari:0x10116fc68 @scripter=#<Watir::AppleScripter:0x10116fbf0 @js=#<Watir::JavaScripter:0x10116fc18>, @typing_lag=0.08, @app=app("/Applications/Safari.app"), @document=app("/Applications/Safari.app").documents[1], @appname="Safari">> > browser.goto "http://watir.com" => nil

It works! :)

Installation

40

safariwatir gem driving Safari 5 on Mac OS 10.6

watir-webdriver
Lets try watir-webdriver gem. For now it can drive Firefox, Chrome and Opera. It should also be able to drive Safari in the future. Install it with sudo gem install watir-webdriver --no-ri --no-rdoc. If you did not install OSX GCC Installer or Xcode, you will get this:

Installation

41

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

$ sudo gem install watir-webdriver --no-ri --no-rdoc (...) Fetching: ffi-1.0.7.gem (100%) (...) Building native extensions. This could take a while... ERROR: Error installing watir-webdriver: ERROR: Failed to build gem native extension. /System/Library/Frameworks/Ruby.framework/Versions/1.8/ usr/bin/ruby/extconf.rb mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/1.8/ usr/lib/ruby/ruby.h Gem files will remain installed in /Library/Ruby/Gems/1.8/gems/ffi-1.0.7 for inspection. Results logged to /Library/Ruby/Gems/1.8/gems/ffi-1.0.7/ext/ffi_c/gem_make.out

Fortunately, it is easy to fix. Install OSX GCC Installer or Xcode (see previous chapters). Try again:

Installation

42

1 2 3 4

$ sudo gem install watir-webdriver --no-ri --no-rdoc (...) Successfully installed watir-webdriver-0.3.2 (...)

Firefox with watir-webdriver on 10.6

Firefox 6 on Mac OS 10.6

Lets try to drive Firefox! To drive Firefox, make sure you have it installed. Open our old friend IRB and type this:
http://www.mozilla.com/en-US/firefox/new/

Installation

43

1 2 3 4 5 6 7 8 9 10

$ irb > require "watir-webdriver" => true > browser = Watir::Browser.new :ff => #<Watir::Browser:0x10101ee40 url="about:blank" title=""> > browser.goto "watir.com" => "http://watir.com/"

Great! We can drive Firefox. Maybe you will get this warning:
1 2 3 4

> browser = Watir::Browser.new :ff Warning: multi_json is using default ok_json engine. Suggested action: require and load an appropriate JSON library. => #<Watir::Browser:0x105035088 url="about:blank" title="">

You can get rid of the error message by installing json gem:

Installation

44

1 2 3 4

$ sudo gem install json --no-ri --no-rdoc (...) Successfully installed json-1.6.4 (...)

watir-webdriver driving Firefox 4 on Mac OS 10.6

Firefox with watir-webdriver on 10.5


There is a problem with driving Firefox 4+ on 10.5:

Installation

45

1 2 3 4 5 6 7 8 9

$ irb > require "watir-webdriver" => true > browser = Watir::Browser.new :ff Selenium::WebDriver::Error::WebDriverError: unable to start Firefox cleanly, args: ["-silent"] (...)

Take a look at https://github.com/jnicklas/capybara/issues/313 for more detail. The easiest way to fix it is to uninstall the current version of Firefox, and install Firefox 3.6.22. I could not find how to download Firefox 4 or 5, so I did not test with them.

Chrome with watir-webdriver

Chrome 13 on Mac OS 10.6

Installation

46

Lets see if it can really drive Chrome too. To drive Chrome, make sure you have it installed.
1 2 3 4 5 6 7 8 9 10 11

$ irb > require "watir-webdriver" => true > browser = Watir::Browser.new :chrome Selenium::WebDriver::Error::WebDriverError: Unable to find the chromedriver executable. Please download the server from http://code.google.com/p/chromium/downloads/list and place it somewhere on your PATH. More info at http://code.google.com/p/selenium/wiki/ChromeDriver.

Looks like we have to install something called chromedriver executable. Fortunately, the error message is pretty clear. Download chromedriver_mac_14.0.836.0.zip (or newer version, the description should be ChromeDriver server for Mac OS X ) from http://code.google.com/p/chromedriver/downloads/list and unzip it (with mouse double-click, for example). You will get a file named chromedriver. Put it somewhere on your PATH, as the error message said. If you have no idea what that means, read on. To find out where to put chromedriver file, type this in Terminal:
1 2

$ echo $PATH /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

So, in my case, these folders are on my PATH: /usr/bin, /bin, /usr/sbin, /sbin, /usr/local/bin and /usr/X11/bin. /usr/bin looks like a good place to put chromedriver file. To open the folder, go to Finder > Go > Go to Folder > /usr/bin > Go. Copy the file there. You will have to provide admin password. Lets try again:
http://www.google.com/chrome/

Installation

47

1 2 3 4 5 6 7 8 9 10

$ irb > require "watir-webdriver" => true > browser = Watir::Browser.new :chrome => #<Watir::Browser:0x12d610c url="about:blank" title="about:blank"> > browser.goto "watir.com" => "http://watir.com/"

Finally! It works!

watir-webdriver driving Chrome 12 on Mac OS 10.5

Installation

48

Java on 10.7
To drive Opera, you need Java. It is not installed by default on Mac OS X 10.7. To install it type java -version in Terminal:
1 2

$ java -version No Java runtime present, requesting install.

You will get No Java runtime present, requesting install message and a popup window will appear.

Install Java

Click button Install and Java will install. Check if Java is installed with java -version:
1 2 3 4

$ java -version java version "1.6.0_29" Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-11M3527) Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode)

Java on 10.6 and 10.5


To drive Opera, you need Java. Fortunately, it is already installed. All you have to do is check if it is installed with java -version: On 10.6 you should get this:
1 2 3 4

$ java -version java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03-384-10M3425) Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-384, mixed mode)

On 10.5 you should get this:

Installation

49

1 2 3 4

java version "1.5.0_30" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_30-b03-389-9M3425) Java HotSpot(TM) Client VM (build 1.5.0_30-161, mixed mode)

Opera with watir-webdriver

Opera 11.51 on Mac 10.6

Lets see how it drives Opera. To drive Opera, make sure you have it installed.
http://www.opera.com/

Installation

50

1 2 3 4 5 6 7 8 9 10 11

$ irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera Selenium::WebDriver::Error::WebDriverError: Unable to find the Selenium server jar. Please download the standalone server from http://code.google.com/p/selenium/downloads/list and set the SELENIUM_SERVER_JAR environmental variable to its location. More info at http://code.google.com/p/selenium/wiki/OperaDriver.

Error message similar to the one when we first tried to open Chrome. The solution is similar too. We have to download a file, put it somewhere and point a variable to it. Do not worry, it sounds more complicated than it really is. Fortunately again, the error message says it all. Go to http://code.google.com/p/selenium/downloads/list and download selenium-server-standalone-2.5.0.jar (or newer version). Since I have put chromedriver file in /usr/bin, I will put selenium-server-standalone-2.5.0.j file there too. You will have to provide admin password when copying the file. The last step is setting SELENIUM_SERVER_JAR environmental variable. Create (if the file does not exist) or edit .bash_profile file in your home folder (/Users/zeljko in my case) with your favorite text editor. Add this line to the file:
1

export SELENIUM_SERVER_JAR=/usr/bin/selenium-server-standalone-2.5.0.jar

If you just got lost, I have step by step guide how to do it. Open new Terminal tab or window (it should open in your home folder by default, /Users/zeljko in my case) and type nano .bash_profile:
1

$ nano .bash_profile

GNU nano text editor will open. Paste (cmd-v, for example) export SELENIUM_SERVER_JAR... line. Exit GNU nano and save the file with control+x. Press y when it asks Save modified buffer (ANSWERING "No" WILL DESTROY CHANGES)? and press Enter when it displays File Name to Write: .bash_profile or Save modified buffer (ANSWERING "No" WILL DESTROY CHANGES)? (text is different if the file already exists or not).

Installation

51

GNU nano asking should it save changes to .bash_profile file

If you have done everything right, GNU nano will close and you will see normal Terminal window. We can check if the line is written to .bash_profile file:
1 2

$ cat .bash_profile export SELENIUM_SERVER_JAR=/usr/bin/selenium-server-standalone-2.5.0.jar

Lets drive Opera, finally! Open new Terminal window or tab (this is important, already opened windows or tabs would not see SELENIUM_SERVER_JAR variable).

Installation

52

1 2 3 4 5 6 7

$ irb > require "watir-webdriver" => true > browser = Watir::Browser.new :opera #<Watir::Browser:0x1017f6a28 url="opera:debug" title="Connect to Debugger">

watir-webdriver gem drives Opera 11.51 on Mac 10.6

Ubuntu Linux 11.04


You will need internet access if you want to follow examples in this chapter.

Installation

53

Ubuntu Linux 11.04 default desktop

Machine is a clean installation of Ubuntu Linux 11.04, fully patched, 512 MB RAM. Firefox 5.0, Chrome 12, Opera 11.50.

Ruby
Lets see if Ubuntu comes with Ruby installed. Open Terminal (Applications > Accessories > Terminal ) and type ruby -v:
1 2 3 4

$ ruby -v The program 'ruby' is currently not installed. You can install it by typing: sudo apt-get install ruby

Install it with sudo apt-get install ruby:

Installation

54

1 2 3 4 5 6

$ sudo apt-get install ruby (...) Setting up libruby1.8 (1.8.7.302-2) ... Setting up ruby1.8 (1.8.7.302-2) ... Setting up ruby (4.5) ... (...)

Check the version with ruby -v:


1 2

$ ruby -v ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-linux]

Ruby 1.8.7 is pretty good, but 1.9.2 would be better. Since we just want to get Watir installed the easiest possible way, we will user Ruby 1.8.7.

RubyGems
Lets see the version of RubyGems we got with Ruby with gem -v:
1 2 3 4

$ gem -v The program 'gem' is currently not installed. You can install it by typing: sudo apt-get install rubygems1.8

Looks like we did not get any version installed. We will install RubyGems with apt-get, since that is the easiest way:
1 2 3 4

$ sudo apt-get install rubygems1.8 (...) Setting up ruby1.8-dev (1.8.7.302-2) ... Setting up rubygems1.8 (1.3.7-3) ...

Ask RubyGems for its version with gem -v:


1 2

$ gem -v 1.3.7

RubyGems 1.3.7 is really old (May 13, 2010). Lets try to update it the usual way, with gem update --system:
https://rubygems.org/gems/rubygems-update/versions

Installation

55

1 2 3 4 5 6 7 8 9 10

$ gem update --system ERROR: While executing gem ... (RuntimeError) gem update --system is disabled on Debian, because it will overwrite the content of the rubygems Debian package, and might break your Debian system in subtle ways. The Debian-supported way to update rubygems is through apt-get, using Debian official repositories. If you really know what you are doing, you can still update rubygems by setting the REALLY_GEM_UPDATE_SYSTEM environment variable, but please remember that this is completely unsupported by Debian.

Since I do not really know what I am doing, I will leave RubyGems at version 1.3.7 and hope everything will work.

watir-webdriver
I think that Watir-webdriver gem is the future of Watir. In short, it can drive Firefox, Chrome and Opera. Install watir-webdriver gem with sudo gem install watir-webdriver --no-ri --no-rdoc.

Installation

56

1 2 3 4

$ sudo gem install watir-webdriver --no-ri --no-rdoc (...) Successfully installed watir-webdriver-0.2.8 4 gems installed

Firefox with watir-webdriver

Firefox on Ubuntu 11.04

Since Firefox is installed by default on Ubuntu, you do not have to install it. Lets check if it can drive Firefox:

Installation

57

1 2 3 4 5 6 7 8 9 10 11 12 13

$ irb > require "rubygems" => true > require "watir-webdriver" => true > browser = Watir::Browser.new :ff => #<Watir::Browser:0x..fb734a4d8 url="about:blank" title=""> > browser.goto "watir.com" => "http://watir.com/"

Installation

58

Watir-webdriver drives Firefox on Ubuntu 11.04

No problem here, works just fine.

Installation

59

Chrome with watir-webdriver

Chrome on Ubuntu 11.04

Now, lets see if it can really drive Chrome too. Ubuntu does not have Chrome installed by default, so you have to install it yourself. Download it from google.com/chrome. After installation Chrome will appear at Applications > Internet > Chrome.
http://www.google.com/chrome

Installation

60

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

$ irb > require "rubygems" => true > require "watir-webdriver" => true > browser = Watir::Browser.new :chrome Selenium::WebDriver::Error::WebDriverError: Unable to find the chromedriver executable. Please download the server from http://code.google.com/p/chromium/downloads/list and place it somewhere on your PATH. More info at http://code.google.com/p/selenium/wiki/ChromeDriver. (...)

Looks like we have to install something called chromedriver executable. Fortunately, the error message is pretty clear. Download chromedriver_linux32_14.0.836.0.zip (or newer version, the description should be ChromeDriver server for linux32) from http://code.google.com/p/chromium/downloads/list and unzip it (mouse right click and then Extract Here, for example). You will get a file named chromedriver. Put it somewhere on your PATH, as the error message said. The easiest way to do it on Ubuntu is to create a folder called bin in your home folder (/home/zeljko/bin in my case). You have to reboot (or at least log out and then log in, but I have not checked that) and by some magic (provided by /home/zeljko/.profile file in my case) /home/zeljko/bin folder will appear in your PATH:
1 2 3

$ echo $PATH /home/zeljko/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin: /sbin:/bin:/usr/games

Lets drive Chrome, finally:

Installation

61

1 2 3 4 5 6 7 8 9 10 11 12 13

$ irb > require "rubygems" => true > require "watir-webdriver" => true > browser = Watir::Browser.new :chrome => #<Watir::Browser:0x..fb743b7d4 url="about:blank" title="about:blank"> > browser.goto "watir.com" => "http://watir.com/"

And it really works!

Installation

62

Watir-webdriver drives Chrome on Ubuntu 11.04

Java
To drive Opera, you will have to install Java first. Lets check if Java is already installed with java -version:

Installation

63

1 2 3 4 5 6

$ java The program 'java' can be found in the following packages: * gcj-4.4-jre-headless * gcj-4.5-jre-headless * openjdk-6-jre-headless Try: sudo apt-get install <selected package>

Looks like we will have to install Java. Install it with sudo apt-get install openjdk-6-jre-headless:
1 2 3 4 5 6 7 8

$ sudo apt-get install openjdk-6-jre-headless (...) Setting up openjdk-6-jre-lib (6b22-1.10.2-0ubuntu1~11.04.1) ... Setting up icedtea-6-jre-cacao (6b22-1.10.2-0ubuntu1~11.04.1) ... Setting up icedtea-6-jre-jamvm (6b22-1.10.2-0ubuntu1~11.04.1) ... Setting up ca-certificates-java (20100412) ... creating /etc/ssl/certs/java/cacerts... done.

Lets check if Java is really installed with java -version:

Installation

64

1 2 3 4 5

$ java -version java version "1.6.0_22" OpenJDK Runtime Environment (IcedTea6 1.10.2) (6b22-1.10.2-0ubuntu1~11.04.1) OpenJDK Client VM (build 20.0-b11, mixed mode, sharing)

Looks good to me!

Opera with watir-webdriver

Opera on Ubuntu 11.04

To drive Opera make sure you have it installed. Lets see how it drives Opera. Open our old friend, IRB:
http://www.opera.com/

Installation

65

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

$ irb > require "rubygems" => true > require "watir-webdriver" => true > browser = Watir::Browser.new :opera Selenium::WebDriver::Error::WebDriverError: Unable to find the Selenium server jar. Please download the standalone server from http://code.google.com/p/selenium/downloads/list and set the SELENIUM_SERVER_JAR environmental variable to its location. More info at http://code.google.com/p/selenium/wiki/OperaDriver. (...)

Error message similar to the one when we first tried to open Chrome. The solution is similar too. We have to download a file, put it somewhere and point a variable to it. Do not worry, it sounds more complicated than it really is. Fortunately again, the error message says it all. Go to http://code.google.com/p/selenium/downloads/list and download selenium-server-standalone-2.5.0.jar (or newer version, the description should be Use this if you want to use the Selenium RC or Remote WebDriver or use Grid 2 without needing any additional dependencies). Since I have put chromedriver file in /home/zeljko/bin, I will put this file there too. The last step is setting SELENIUM_SERVER_JAR environmental variable. If you just got lost, I have step by step guide how to do it. Open Nautilus and go to your home folder: Places > Home Folder. You want to edit .bashrc file, but by default files that have names starting with dot are not displayed. To see the file go to View > Show Hidden Files. Doubleclick .bashrc file (it will open the file in gedit editor). Add this line to the file:
1

export SELENIUM_SERVER_JAR=~/bin/selenium-server-standalone-2.5.0.jar

Save the file and close all Terminal windows. Open Terminal again. To check if the variable is set, try printenv | grep SELENIUM:
1 2

$ printenv | grep SELENIUM SELENIUM_SERVER_JAR=/home/zeljko/bin/selenium-server-standalone-2.5.0.jar

Looks good to me! After all this work, enjoy driving Opera:

Installation

66

1 2 3 4 5 6 7 8 9 10 11 12 13

$ irb > require "rubygems" => true > require "watir-webdriver" => true > browser = Watir::Browser.new :opera => #<Watir::Browser:0x..fb72fd854 url="http://watir.com/" title="Watir"> > browser.goto "watir.com" => "http://watir.com/"

Installation

67

Watir-webdriver drives Opera on Ubuntu 11.04

Watir in Five Minutes


You will need internet access if you want to follow examples in this chapter. In this chapter I assume you have Ruby, RubyGems, watir-webdriver gem and Firefox browser installed, since that is the combination available on all operating systems. If you do not have them installed, please see Installation chapter. An example would be handy right about now Brian Marick would say. Five minutes from now, you will be crazy about Watir. If not, maybe it is not the right tool for you. Even then, if you continue reading the book, I hope you will grow to like it the more you know about it. In the rest of the book, I will explain all Watir functionality in great (maybe even painful) detail, but for now, I just want to show off a few cool features to get you excited about it. I still remember how pleasantly surprised I was the first time I saw Watir at work. I installed it, and in a few hours I was able to create a script that would log me into the web application I was testing. Since you have this book you will be able to log into your web site in minutes, not hours. If you are familiar with Ruby, I am sure you already think IRB is one of the greatest tools for learning a new Ruby library. If you are new to Ruby, you are probably thinking: What is this IRB thing? IRB (in this case) does not stand for International Rugby Board or Immigration or Refugee Board (of Canada). It stands for Interactive Ruby Shell. Think of it as a shell that knows Ruby (as the name says). To start IRB, just type irb in command line. You will see something like this:
1 2

$ irb >

Now you can enter any Ruby command and you will immediately get a result. We will start with telling Ruby that we want to use watir-webdriver gem with require "watir-webdriver": You should see something like this:
1 2

> require "watir-webdriver" => true

If you get something like this, do not panic:

68

Watir in Five Minutes

69

1 2 3 4

> require "watir-webdriver" LoadError: no such file to load -- watir-webdriver from (irb):1:in `require' from (irb):1

It just means you have to require RubyGems first. In that case, do this:
1 2 3 4 5

> require "rubygems" => true > require "watir-webdriver" => true

Every Ruby command returns something. After require "rubygems" you will get either true or false, depending how your Ruby installation is set up. You do not have to care about that right now. You should get => true after require "watir-webdriver". There are two parts in the returned line. The first one is =>. It looks like an arrow. It means Ruby returned this. The second part is true, the thing that is actually returned. When true is returned, it usually means that everything is fine. Unless I say differently, just ignore what is returned, for now. And now the magic starts. With just one command you will open Firefox.

Watir in Five Minutes

70

browser = Watir::Browser.new :ff

watir-webdriver driving Firefox 6 on Mac OS 10.6

When I saw the browser magically appearing for the first time, I started singing (with apologies to Foreigner): Ive been waiting for a tool like you to come into my life Please open just one browser. It will be enough. You can play with other browsers later. Output should be similar to this:
http://www.youtube.com/watch?v=BrzzR-3PPqw

Watir in Five Minutes

71

1 2

> browser = Watir::Browser.new :ff => #<Watir::Browser:0x2ed1f1cd5b186306 url="about:blank" title="">

As I said earlier, you can ignore #<Watir::Browser...>. Opening Firefox returned the browser as an object, and this is textual representation of the object. Just opening a browser is cool, but not so useful. Watir can do much more. For example, it can navigate the browser to any site. I will use google.com in this example. I suggest that you literally follow the example, and then try a few sites yourself. So, go to google.com:
1 2

> browser.goto "http://www.google.com/" => "http://www.google.hr/"

And google.com opens. Magic, isnt it? Controlling the browser is really useful but, as I am sure you already know, there is more to testing than just performing the actions. You have to check what happened after the action. What happens when I enter a URL in browser address bar, when I click a link or a button, when I enter some text in a text field or select something from select box? This is the first time we will perform a check. It is also the first time we will take a look what Ruby returns after the command. Lets check if the browser really opened google.com.
1 2

> browser.url => "http://www.google.hr/"

It really works! Ruby returned a string (the thing in double quotes) that contains the text from the browser address bar. Since I am in Croatia, google.hr opened. If you are not in the US, some other Google site could open. Time to click on a link. It is easy to explicitly say which link to click on. Right now I want to click on a link with the text Google.com in English. It gets just a bit more complicated if there are two links with the same text on the page, but we will deal with that later. If your browser already opened google.com, ignore this step.
1 2

> browser.a(:text => "Google.com in English").click => []

And google.com opens. Before we click another link, I want to show off one of Watirs killer features. It is called flash. Real world web applications are complex, and sometimes when you are developing a new test or debugging an existing one, you want to make sure you are interacting with the correct element. Try this (and look at Images link in the top-left corner of google.com):

Watir in Five Minutes

72

1 2

> browser.a(:text => "Images").flash => 10

Link Images with normal background

Watir in Five Minutes

73

Link Images with red background

Link Images changes background from white to red a few times. Did you see the link flashing? Its background color changes to red a few times. Isnt that cool? I use it all the time when I talk about Watir (at conferences, for example). I think Watir is just great for presentations. It is very visual. If you did not see the flash (it flashes just for a short time), execute the command a few more times. To execute the same command in command prompt again, just click up arrow key on your keyboard and the last command that you have typed will appear. It is time to click the link:
1 2

> browser.a(:text => "Images").click => []

This time, lets check the page title.

Watir in Five Minutes

74

1 2

> browser.title => "Google Images"

We got back the string with the page title. Lets search for something. This will enter book in search text field:
1 2

> browser.text_field(:name => "q").set "book" => ["book"]

Maybe you are wondering how I knew the text field had the value of name attribute set to q (I am talking about :name => "q"). If you do not know how to inspect pages, read on. I will explain it later. Now, click Search Images button:
1 2

> browser.button(:value => "Search Images").click => []

Page with search results will open. Lets check how many images are on the page. (You might get a different number, it does not have to be 250.)
1 2

> browser.images.size => 250

And finally, lets close the browser.


1 2

> browser.close => true

Well, that was a lot of fun. But you do not want to type into IRB all the time. You want to run the tests and do something else while it runs. As for almost everything else in Ruby and Watir, there is a simple solution. Paste all code you have entered in IRB in a text file, and save it with rb extension. IRB is used only for development or debugging, so do not paste irb as the first line of the file. The file should look like this:

Watir in Five Minutes

75

1 2 3 4 5 6 7 8 9 10 11

require "watir-webdriver" browser = Watir::Browser.new :ff browser.goto "http://www.google.com/" browser.url browser.a(:text => "Google.com in English").click browser.a(:text => "Images").click browser.title browser.text_field(:name => "q").set "book" browser.button(:value => "Search Images").click browser.images.size browser.close

Add require "rubygems" at the top of the file if you had to type it in IRB. You can use any text editor to edit the file. I use RubyMine or NetBeans. Save the file as watir5.rb. If IRB is still running in your command prompt, enter exit to return to normal command prompt, or open a new command prompt. You can remove clicking Google.com in English link if Firefox opens google.com automatically for you. To run the file, navigate in command prompt to the folder where you have saved it and run it with ruby watir5.rb:
1

$ ruby watir5.rb

Smile while the browser clicks around. What is the output in the command prompt? Nothing? Yes, nothing. IRB displays values that Ruby returns, but when you execute Ruby file from the command line, it does not display the values Ruby returns. You have to explicitly say to Ruby that you want them displayed. It is as easy as adding puts in front of the command. Add puts in front of three lines. Modify the script to look like this. You can add puts in front of every command, but you really do not care about what some commands return:
http://www.jetbrains.com/ruby/ http://netbeans.org/

Watir in Five Minutes

76

1 2 3 4 5 6 7 8 9 10 11

require "watir-webdriver" browser = Watir::Browser.new :ff browser.goto "http://www.google.com/" puts browser.url browser.a(:text => "Google.com in English").click browser.a(:text => "Images").click puts browser.title browser.text_field(:name => "q").set "book" browser.button(:value => "Search Images").click puts browser.images.size browser.close

Run the script. This time the output should look like this:
1 2 3 4

$ ruby watir5.rb http://www.google.hr/ Google Images 246

Later I will show you how to make cool looking reports. If you are not impressed by now, you probably never will. If you liked what you saw so far, it is time to bring on heavy artillery. Lets go deeper.

HTML Elements Supported by Watir


Different Watir gems support different HTML elements. For example, watir-webdriver gem supports all elements. Yes, all of them. Watir gem supports the most common ones, but as you will see later in the book, it is easy to extend it to support more elements. Safariwatir does not support a lot of elements, but it supports the most common ones. Please take a look at HTML Elements Supported by Watir table in Reference chapter for more details.

77

Link
You do not need internet access if you want to follow examples in this chapter. All examples in this chapter are tried on Ruby 1.9.2p290, RubyGems 1.8.11: Mac OS 10.6.8: Firefox 8 and watir-webdriver 0.3.9 Microsoft Windows 7 Professional 32-bit, Service Pack 1, Internet Explorer 9 and watir 2.0.4 Note: safariwatir does not support a lot of features that are used in this chapter.

HTML tag
Lets take a closer look at one HTML element. Links are probably the most popular of all HTML elements, so it would be just fair to start there. Usually, you can recognize a link on a web page because its text is underlined. Its HTML looks like this:
1

<a href="clicked.htm">click me</a>

There are two ways of accessing the link, browser.a and browser.link. Both of them do the same thing, but browser.a is not supported in older versions of watir gem and in safariwatir. You could access the link in a lot of ways (alphabetically): after?, class, css, href, html, id, index,
name, text, title, url, xpath and multiple attributes.

Examples:
1 2 3 4 5 6 7 8 9 10 11 12

browser.a(:after? => browser.a(:text => "buy")) browser.a(:class => "header") browser.a(:css => "[id=click-me]").click browser.a(:href => "clicked.htm") browser.a(:html => /test/) browser.a(:id => "footer") browser.a(:index => 1) browser.a(:name => "sidebar) browser.a(:text => "click me") browser.a(:title => "click me") browser.a(:url => /watir/) browser.a(:xpath => "//a[@href='clicked.htm']/").click

and multiple attributes: 78

Link

79

browser.a(:text => "click me", index => 2)

To make sure you could do the exercises from this chapter even without internet access, we will create two HTML files, and create a link from one to the other. First, create a simple HTML file with only one link in it. Open your favorite text editor, enter the following line in it and save it as link.htm:
1

<a href="clicked.htm">click me</a>

Then create another file, clicked.htm and put it in the same folder as link.htm. You can put anything in clicked.htm file, for example just text Clicked!. You can save the files anywhere (make sure both files are in the same folder), but I suggest that you save it to desktop, it will be easy to find there. Open link.htm with Firefox.

A simple web page with only one link.

Copy URL from the address bar and paste it somewhere safe, in another file, for example. In my case, URL was file:///Users/zeljko/Desktop/link.htm, since I have saved the file to my desktop. We will need the URL to open the same HTML page later with Watir. Close the browser.

Link

80

Open command prompt application and open IRB (make sure you are opening command prompt as administrator if you are on Windows):
1 2

$ irb >

Let IRB know that you plan to use watir-webdriver or watir gem:
1

require "watir-webdriver"

or
1

require "watir"

The output should look similar to this:


1 2

> require "watir-webdriver" => true

If you get something like this, do not panic:


1 2 3 4

> require "watir-webdriver" LoadError: no such file to load -- watir-webdriver from (irb):1:in `require' from (irb):1

It just means you have to require RubyGems first. In that case, do this:
1 2 3 4 5

> require "rubygems" => true > require "watir-webdriver" => true

In following code examples, do not type lines that start with => (=> true for example). That represents value that Ruby returned. You can ignore those lines, until I say differently. Open the browser (the following code will open Firefox if you are using watir-webdriver gem, and Internet Explorer if you are using watir gem):

Link

81

1 2

browser = Watir::Browser.new => #<Watir::Browser:0x2b6d7f970192e212 url="about:blank" title="">

Go to link.htm:
1 2

browser.goto "file:///Users/zeljko/Desktop/link.htm" => "file:///Users/zeljko/Desktop/link.htm"

We are ready now to play with the link.

Text
We will start with accessing the link via text, since it is the most common way of accessing links. Our link looks like this:
1

<a href="clicked.htm">click me</a>

There is two ways to access the link, using the exact text, and only part of the text.

Text and String


Since we know the exact text of the link, we can click it using string. But before we click the link, lets flash it, just to make sure we are interacting with the right link:
1 2

browser.a(:text => "click me").flash => 10

Lets finally click the link:


1 2

browser.a(:text => "click me").click => [] clicked.htm file should open. Tell the browser to go back to link.htm, we have more exercises to

finish there:
1 2

browser.back => ""

Browser should go back to link.htm.

Link

82

Text and Regular expression


If you know only a portion of a string, you can use regular expressions. For now, think of regular expressions as a string with a strange syntax. It looks like this: /click/. Please notice the slashes instead of quotes. When would you use regular expressions? For example, you want to click on a discussion on a forum by its title, but the title changes form On Dogs (1) to On Dogs (2) after the first reply is posted. You could not use "On Dogs" to locate the link, because link text is On Dogs (1) and Watir will complain that it could not find it. You could use "On Dogs (1)" to locate the link the first time, but when link text changes to On Dogs (2), Watir will no longer be able to find the link. In that case, you could tell Watir: Well, I know just one part of the string. and it will happily look at all strings until it finds the one that matches the portion you have provided. In our example, we will use /click/. First, we will flash the link, and then click it. In this example we do not care if there is any text before or after click.
1 2 3 4 5

> browser.a(:text => /click/).flash => 10 > browser.a(:text => /click/).click => []

Of course, tell the browser to go back to link.htm with browser.back. From now on, each time clicked.htm opens, tell the browser to go back to link.htm.
1 2

browser.back => ""

Href
For this example, lets look only at the links href attribute.
1

<a href="clicked.htm">click me</a>

Href and String


If you know the full value of links href attribute, you could use string to click the link. Of course, flash the link first, to see if everything works, then click it.

Link

83

1 2

browser.a(:href => "clicked.htm").flash => 10

The above code will not work in watir gem, but this one will:
1 2

browser.a(:href => "file:///Users/zeljko/Desktop/clicked.htm").flash => nil

Click it with
1 2

browser.a(:href => "clicked.htm").click => []

or
1 2

browser.a(:href => "file:///Users/zeljko/Desktop/clicked.htm").click => 0.078119

Did you remember to tell tell the browser to go back to link.htm with browser.back?
1 2

browser.back => ""

Href and Regular Expression


If you know only a portion of href attribute, you will still use href to locate the link, but this time with a regular expression instead of a string. The usual story: flash, click, back to link.htm.
1 2 3 4 5 6 7 8

browser.a(:href => /clicked/).flash => 10 browser.a(:href => /clicked/).click => [] browser.back => ""

Link

84

URL
Note: watir-webdriver does not support accessing page elements via url.
url is alias for href. So, everything I said about href is true for url also. Well, not everything. If

you try any of the following with watir-webdriver:


1 2

browser.a(:url => "clicked.htm").click browser.a(:url => /clicked/).click

you would get this error message:


1 2 3

Watir::Exception::MissingWayOfFindingObjectException: invalid attribute: :url ...

Watir-webdriver wants to tell you that it does not support accessing links via url attribute. Other gems support it. Since it is just an alias for href, I would recommend that you use href everywhere.

ID
According to the HTML specification, almost all HTML elements can have an id, and each id should be unique on the page. Uniqueness makes id very convenient for us. All other element attributes can appear more than once on the page and Watir will locate only the first element with the specified attribute, and maybe you want the second or the third one. (There is a workaround for that problem, keep on reading.) Open link.htm in your favorite text editor and change the text to this, and save the file:
1

<a href="clicked.htm" id="click-me">click me</a>

Refresh the page in the browser to make sure the latest version of link.htm is loaded:
1 2

browser.refresh => []

Link

85

ID and String
If you know the entire id:
1 2 3 4 5 6 7 8

browser.a(:id => "click-me").flash => 10 browser.a(:id => "click-me").click => [] browser.back => ""

ID and Regular Expression


Sometimes ids on a page are automatically generated by the framework developers use, so ids are different every time a page is opened. Usually the portion of id stays the same. For example, it changes from user007 to user42 to user123. It is obvious that user part of the id is the same every time, so you can use that. If our example, we will use /click/.
1 2 3 4 5 6 7 8

browser.a(:id => /click/).flash => 10 browser.a(:id => /click/).click => [] browser.back => ""

Name
Another attribute that almost all HTML elements can have is name. It is not supposed to be unique on the page. It is very common that elements that are somehow related on the page have the same name. Change link.htm to this, and reload the page in the browser:
1 2 3 4

<a href="clicked.htm" name="click-me">click me</a> browser.refresh => []

Link

86

Name and String


If you know the entire name:
1 2 3 4 5 6 7 8

browser.a(:name => "click-me").flash => 10 browser.a(:name => "click-me").click => [] browser.back => ""

Name and Regular expression


If you know the portion of name:
1 2 3 4 5 6 7 8

browser.a(:name => /click/).flash => 10 browser.a(:name => /click/).click => [] browser.back => ""

Class
It is also very common for an HTML element to have a class attribute. Change link.htm to this, and reload the page in the browser:
1 2 3 4

<a href="clicked.htm" class="click-me">click me</a> browser.refresh => []

Class and String


If you know the entire class:

Link

87

1 2 3 4 5 6 7 8

browser.a(:class => "click-me").flash => 10 browser.a(:class => "click-me").click => [] browser.back => ""

Class and Regular Expression


If you know the portion of class:
1 2 3 4 5 6 7 8

browser.a(:class => /click/).flash => 10 browser.a(:class => /click/).click => [] browser.back => ""

Title
It is also very common for an HTML element to have a title attribute. Change link.htm to this, save the file and reload the page in the browser:
1 2 3 4

<a href="clicked.htm" title="click me">click me</a> browser.refresh => []

Title and String


If you know the entire title:

Link

88

1 2 3 4 5 6 7 8

browser.a(:title => "click me").flash => 10 browser.a(:title => "click me").click => [] browser.back => ""

Title and Regular Expression


If you know the portion of title:
1 2 3 4 5 6 7 8

browser.a(:title => /click/).flash => 10 browser.a(:title => /click/).click => [] browser.back => ""

Index
Explicit Index
Note: watir and watir-webdriver use zero-based indexing, safariwatir uses one-based indexing. If the link does not have any attributes that would differentiate it from the other links on the page, but you know the links position on the page, you could use its index. In this example, it is the first link.
1 2 3 4 5 6 7 8

browser.a(:index => 0).flash => 10 browser.a(:index => 0).click => [] browser.back => ""

Link

89

Do you see anything strange in the above code? Take a look. I will wait. Maybe you have noticed that this is the first time we did not use a string (double quotes around the text, remember?) or a regular expression (slashes around the text). We have used just the number one. Such numbers are called integers. Watir uses integers only with index. Please note that watir and watir-webdriver gems counts from 0 (0, 1, 2). That is called zero-based indexing. Safariwatir counts from 1 (1, 2, 3). That is called one-based indexing. (Watir gem used one-based indexing until versinon 2.0.) It is usual in programming that the first element is the number zero (hence zero-based indexing).

Implicit Index
This will do the same thing.
1 2 3 4 5 6 7 8

browser.a.flash => 10 browser.a.click => [] browser.back => ""

So, if you do not provide any arguments to link method, it will just click the first link it finds. It is very useful. It is time for and example. If you know that the link is the first (or even the only) link inside a specific div:
1 2 3

<div id="42"> <a href="clicked.htm">click me</a> </div>

Save the above HTML as link.htm, and reload the page in the browser:
1 2

browser.refresh => []

Then try this:

Link

90

1 2 3 4 5 6 7 8

browser.div(:id => "42").link.flash => 10 browser.div(:id => "42").link.click => [] browser.back => ""

After
Note: watir-webdriver does not support accessing page elements via after. Sometimes the only way to identify the element is to say that it should be after another element. Take a look at this example:
1 2 3

<a href="clicked.htm">click me</a> <a href="clicked.htm" id="click-me">click me</a> <a href="clicked.htm">click me</a>

Save the above HTML as link.htm, and reload the page in the browser:
1 2

browser.refresh => []

This will flash the first link, but we want to flash the third one:
1

browser.a(:href => /click/).flash

One of the ways you could do it is, but looks like watir-webdriver does not support after:
1 2 3 4 5

browser.a(:after? => browser.a(:id => "click-me")).flash TypeError: expected one of [String, Regexp], got #<Watir::Anchor:0x3308eea0e6878cb6 located=false selector={:id=>"click-me", :tag_name=>"a"}>:Watir::Anchor ...

We told Watir that we want to click a link after a div that has id attribute set to click-me. I rarely use it, but there are times when it is really handy. Do you see something strange in the above code? This is the first time we have used a page element as the second parameter (instead of string, regular expression or integer).

Link

91

HTML
Note: watir-webdriver does not support accessing page elements via html. If the link you want to access does not have any usual attributes that could uniquely identify it, Watir can handle that too. For example, you need to click the second link:
1 2

<a href="clicked.htm" onclick="new Ajax.Request('007')">click me</a> <a href="clicked.htm" onclick="new Ajax.Request('42')">click me</a>

One of the really elegant ways to do it is by using html:


1

browser.a(:html => /007/).click

In above example, we have used a regular expression as the second parameter, but I am sure you have already gotten used to them. I am also sure you are already convinced that regular expressions are very useful.

CSS
Note: watir-webdriver does not support accessing page elements via css. CSS selectors are a pretty new addition to Watir, but a powerful one. For example, if you have a link:
1

<a href="clicked.htm" id="click-me">click me</a>

you could click it with


1

browser.a(:css => "a").flash

or, if you prefer to be more explicit:


1

browser.a(:css => "[id=click-me]").click

This is just one example. There will be entire chapter on CSS selectors.

Link

92

XPath
XPath was not in Watir from the beginning. It was added by Angrez Singh. He also created Watirs Firefox driver. Aidy Lewis moved Watirs XPath implementation from REXML to Nokogiri, and now it is faster. XPath is really powerful. Most times you can just use html, but if it does not solve the problem, try XPath.

XPath
If you have a link:
1

<a href="clicked.htm" id="click-me">click me</a>

You could click it with:


1

browser.a(:xpath => "//a").click

Or, if you would like to be more explicit:


1

browser.a(:xpath => "//a[@id='click-me']").click

Element_by_xpath
Note: watir gem does not support flash with element_by_xpath. Another way, especially useful if the element you are trying to access is not supported by Watir:
1

browser.element_by_xpath("//a").click

Or, the more explicit way:


1

browser.element_by_xpath("//a[@id='click-me']").click

Frames
Note: note tested. At the moment, you can use XPath to access elements located in a frame, but you can not use XPath to access the frame itself. In another words, this would work:

Link

93

1 2

browser.frame(:name => "one").link( :xpath => "//a[@href='clicked.htm']/").click

but this would not:


1

browser.frame(:xpath => "//frame[@name='one']/")

There will be entire chapter on XPath, so I will not go into a lot of detail here.

Multiple Attributes
Note: watir and watir-webdriver use zero-based indexing, safariwatir uses one-based indexing. Accessing an element using multiple attributes was not in Watir from the start. This is a killer feature, as you will see. For example, if you have two completely identical links on the same page:
1 2

<a href="clicked.htm">click me</a> <a href="clicked.htm">click me</a>

and you want to click the second one, you could do it like this:
1

browser.a(:text => "click me", :index => 1).click

This is just one example. There will be entire chapter on multiple attributes.

Collection
You can even do stuff with all elements of a particular kind on a page. For example, if you have a page that looks like this:
1 2

<a href="clicked.htm">click me</a> <a href="clicked.htm">click me</a>

and you would want to display text of all links from the page, this will do it:
1 2 3

browser.as.each do |a| puts a.text end

The output should look like this:


1 2

click me click me

This is just one example. There will be entire chapter on collections.

Img
You do not need internet access if you want to follow examples in this chapter. All examples in this chapter are tried on Mac OS 10.7.2, Firefox 8.0.1 Ruby 1.9.3p0, RubyGems 1.8.12 and watir-webdriver 0.3.9. Did you read Link chapter? If you did not, please read it first. I explained a lot of basics there. If you did read it, good job. Continue with the good work.
<img> tag represents image on the HTML page. Its HTML can look like this:
1

<img src="click-me.png">

You can access the image with one of the following:


1 2

browser.img(how, what) browser.image(how, what)

The how part can be (alphabetically): after?, alt, class, css, html, id, index, name, src, title, xpath and multiple attributes. To make sure you could do the exercises from this chapter even without internet access, create a simple HTML file with only one image in it. Open your favorite text editor, enter the following line in it and save it as img.htm:
1 2

<img id="click-me" src="red.png" onclick="document.getElementById('click-me').src='green.png';">

The onclick part makes sure the image changes when clicked, so you can see if the code you are trying out actually works. Open IRB, require watir-webdriver, open the browser and open img.htm. If you do not know how to do that, please read Link chapter. I have explained it there. Since I have also gone into great detail there how to access links, I will assume that you are familiar with all that stuff, and here I will just talk about things that are different for images. Take a look at Img table in Reference chapter for more examples.

Src
All images have src attribute, and you can use it to access the image. If you know the entire value of src attribute, use string to click it: 94

Img

95

browser.img(:src => "red.png").click

If you know the portion of value of src attribute, use regular expression to click it:
1

browser.img(:src => /red/).click

Alt
It is very common for an image element to have alt attribute. Change img.htm to this, save the file and reload the page in the browser:
1 2

<img id="click-me" src="red.png" alt="red image" onclick="document.getElementById('click-me').src='red.png';">

If you know the entire value of alt attribute, use string to click it:
1

browser.img(:alt => "red image").click

If you know the portion of value of alt attribute, use regular expression to click it:
1

browser.img(:alt => /red/).click

Button
Did you read Link chapter? If you did not, please read it first. I explained a lot of basics there. If you did read it, good job. Continue with the good work. Buttons HTML can look like any of the following:
1 2 3 4 5

<button> <input type="button"> <input type="image"> <input type="reset"> <input type="submit">

The most trouble people have with <input type="image">. It looks like an image, but Watir sees it as a button. You can access the button with:
1

browser.button(how, what)

The how part can be (alphabetically): after?, alt*, class, css, html, id, index, name, src*, text, title, xpath and multiple attributes. * only for <input type="image"> Since I have gone into great detail there how to access links in the Link chapter and how to access images in Img chapter, I will assume that you are familiar with all that stuff, and here I will just talk about things that are different for buttons. Take a look at Button table in Reference chapter for more examples.

96

Checkbox
You do not need internet access if you want to follow examples in this chapter. All examples in this chapter are tried on Mac OS 10.7.2, Firefox 8.0.1 Ruby 1.9.3p0, RubyGems 1.8.12 and watir-webdriver 0.3.9. Did you read Link chapter? If you did not, please read it first. I explained a lot of basics there. If you did read it, good job. Continue with the good work. Checkboxs HTML can look like this:
1

<input type="checkbox">

You can access the it with:


1

browser.checkbox(how, what)

The how part can be (alphabetically): after?, class, css, html, id, index, name, title, xpath and multiple attributes. Since I have gone into great detail there how to access links in the Link chapter, I will assume that you are familiar with all that stuff, and here I will just talk about things that are different for checkboxes. Take a look at Checkbox table in Reference chapter for more examples. Create a simple HTML file with only one checkbox in it. Open your favorite text editor, enter the following line in it and save it as checkbox.htm:
1

<input type="checkbox" id="click-me">

You can click, set or clear a checkbox.

Click
Clicking the checkbox will change its state. If it was checked, it will become unchecked and vice versa.
1

browser.checkbox(:id => "click-me").click

Set
If you want to make sure checkbox is checked, you can use set:
1

browser.checkbox(:id => "click-me").set

97

Checkbox

98

Clear
If you want to make sure checkbox is unchecked, you can use clear:
1

browser.checkbox(:id => "click-me").clear

Radio
You do not need internet access if you want to follow examples in this chapter. All examples in this chapter are tried on Mac OS 10.7.2, Firefox 8.0.1 Ruby 1.9.3p0, RubyGems 1.8.12 and watir-webdriver 0.3.9. Did you read Link chapter? If you did not, please read it first. I explained a lot of basics there. If you did read it, good job. Continue with the good work. Radio buttons HTML can look like this:
1

<input type="radio">

You can access the it with:


1

browser.radio(how, what)

The how part can be (alphabetically): after?, class, css, html, id, index, name, title, xpath and multiple attributes. Since I have gone into great detail there how to access links in the Link chapter, I will assume that you are familiar with all that stuff, and here I will just talk about things that are different for radio buttons. Take a look at Radio table in Reference chapter for more examples. Create a simple HTML file with only one radio button in it. Open your favorite text editor, enter the following line in it and save it as radio.htm:
1

<input type="radio" id="click-me">

You can click, set or clear a radio button.

Click
Clicking the radio button will select it.
1

browser.radio(:id => "click-me").click

Set
Setting the radio button does the exactly same thing as click, selects the radio button:
1

browser.radio(:id => "click-me").set

99

Radio

100

Clear
If you want to deselect radio button, use clear:
1

browser.radio(:id => "click-me").clear

I am getting this error message:


1 2

NoMethodError: undefined method `clear' for #<Watir::Radio:0x00000100f8bb18>

Looks like watir-webdriver gem does not support clear with radio buttons. I am pretty sure watir gem supports it.

Collections
You can even do stuff with all elements of a particular kind on a page. If you want to display href attributes of all links in the page, this will do it:
1 2 3

browser.as.each do |link| puts link.href end

101

Nested Elements
Simple Nesting
Sometimes the only way to uniquely identify a link is to specify one or more of its parent elements. How would you click the second link in this example?
1 2 3 4 5 6

<div id="one"> <a href="clicked.htm">click me</a> </div> <div id="two"> <a href="clicked.htm">click me</a> </div>

This will click on the first link, but we want to click on the second one:
1

browser.a(:text => "click me").click

This will work, but it is really fragile:


1

browser.a(:index => 1).click

If in further development a link (or more) is added between the two links we have so far, the code above will click on whatever link was the second, and that is not what we want. Lets make it less fragile. We know that the second link is a child element of a div with an id attribute. This is the solution to the problem:
1

browser.div(:id => "two").link(:text => "click me").click

Isnt that just so elegant?! Read it. First there is a browser, inside it there is the div, and inside the div is our link. The above solution is not the only one. This will work too:
1

browser.div(:id => "two").link(:index => 0).click

This time we told Watir that we want it to click the first link in a specific div. There are endless options how to click on an element on a page, and this book will try to teach you all of them. 102

Nested Elements

103

More nesting
If for some reason you want to be very specific about where the element is located in the page, Watir can handle that too. For example, if you had something like this:
1 2 3 4 5

<div id="one"> <div id="two"> <a href="clicked.htm">click me</a> </div> </div>

You could click the link with:


1

browser.div(:id => "one").div(:id => "two").link(:text => "click me").click

So, there is a browser, then a div, another div and the link we are looking for. The nesting can go as deep as you like.

About Watir, Extended Version


If you are reading this chapter, then you really like Watir. In that case, you deserve to know every little detail about it. Read on. I was thinking about open source, and I have asked myself: So, what is an open source project, after all? After a lot of thinking (and a few beers) I think I know the answer. Open source project is code, documentation and community. So simple.

History
Code
Watir is fairly old project. According to github.com, the first commit containing Ruby code was made in October 2003. That is almost 8 years ago. In internet years, it is almost a century. I thought the code was first in SVN repository at RubyForge. Bret commented on the early draft of the book: Actually started in CVS, then was ported to SVN and then Git. Nobody was using SVN in Oct 2003. From RubyForge it moved to SVN repository at OpenQA and now is git repository at GitHub. License it an important part of every open source project. The very first commit had the license, and as far as I can tell, it was BSD, although it was not explicitly stated. In January 2005, when the first version of Watir, 1.0.1, was released as a zip file (according to RubyForge) we had some code. Zip file? Really?! Really. RubyGems did not exist back then. And you thought I was joking when I sad it is almost a century in internet years. Watir 1.4.1 (August 2005) was a big success, downloaded almost 45k times. That was also the first version that was available as both a gem and exe file. Watir is 23rd on the list of top RubyForge downloads, if that means anything these days. Bret commented on the early draft of the book: Back then Watir was one of the top 5 downloads on Rubyforge. That was before rails. Watir gem is now hosted at RubyGems.org, all gems have over 55k downloads, and the current version (1.8.1) over 2k downloads. Watir gem is not the only gem included in the Watir project, there
http://en.wikipedia.org/wiki/Open_source https://github.com/bret/watir/commit/aca359922c6b3db2ec8329ea0b26c186b00e0bb5 http://svn.openqa.org/fisheye/browse/watir https://github.com/bret/watir http://rubyforge.org/frs/?group_id=104&release_id=41300 http://rubyforge.org/top/toplist.php?type=downloads https://rubygems.org/gems/watir

104

About Watir, Extended Version

105

is also firewatir, commonwatir, safariwatir, celerity, watir-webdriver and the youngest one, operawatir. There used to be chromewatir gem too, but it is replaced with watir-webdriver. There are a few frameworks that simplify writing Watir code: taza, watircraft, watirloo, and watirsplash, but only the last one is updated. There is even one fork of Watir project, Vapir. Ethan (he never said his last name) created a fork in May 2010.

Documentation
The first significant documentation I could find in repository was made by Bret in April 2004. When I started using Watir (March 2005) it already had pretty good documentation. It had user guide written by Jonathan Kohl and RDoc documentation. RDoc documentation is now hosted at RubyDoc.info that auto-generates it with every new release. Internet Archive Wayback Machine says we had a web site since February 2005, and around August 2009 we moved the site to http://watir.com/. Paul Rogers registered watir.com domain in April 2005 (according to whois.net). Maybe watir.org would be better for open source project, but it was taken. Alister Scott did a great job with the web site. The plan is that all you need to know will be there, but not overwhelming like wiki. With time we were just adding more and more stuff there, maybe it is the time for a cleanup. I am also very proud that we do not have www in front of our domain at our web site. I even tried going to www.watir.com and it redirected to watir.com. I was so proud. If you do not know what I am talking about, take a look at http://no-www.org/. Wiki is an important part of our documentation. We had it in early stages of the project. The first web site had a link to Web Testing with Ruby wiki (still live, but obsolete, from February
https://rubygems.org/gems/firewatir https://rubygems.org/gems/safariwatir https://rubygems.org/gems/commonwatir https://rubygems.org/gems/celerity https://rubygems.org/gems/watir-webdriver https://rubygems.org/gems/operawatir https://rubygems.org/gems/chromewatir https://rubygems.org/gems/taza https://github.com/bret/watircraft/ https://rubygems.org/gems/watirloo https://rubygems.org/gems/watirsplash http://vapir.org/ https://github.com/bret/watir/commit/099d95c6189e1cec1bf010ead639f29191195ed4 http://replay.waybackmachine.org/20050115054556/http://wtr.rubyforge.org/watir_user_guide.html http://rubydoc.info/gems/watir http://replay.waybackmachine.org/20050206120226/http://wtr.rubyforge.org/ http://waybackmachine.org/20050901000000*/http://wtr.rubyforge.org http://watirpodcast.com/26-alister-scott-on-watir-com/ http://www.whois.net/whois/watir.com http://www.whois.net/whois/watir.org http://www.clabs.org/wtr/

About Watir, Extended Version

106

2004). I do not remember there was anything useful at the wiki while it was at RubyForge. We started working on the wiki when we moved to OpenQA. Alister did a lot of work on it, and I have moved the user guide there and renamed it to tutorial. We have a lot of documentation there at the moment, but it needs some love. A lot of stuff should be updated. We have a bug tracker at OpenQA. Previously it was at RubyForge, for firewatir at Google Code, and for safariwatir at GitHub. All of them are now at OpenQA. Since October 2007 we have Google Custom Search that searches all Watir related sites but nothing else. It was usually embedded or linked from our web page.

Community
Wtr-general mailing list exists from October 2003, about the same time when the first commits were made to the code, but way back then the list was not about Watir as we know it today. It was about a larger topic, web testing in Ruby. We moved wtr-general from RubyForge to OpenQA, and from there to Google Groups. Wtr-general says Watir project was stared by Chris Morris, Johnatan Kohl, Bret Pettichord and Paul Rogers. We also have wtr-development mailing list at RubyForge, and it is still there. One of the rare things we did not move around. We have even managed to make Jira bug tracker send mail to wtrdevelopment when any ticket is created or changed. I think it makes the developers more aware of the problems people have. We had wtr-core group at RubyForge for a while, but that is not active any more. I see spam at other lists from time to time, but I think we managed to keep our lists clean, polite and productive. In the past 2,5 years I have been pushing Stack Overflow as the place to get Watir support, but had little luck, up until recently. I think in the last few weeks or months, almost every day a new question is posted there. Some people also started participating, and I am really happy for that. We have also tried to create a separate Watir Stack Exchange site, but that failed. I think it was good that we have tried, at least we created some buzz around Stack Overflow/Exchange. There is 256
http://web.archive.org/20040415000000*/http://www.clabs.org/wtr/ http://wiki.openqa.org/display/WTR/Project+Home http://wiki.openqa.org/display/WTR/Tutorial http://jira.openqa.org/browse/WTR http://bit.ly/watirsearch http://rubyforge.org/pipermail/wtr-general/ http://groups.google.com/group/watir-general/ http://rubyforge.org/pipermail/wtr-development/ http://rubyforge.org/pipermail/wtr-core/ http://stackoverflow.com/tags/watir http://watirpodcast.com/35-zeljko-filipin-on-watir-stack-exchange-site/

About Watir, Extended Version

107

questions tagged Watir there. (Nice, round number.) We finally have enough active users to get the questions answered. I have started recording Watir podcast in May 2008, and that makes us one of the rare projects that has its own podcast. It is hard to tell how much impact the podcast has. I like to think that it gives us a human face (well, human voice at least). So far I have recorded 44 episodes. I started using podtrac (for tracking how many times a podcast is downloaded) in December 2009 and since then we had about 300-400 downloads per episode. Episode #26 with Alister (we were talking about moving our web site to watir.com) is interesting. I am not sure why, but it has about three times more unique and total downloads than any other show. I guess I will have to have him on the show more frequently. I am not sure what I will do with the podcast in the future. My current plan is to reduce the size of the episodes to 5-15 minutes. Also, it is interesting that old episodes are still downloaded, even the very first one. One of the first real marketing adventures was free ad at stackoverflow.com. It is hard to measure how successful it was. We did it two times (January 2010 and June 2010). I could not find any numbers on how successful the ad was, but additional exposure could not hurt. The third round is up right now, but I did not have the time to create an ad yet. We also have #watir IRC channel at freenode, but I never got used to hanging out there. When I have the time, nobody is there. When I have to work I usually shut down mail, messengers and stuff like that to reduce distractions. People have been blogging about Watir. We have a list of people that mostly blog about Watir at our web site. I remember seeing articles about Watir in print magazines, I wrote one for a local computer magazine. I am sure I am not the only one that speaks about Watir at local conferences and meet-ups. We even organized a few conferences specifically about Watir: AWTA in Austin, Texas (2000-2009); Watir Day in San Francisco, California (2011).
http://watirpodcast.com/ http://watirpodcast.com/26-alister-scott-on-watir-com/ http://meta.stackoverflow.com/questions/31913/open-source-advertising-sidebar-1h-2010/38414#38414 http://meta.stackoverflow.com/questions/53346/open-source-advertising-sidebar-2h-2010/53544#53544 http://meta.stackoverflow.com/questions/74983/open-source-advertising-sidebar-1h-2011 http://wiki.openqa.org/display/WTR/The+IRC+Channel http://watir.com/blogs/ http://www.vidilab.com/digitalvidi/arhiva/vidi158/index.php http://zeljkofilipin.com/category/self-education/events/ http://awta.wikispaces.com/AWTA http://watir.com/watir-day/

About Watir, Extended Version

108

Today
Code
If you are just starting using Watir, I would suggest that you start with watir-webdriver gem. I think it is the future of Watir project. Some time in the future we will probably no longer develop other gems, just watir-webdriver. It will probably not happen soon (in the next few months), but it might be sooner than you expect. If you are already using Watir, you can continue to use the gem(s) you have used so far. The only exception is firewatir gem. It can not drive Firefox 4. Good new is that watir-webdriver gem can. So, if you have to drive Firefox 4, start moving your tests to watir-webdriver. If you are still using Firefox 3, you can use either firewatir or watir-webdriver. Jari Bakken, creator of watir-webdriver gem, also created celerity gem. If you have a need for headless browser driver, take a look at celerity. There is also headless driver in watir-webdriver, but I did not have the time to play with it so far, so I could not recommend it. My guess is that it is pretty usable, but that is only a guess. Andreas Tolf Tolfsen, lead developer of operawatir gem says Opera should be supported via watirwebdriver gem in the near future. Until then, if you need to drive Opera, use operawatir, but have in mind that you might need to move to watir-webdriver soon. Safariwatir was created by Dave Hoover in July 2006. Tom Copeland (of RubyForge fame) took over the project in October 2009. Safariwatir was never really popular, but it was there, waiting for somebody to take care of it. If you need to drive Safari on Mac (safariwatir does not work on Windows) give it a try. There is a rumor that watir-webdriver will be able to drive Safari in the future.

Documentation
There is only one thing going on regarding documentation of Watir project. This book. If you think it is a good idea to write a book about Watir, please let me know. Sometimes I am wondering if it was a good idea to start writing the book.

Community
We have created watir account at twitter.com (June 2009). It is pretty active. Alister and I post there when there is something significant, like new releases or blog posts. I also used it to link to new Stack Overflow questions, but not any more. It has 242 followers at the moment. We used to display tweets with #watir hash tag at the Watir web site, but it got flooded with a lot of posts in
https://twitter.com/#!/watir https://twitter.com/#!/search/%23watir

About Watir, Extended Version

109

some strange language. At the moment, all posts containing @watir will appear in the sidebar of watir.com. We had a LinkedIn group for some time (April 2008) with 554 members, but just recently I started posting relevant Watir links there. Usually the same stuff as Twitter account. Since all the cool kids are at Facebook, so are we. I have created the account a few months ago but I did not have the time to start using it since this February (2011). I wanted facebook.com/watir url, but it is taken, so I took facebook.com/watirproject. Usually the same stuff gets posted there as all other social media we use. 82 likes so far. I was hoping we would get some interaction at Twitter, LinkedIn and Facebook, but it is pretty quiet so far. We started receiving donations at watir.com via PayPal since 2009 and via Pledgie since at least January 2010. Andreas suggested we start using Flattr in March 2011. We have received about $1000 in donations.

Future
Code
What would I like to see happening in the (near) future, regarding Watir code, you ask? In no particular order: Watirspec is the test suite for all Watir implementations. Each gem has a score and you can see what fails and what works. Watir-webdriver is the only driver, and it can drive all popular browsers on all popular platforms. One (or more) Watir frameworks that is up to date. Watir participates in Google Summer of Code. I hope we will raise some money so we could fund further development.

Documentation
I guess every project needs (more) books, updated web site and wiki, and in case of Watir, updated RDoc would be nice too.
https://twitter.com/#!/search/%40watir http://www.linkedin.com/groups?about=&gid=88535&trk=anet_ug_grppro https://www.facebook.com/watirproject http://pledgie.com/campaigns/2982 https://flattr.com/thing/141470/Watir http://code.google.com/soc/

About Watir, Extended Version

110

Community
Watir community is a topic I think a lot. There a few things I think we should do in the near future: Joining Software Freedom Conservancy and moving all of our stuff there (domain, money, trademark). We regularly create Stack Overflow ads, when ever the have a new round. It would be great if more people were writing about Watir, especially on their blogs. I think meeting regularly (at least once a year) is really important. We could meet at conferences that attract Watir users anyway, like Selenium Conference (may be renamed to Browser Automation Conference in the future). Organizing our own conferences and meetups is also important. Viaqa Watir Day in Zagreb, Croatia will be in June 2011. It would be great if I could get some funding. It would really help me with working on documentation, podcast, this book

http://sfconservancy.org/

Das könnte Ihnen auch gefallen