TrySelenium.org in Watir-WebDriver

Jason Huggins put out a call for some example scripts to tweet some stuff using Selenium.
Whilst I don’t agree with this being done through the Twitter GUI (there’s an API for this), being a Watir core team member and ruby guy, I thought I would use Watir-WebDriver.

My resulting script is:

require 'rubygems'
require 'highline/import'
require 'watir-webdriver'

begin
 username = ask("What is your twitter username?")
 password = ask("and your password?") { |q| q.echo = false }
 browser=  Watir::Browser.start "twitter.com", :firefox
 browser.span(:text => "Sign in").click
 browser.text_field(:id => "username").set username
 browser.text_field(:id => "password").set password
 browser.button(:id => "signin_submit").click
 raise "Could not log into Twitter: either your password is wrong or a CAPTCHA is needed."   if browser.url.include? "sessions"
 1.times do |attempt|
 browser.text_field(:class => "twitter-anywhere-tweet-box-editor").when_present.set "#SeConf is awesome x #{attempt}! http://tryselenium.org @Watir-WebDriver is even more awesome!"
 browser.link(:class => "tweet-button button").when_present.click
 browser.goto "twitter.com"
 end
ensure
 browser.close
end

And the resulting tweet:

Thanks for Jari Bakken for discussing this with me.

Watir Day 2011 Tickets now available for $50

Tickets to Watir Day 2011 on Sunday 3rd April 2011 in San Francisco are now on sale for $50 each.

Don’t forget about the sponsorship deal where your employer or company can be a sponsor for just $175 and receive four free tickets. This sponsorship can be purchased through the main ticket page too.

All proceeds from the event go to cover costs and to support the Watir project. And to cover the cost of your special Watir Day t-shirt (include your t-shirt size when you register).

More information about Watir Day can be found here.

Your automated acceptance tests needn’t be written in the same language as your system being tested

When selecting which tool to implement for business facing automated acceptance tests, I’ve often heard that it must use the same programming language as the system under test. Whilst this can sometimes work well, often it is better to choose a tool in another language that will ulimately deliver you better success as it can be adopted more passionately. Here are some of the reasons on why I think so.

The simplicity of some other languages mean it’s easier for less technical testers to understand them

Let me show you an example that compares the same test written in C# as in Ruby.

C# WebDriver Example – Inspired by David Burns

using OpenQA.Selenium;
using OpenQA.Selenium.IE;
 
using NUnit.Framework;
 
namespace Selenium.Two.DotNetExample
{
    [TestFixture]
    public class Test_Google
    {
	    IWebDriver driver;
	     
	    [SetUp]
	    public void Setup()
	    {
		    driver = new InternetExplorerDriver();
	    }
	    
	    [TearDown]
	    public void Teardown()
	    {
		    driver.Quit();
	    }
    		
        [Test]
        public void TestSearchGoogleForTheAutomatedTester()
	    {
	        //Navigate to the site
            driver.Navigate().GoToUrl("http://www.google.com");
            //Find the Element and create an object so we can use it
            IWebElement queryBox = driver.FindElement(By.Name("q"));
            //Work with the Element that's on the page
            queryBox.SendKeys("Watir");
			queryBox.SendKeys(Keys.ArrowDown);
            queryBox.Submit();
            //Check that the Title is what we are expecting
            Assert.True(driver.Title.IndexOf("Watir - Google Search") > -1);
        }
    }
}

Ruby Watir Example – written by me

require 'watir-webdriver' #watir, celerity, firewatir
require "test/unit"
class GoogleTest < Test::Unit::TestCase
  def test_google
    b =Watir::Browser.start "www.google.com"
    b.text_field(:name => "q").set "watir"
    b.button(:name, "btnG").click
    assert_equal("Watir - Google Search", b.title)
    b.close
  end
end

I am slightly biased, but I think the ruby example is neater and easier to read, especially to someone with a less technical background. Sure, a C# developer might baulk at this premise, but for most people who don’t know C#, I imagine it’s the case.

Often times developers like learning another programming language to add to their experience
When I’ve been working on automated tests in ruby, I’ve often seen a strong interest in developers wanting to learn ruby and the automated testing framework, as it’s common for developers to specialize in a language (Java or .NET) and then focus solely on that. Don’t get me wrong, this isn’t always the case, but it happens more than you think.

Testers can embrace simpler programming languages such as ruby, and can become the “experts” in that domain

