Thursday, September 17, 2009

Extending Watir

My current project is my first project that is solely a web application. I was looking for a way to automate testing for acceptance and regression tests. In reviewing the available frameworks I chose watir. Watir is built using Ruby which fit well with my project as I am using Rake for my build system.

The app makes extensive use of divs and spans in the page templates. Watir allows divs and spans to be tested but it required a lot of repetitive coding. To test that a div exists, and if so that it meets some criteria you have to do something like this.
# validate the login error message is not displayed
#
divFound = false
@browser.divs.each{ |d|
if d.id == 'ValidationSummary'
assert( false ==
d.text().include?('Enter a valid e-mail address.'),
"Expected the error message: 'Enter a valid e-mail " +
"address'. Received error message: #{d.text()}\n"
)
divFound = true
break
end
}
assert( divFound, "Did not find the ValidationSummary div\n")
Not a big deal but it gets tedious if just about everything is in a div or span. To make life a bit easier I wrote routines that encapsulate the repetitive code. They will test if the div or span exists and if so call an optional block. Since all objects in Ruby are open I coded these as an extension of watir.
module Watir
module Container

# Search the list of divs for the one specified by id.
# If the div is not found return false. If a block is
# provide return its result. Otherwise return true.
#
# id - The id of the div to test for
# block - The optional code block
#
def div?(id, &block )
self.divs.each{ |d|
if d.id == id
return (block) ? yield(d) : true
end
}
false
end

# Search the list of spans for the one specified by id.
# If the span is not found return false. If a block is
# provide return its result. Otherwise return true.
#
# id - The id of the span to test for
# block - The optional code block
#
def span?(id, &block )
self.spans.each{ |d|
if d.id == id
return (block) ? yield(d) : true
end
}
false
end
end
end

We can then change the first example to:
# validate the login error message is not displayed
#
divFound = @browser.divs?( 'ValidationSummary') { |d|
assert( false ==
d.text().include?('Enter a valid e-mail address.'),
"Expected the error message: 'Enter a valid e-mail " +
"address'. Received error message: #{d.text()}\n")
true }
assert( divFound, "Did not find the ValidationSummary1 div\n")
If you just wanted to test for the existence of the div you would do this.
assert( @browser.divs?( 'ValidationSummary'), "Did not find....")

I'm working on a patch submission to add these to the watir project.

No comments: