Watir is a web testing tool that allows you to automate Internet Explorer and script interactions with your web application.  It uses the COM automation interface to drive the browser.  The nicest thing about the tool is that it allows you to use Ruby to create the test scripts.  Ruby is an unobtrusive, easy to learn, fully object-oriented language whose power at abstraction building will allow you to bring your testing to a level you never previously imagined.

Now, a lot of people love and use Watir, and we have been getting requests for help on scripting our web controls with Watir.  All of our controls are pretty complex beasts and require interaction with the client-side API in order to drive them effectively.  It is a pain to find HTML sub-elements, rendered by the control and click them -- what if we change those element's ID's in the future?  The test scripts will be hard to maintain to say the least.

Interacting through the JavaScript API requires two things:
  • executing JavaScript code and passing parameters to the methods.
  • extracting return values and object properties and using them to write assertions

This forum thread, started by Tobias Bartlind, solves the first part of the problem -- it uses the browser's Navigate method to navigate to a "Javascript: ..." URL and execute some script.  I did some digging and found a more elegant way to do that.  You can obtain a reference to the window object and call its execScript method:

window = ie.ie.Document.parentWindow
window.execScript("RadComboBox1.FindItemByText(\"Golf\").Select()")

How do we get values out of the script though?  The best way I have found so far is to attach an expando property to the window object and get it from the Ruby script:

ie.execute_script "window.Result = 5;"
window = ie.ie.Document.parentWindow
puts window.Result

I decided to wrap the logic about obtaining the window object inside the IE class, provided by Watir.  Ruby's classes can be opened at any time and new methods can be added.  I did exactly that, adding two new methods: execute_script and window.  I moved those to a separate file, watir_telerik_extensions.rb:

========watir_telerik_extensions.rb========
require 'rubygems'
require 'watir'

require 'rubygems'
require 'watir'

module Watir
    class IE
        def execute_script(scriptCode)
            window.execScript(scriptCode)
        end
       
        def window
            ie.Document.parentWindow
        end
    end
end


====================================

This allows me to use the file from any test script by including:

require 'watir_telerik_extenstions'


inside the script.  Having the extensions around, I can write a complete test that exercises r.a.d.combobox's selection mechanism.  I can find an item, select it, and then assert if the text of the combobox equals to the item's text:

========watir_telerik_combo.rb===========

require 'rubygems'
require 'watir'
require 'test/unit'
require 'watir_telerik_extenstions'

include Watir

class ComboTest < Test::Unit::TestCase
    def setup
        @ie = IE.new
        @ie.goto "http://www.telerik.com/r.a.d.controls/Combobox/Examples/Functionality/WhatsNew/DefaultCS.aspx"
    end
   
    def test_selection
        @ie.execute_script "RadComboBox1.FindItemByText(\"Golf\").Select()"
        @ie.execute_script "window.Result = RadComboBox1.GetText()"
        assert_equal "Golf", @ie.window.Result
    end
   
    def teardown
        @ie.close
    end
end

====================================

The test results:

Loaded suite watir_combo
Started
.
Finished in 12.86 seconds.

1 tests, 1 assertions, 0 failures, 0 errors


The test is a bit slow, because it uses the online combobox examples.  I recommend running it agains a local installation of the product.

Have fun with Watir, and keep writing those tests.



Comments