Sips of Watir
Hi, I wanted to ask. When you spoke to the SauceLabs employee and they showed you that you could run watir-webdriver tests, did they confirm that they were thinking of supporting watir-webdriver?

No, they did not say one way or the other. 

Getting Help

I am working through Ruby Koans to refresh my memory of what I can do with Ruby.  In about_symbols.rb there is a “THINK ABOUT IT” brainteaser with no given answer.   The puzzle is this: 

Why do we convert the list of symbols to strings, then look for the symbol as a string below?

def test_method_names_become_symbols 
  symbols_as_string = Symbol.all_symbols.map { |x| x.to_s }
  assert_equal true, symbols_as_strings.include? ("test_method_names_become_symbols")
end 

While working through this question, I wondered if this is because String class has the include? method, while Symbol class does not?

Here’s how I get information about Ruby classes and methods when I do not know what exactly is available.

I check for documentation using Ruby index (ri) from the command line:

ri Symbol

The output does not show include? as an instance method, but it has class method all_symbols listed.   Since this is in the code snippet, lets get more information about it:

ri Symbol.all_symbols

Notice that I do not use ri Symbol#all_symbols to get help because ‘#’ is used for instance methods.  To ask about class methods, it appears that you can use either “::” or “.”.  The following yields the same documentation:

ri Symbol::all_symbols

The documentation from the above shows that calling Symbol.all_symbols returns an Array.  I investigate what methods may be useful:

ri Array

This shows that include? is an instance method available to class Array.  In other words, I should be able to skip converting the Symbol array to a string to find a match and do this instead:

def test_method_names_become_symbols 
  Symbol.all_symbols.include? (:test_method_names_become_symbols)
end 

I do not have an answer for why the Ruby Koan snippet used strings instead of looking for the symbol directly, but I’ve found another way to accomplish this task!  

How can I apply this to Watir?  Watir does not have a lot of documentation, but the following return some results (using watir-webdriver-0.3.4)

ri Watir
ri Watir::Browser
ri Watir::Browser#wait
ri Watir::Browser::new

I can also get help when I’m inside the irb.  Start irb and type the following commands:

require 'watir-webdriver'
browser=Watir::Browser.new :firefox
browser.goto ("google.com")

#1. lists all methods available to this instance of the browser.  
browser.methods.sort  

#2. lists methods private to this instance of the browser in sorted order
browser.private_methods.sort 

#3. identifies the instance as Selenium::WebDriver::Driver:0x6b...
browser.driver.inspect 

#4. shows all the methods available to this instance of the driver in sorted order
browser.driver.methods.sort

#5. complains that I need 1 argument
browser.driver.save_screenshot 

#6. look up online documentation for save_screenshot
browser.driver.save_screenshot "/Users/me/bananas"

browser.close

Using a combination of irb (to get dynamic typing information) and online documentation (Watir WebDriver API Documentation and Selenium WebDriver API documentation), I find the missing argument I need to supply.  After #5 above, I refer to the Selenium WebDriver API documentation, click Method List, type in save_screenshot.  This describes the parameter it expects, but it also warns against calling the method because it may be removed in the future!

Summary:  When working with Ruby, take advantage of irb and online API documentation to find missing information!  Ruby index (ri) is another resource, although it is not as complete.

Run Watir Script using Sauce OnDemand

Write once, run everywhere!  This post will explore how you can run a Watir script using Sauce OnDemand.  A Sauce Labs employee first demonstrated this to me on Watir Day in San Francisco. You will need to signup for a FREE account from Sauce Labs to try this at home.

My test platform is WinXP which unfortunately does not run IE9, but I’d like to know if my script runs there (as well as on other browsers that I do not want to install or have access to.)

After I sign up for a free account, navigate to Sauce Lab’s Sauce OnDemand’s Getting Started page.  Set Documentation for Ruby, Selenium version to be WebDriver, and OS to be Windows.  Follow the directions to install selenium-webdriver gem, and grab the sample ruby code to get started.  For sanity check, I followed all the steps and made sure my setup is working properly.

For my test, I want to check if a website’s “All Rights Reserved” text is showing up on every page.  My Cucumber test script looks like this:


Feature: All rights reserved should be visible from different webpages    
   Scenario: Check if I can see "All rights reserved" 
    Given I am on Zazzle Home Page
    Then should read "All rights reserved"

    Given I am on Zazzle Community Forum Page
    Then should read "All rights reserved"

Save this script in c:\CucumberExample\features\ZAllRights.feature