I’ve seen testers pick up a programming language like ruby and polish their skills in it, which helps their morale by becoming experts in it. If the automated acceptance tests were written in the same language as the developers, yes this brings benefits, but the testers might not become experts as quickly, and may lack ownership of the tests.

Automated acceptance test tools provide different mileage across languages
Some languages have particularly good tools for defining business facing automated tests, for example, Cucumber’s support for ruby is superb, whereas support for C# equivalents such as Cuke4Nuke and SpecFlow isn’t quite as good. RSpec is another example of a tool that is awesome in its domain.

Summary

I know this post has ended up sounding like a pro-ruby rant, but it is :) I am trying to point out that there’s simpler, easier languages for testers to pick up than your Javas and C-Sharps. The ruby and python programming languages are two great examples, and as I mentioned, it seems that ruby is quickly becoming the testing language of choice, because of its simplicity, and the wide variety of testing related gems available. Ruby also makes it extremely easy to bootstrap configurations across different environments, and its lack of licensing requirements or need for an IDE make it an excellent choice for testers.

One of the reasons that the Selenium project is so successful is that it supports various programming languages (and browsers), which appeals to the majority of developers who can use their established skills, but it’s common to meet testers who are passionate about Watir, because of its simplicity and focus: a tool for testers by testers. It is for this reason I believe Ruby & Watir & Cucumber is a winning combination, and will bring about many success stories for agile testing teams in the future.

Watir Day is happening in San Francisco on Sunday April 3rd 2011

Just to let everyone know Watir day is happening in San Francisco on Sunday April 3rd, 2011. It’s the day before the Selenium Conference officially starts, to which most of the core Watir team will be attending.

I am hoping to share some of the stuff I have been doing with Watir, Watir-WebDriver, Selenium & Cucumber.

We’re hoping the Watir day will be less formal than the conference, and this includes hacking, so please bring along your laptop.

Hope to meet you there! http://watir.com/watir-day/

A new blog for the new year: Testing with Vision

I’ve recently started a new blog, co-editing it with Bret Pettichord from Austin, Texas. I was a follower of Bret’s writing on his testing hotlist update blog for some time, but since he hadn’t updated it in 18 months, I jumped at the opportunity when he recently asked me to co-edit a new blog titled “Testing with Vision“.

I set it all up on wordpress.com, because it’s a rock solid and aesthetic blogging platform for minimal cost and we’ve begun publishing posts on Cucumber and Watir. We are hoping to present together at the upcoming Selenium Conference in San Francisco in April this year.

In the meantime, please check it out and subscribe.

Watir-WebDriver: A detailed introduction

Update: 22 August 2011: Please see: watirwebdriver.com for a detailed guide to Watir-WebDriver

Update: 22 July 2011: I have updated quite a number of things that have changed since the earlier releases

Watir-WebDriver is a really great tool; Jari Bakken‘s done a really good job of it. There’s not a huge amount on the web about it, how to get it up and running and use it. I’m aiming to fix that here.

For those who don’t know what Watir-WebDriver is, it’s basically a nice Watir (ruby) implementation on WebDriver, so it gives you four browsers (three real, one headless) using one neat API, out of the box. The thing I like about it is you don’t need to use JRuby (like Celerity), which means it plays nice with Cucumber (although Cucumber does work under JRuby).

I’ve written about how Watir, WebDriver and Selenium all fit together before, so this post aims to be a lot more hands-on.

Getting Watir-WebDriver Running

There are essentially two components you need: the Watir-WebDriver ruby gem, and the remote WebDriver server. The remote WebDriver server is only needed if you want to run your tests in headless mode without a real browser (or want to use Opera). You obviously need ruby first but I won’t detail that here. You can find info about ruby versions etc. at watir.com. If you’re on Mac or Linux, I strongly suggest using RVM and bundler.

The Watir-WebDriver ruby gem

It’s a simple matter of opening a command prompt and typing:

  • gem install watir-webdriver (windows); or
  • sudo gem install watir-webdriver (osx or linux – better to use RVM and bundler)

The remote WebDriver Server

This is the slightly tricky part. This is so that WebDriver can run headless without a real browser, and isn’t needed for real browser support (bar Opera). The quickest easiest way to get up and running is to download this java jar file, open a command prompt where you have saved it, and run:

java -jar selenium-server-standalone-2.0b1.jar

You can also specify the startup and max memory allocated, which is handy when running large test suites.

java -Xms1024M -Xmx2048M -jar selenium-server-standalone-2.0a7.jar

You need to have this java server running whenever using WebDriver, but it’s easy enough to bootstrap it.

Update: Jari has pointed out you can run the server programmatically which is even better:

require 'selenium/server'
server = Selenium::Server.new("/path/to/jar", :background => true)
server.start
# run your tests
server.stop

First Impressions

Waiting in Watir-WebDriver doesn’t seem as straightforward as with Watir, probably due to the underlying drivers, but fortunately there’s an inbuilt waiting library to use (also available in Watir 1.6.7+):

  • Watir::Wait.until { ... }: where you can wait for a block to be true
  • object.when_present.set: where you can do something when it’s present
  • object.wait_until_present:; where you just wait until something is present
  • object.wait_while_present:; where you just wait until something disappears

Hello Watir-WebDriver

It seems pertinent to start with a google search example.

Hello Watir-WebDriver in three browsers

These three browsers seem to work very similarly, but obviously Internet Explorer will only run on Microsoft Windows.

require 'rubygems'
require 'watir-webdriver'
b = Watir::Browser.new :chrome
b.goto 'www.google.com'
b.text_field(:name => 'q').set 'Watir-WebDriver'
b.button(:name => 'btnG').click
b.div(:id => 'resultStats').wait_until_present
puts "Displaying page: '#{b.title}' with results: '#{b.div(:id => "resultStats").text}'"
b.close

The only difference for Firefox:

b = Watir::Browser.new :firefox

The only difference for IE:

b = Watir::Browser.new :ie

Hello Watir-WebDriver in Headless (HTML Unit)

I imagine this is the most anticipated feature for Watir users, as it means your tests run much faster, and you can still use ruby (unlike Celerity which uses JRuby). The script is fairly straightforward, you simply specify the hostname for your WebDriver server you started above. You need to specifically enable JavaScript by creating a capabilities profile.

require 'rubygems'
require 'watir-webdriver'
include Selenium
capabilities = WebDriver::Remote::Capabilities.htmlunit(:javascript_enabled => true)
b = Watir::Browser.new(:remote, :url => 'http://127.0.0.1:4444/wd/hub', :desired_capabilities => capabilities)
b = Watir::Browser.new :firefox
b.goto "www.google.com"
b.text_field(:name => "q").set "Watir-WebDriver"
b.button(:name => "btnG").click
b.div(:id => "resultStats").wait_until_present
puts "Displaying page: '#{b.title}' with results: '#{b.div(:id => "resultStats").text}'"
b.close

Sample Timings

As an experiment, I looped the Google Search script above 100 times to measure and compare the execution times.

  • Internet Explorer 8 on Windows 7: 400 seconds
  • Firefox 3.6 on Mac OSX: 277 seconds
  • Headless HTMLUnit on Mac OSX: 269 seconds

Very surprisingly, the headless run wasn’t much quicker at all. This may be due to running the test on Google over the Internet and not a local application.

Caveat Emptor

There are a number of differences between Watir-WebDriver and Watir. The main ones that are important to me are:

Zero based indexing as opposed to 1 based

For example,

In Watir/FireWatir: this finds the first table on a page:

puts b.table(:index => 1).text

But in Watir-WebDriver, it finds the second table on a page.

Attaching to windows
Attaching to new windows (for example pop-ups) has been fairly straightforward in Watir with its attach method, which is missing in Watir-WebDriver. It looks like you can iterate through a collection of windows in Watir-WebDriver using browser.windows, but I haven’t tried this out yet.

Summary

Watir-WebDriver is a very solid testing tool that uses a great browser automation engine (WebDriver) with a clean ruby API (Watir). I believe it will be a popular choice amongst testing teams, particually those using it for ATDD through Cucumber and running it as headless on a continuous integration server.

Further Reading

How to set up Cucumber and Watir on OSX

These are the steps I had to use to get Cucumber and Watir running on OSX. It’s a shame about step 1, it’s a real pain but I don’t know any way around it.

  1. Install Xcode from OSX installation DVD – this takes about 15 minutes
  2. Open a command prompt and use enter the following commands.
  3. sudo gem update --system
  4. sudo gem install rspec --no-rdoc --no-ri
  5. sudo gem install gherkin --no-rdoc --no-ri
  6. sudo gem install cucumber --no-rdoc --no-ri
  7. sudo gem install firewatir --no-rdoc --no-ri