Using the code sample from Sauce OnDemand for reference, but instead of require selenium-webdriver, require watir-webdriver.  Here’s the ruby script:


require 'watir-webdriver'

#replace with your own user name
username = 'myname'
#replace with your own API key
access_key = 'd22222222-b333-444-5555-6666666'

caps_ie8 = {:name=>"Testing in the Sauce Cloud", :platform => "XP", :version => "8", :browserName => "internet explorer"}
caps_ie9 = {:name=>"Testing in the Sauce Cloud", :platform => "VISTA", :version => "9", :browserName => "internet explorer"}
caps_ff7 = {:name=>"Testing in the Sauce Cloud", :platform => "XP", :version => "7", :browserName => "firefox"}
caps_chrome = {:name=>"Testing in the Sauce Cloud", :platform=> "VISTA", :browserName=> "chrome", :version=> ""}

MAPS = {
  "Zazzle Home Page" => "http://www.zazzle.com",
  "Zazzle Community Forum Page" => "http://forum.zazzle.com"
}

Given /^I am on (.*)$/ do |page|
  @browser = Watir::Browser.new(:remote,
		:url => "http://#{username}:#{access_key}@ondemand.saucelabs.com:80/wd/hub",
		:desired_capabilities => caps_ff7)
  @browser.goto(MAPS[page])
end

Then /^should read "([^"]*)"$/ do |rights|
  @browser.html.include?(rights).should == true
  @browser.quit
end

I run my Cucumber script (cucumber ZAllRights.feature).  The browser no longer pop up locally, but the results of Cucumber file still display on the local terminal.

To see a video recording of the test run, I can go to my Sauce Lab account’s My Jobs and check on the videos.

Summary: By changing the browser’s desired_capability to caps_ie9 (or caps_ff7, etc), I can run my Cucumber/Watir scripts on platforms that Sauce Labs support!

Checking a bug using Cucumber and Watir

To kick off my blog, lets use Cucumber and Watir to reproduce a bug so that later on, it can be used to verify the bug fix.

My platform: WinXP, cucumber 1.1.0, watir-webdriver 0.3.4, Ruby 1.9.2p0.

According to Watir.com, Zazzle.com uses Watir, so lets use this website as an example so that I don’t waste my Watir (smile).

Looking around their site for bugs, I notice that the ‘Last Updated’ timestamp on the tags page is not being updated, so that will be the bug I create a Cucumber script for.


Feature: Tag page timestamp
  Scenario: Check if Zazzle's last updated date is correctly set
    Given I am on Zazzle tag page
    When there is a timestamp
    Then the timestamp is not "1/1/0001 12:00:00 AM"

I save the script in C:\CucumberExamples\features\Ztimestamp.feature

Next run cucumber on it:

Color output would be nice to have, so I will fix this deficiency.  I researched Stackoverflow.com using the ANSICON error message above, and I found the steps to install it (download the zip file, extract it, use the 32bit version, type ansicon.exe -i).  Rerun my cucumber file and now it looks beautiful:

Next I copy the cucumber-generated snippet into a steps file named zazzle_steps.rb.  I require the awesome watir-webdriver library, instantiate a firefox browser, then goto Zazzle’s tag page.


require 'watir-webdriver'

Given /^I am on Zazzle tag page$/ do
  @browser = Watir::Browser.new :firefox
  @browser.goto("http://www.zazzle.com/pd/tags")
end

When /^there is a timestamp$/ do
  pending # express the regexp above with the code you wish you had  
end

Then /^the timestamp is not "([^"]*)"$/ do |updated_time|
  pending # express the regexp above with the code you wish you had  
end

Test this out using cucumber command again.  I verify that the Firefox browser starts up on the tags page as expected.  I now fill in the other steps.


require 'watir-webdriver'

Given /^I am on Zazzle tag page$/ do
  @browser = Watir::Browser.new :firefox
  @browser.goto("http://www.zazzle.com/pd/tags")
end

When /^there is a timestamp$/ do
  @browser.html.include?("Last updated")  == true 
end

Then /^the timestamp is not "([^"]*)"$/ do |updated_time|
  @browser.html.include?(updated_time).should_not == true
  @browser.quit  
end

Run cucumber on the file

The above output shows that for this test scenario, the bug still exists (red).

To summarize, this post demonstrates

  1. how one can use Cucumber to describe a bug 
  2. how to use the generated code and fill it with watir-webdriver commands  
  3. ANSI color problem specific to Windows platform can be resolved by installing Ansicon