You should be good to go.

Elegantly handling basic browser authentication with Watir

In programming, I find there’s little that compares to the feeling of deleting code; like finding a one or two-line solution that means you can remove a good-sized chunk of code no longer needed.

A fellow ThoughtWorker (who I shall call the Awesome-est Tom™) showed me a solution to handling the basic browser authentication in Internet Explorer, which effectively meant I could delete lines and lines of ruby code that called the AutoIt dll to handle the modal authentication dialog.

Internet Explorer Basic Authentication Dialog

Internet Explorer Basic Authentication Dialog

The code I had was loosely based upon the solutions available on the Watir wiki, all which roughly use the same technique of locating and authenticating the authentication dialog using AutoIt. Because the dialog is modal, the code I had used to run in a separate thread, and this caused me problems with debugging, and I find if I can avoid AutoIt, then my Watir tests run a lot more reliably.

Tom’s Occam’s Razor solution simply embeds the username and password in the URL that usually triggers an authentication dialog.

Instead of using:

Watir::Browser.start "http://yoururl.com"

you use:

Watir::Browser.start "http://username:password@yoururl.com"

This means you don’t see the authentication dialog at all! No more messy AutoIt code. The only tricky part is ensuring that Internet Explorer allows you to do this. Since Internet Explorer 6, this has been disabled by default, but it’s a simple matter of enabling the functionality by setting two registry keys.

This can easily be done running a .reg file you can create (I’ve uploaded mine ‘IESecurityURL.reg’ here), that sets the required values:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE]
"iexplore.exe"=dword:00000000
"explorer.exe"=dword:00000000

You then run this file from the command line: regedit.exe /s IESecurityURL.reg and Robert is your father’s brother.

I’ve updated the wiki with this solution, so hopefully everyone can now use this and avoid the nastiness that is AutoIt :)

Rubular & RubyMine: makes Cucumber easier

I’ve spent the last couple of months establishing Acceptance Test Driven Development on a medium sized software delivery project using Watir & Cucumber.

Cucumber is premised on reading feature files and matching strings to determine what to do, which is done by using regular expressions in step files. This means constant use of ruby regular expressions, and in polishing up on my regular expression skills, I have found rubular incredidly useful. I love the simple layout and the ‘Regex Quick Reference’ at the bottom, just where you need it. It’s very well done.

Rubular: A Ruby regular expression editor and tester

Rubular: A Ruby regular expression editor and tester

The other tool I have found incredibly useful is RubyMine. Up until now, I’ve never really bothered with an IDE for Watir stuff. I’ve mainly stuck to text editors before, but since I have started using Cucumber, I have found the RubyMine tool almost critical, as its support for Cucumber feature files and step definitions is superb. It features click through linking for feature files so you know exactly what step you’re calling, and the debugger is awesome; no more puts statements for me :)

So, if you’re thinking about implementing Cucumber, or using Cucumber but are annoyed with the lack of efficiency in managing a large suite of step definitions, I would thoroughly recommend these two tools. Rubular is free, and I believe RubyMine is about $99, but less if you need multiple licenses. There’s also an Early Access Program where you can use RubyMine for free as long as you’re happy to test it along the way.

Running Watir reliably on a CI machine

I’ve found that Watir generally works well when running under Windows on a Continuous Integration machine (for example, Hudson or TeamCity) but if you use any of the autoit stuff to handle things like security authentication dialogs, it can fail when the machine is locked or not actively logged in.

I’ve found two ways to ensure Watir reliably runs tests without issues.

Run Caffeine to stop the machine locking or screensaver activating

Your Windows sys-admin might not like this one, but caffeine is a tiny executable that’s perfect for ensuring your Windows machine never locks or activates its screensaver, by simulating a keypress every 59 seconds. It’s a matter of installing it and a coffee cup appears in the tray to show you you’re machine is now on caffeine!

Use a command to release any remote desktop sessions to console

Caffeine works well, but if you use remote desktop to control the machine, when you disconnect, the machine will be locked and this will cause problems. What you need tp do is create a batch file, on your desktop say, that releases the RDP connection to console, so it’s ready to run any watir tests. The command you’ll need in the batch file is:

cmd.exe /Q /C "%windir%\System32\tscon.exe 0 /dest:console"

By using the combination of the above items, it’s easy to set up a reliable suite of Watir tests to run on a CI machine that you can easily remote into to see what is running when needed.