Pelargir

Musings on software and life from Matthew Bass.

December 12th, 2005

Watir tips and tricks

I’ve been using Watir for a week or so now and have (naturally) run into a couple of problems. I’ve also come up with a handy way to reference fields on a page. I thought I’d share these tips so others won’t have to spend their precious time working through ‘em as I had to do.

Problem: Watir doesn’t respect maxLength

The first problem I found is that Watir doesn’t respect the maxLength attribute on a text field. It will happily enter 20 characters into a text field with a maxLength of 10 without complaining. This can cause problems with assertions and such. I was able to override Watir’s set(..) method with code which will throw an exception if the string to be entered into the text field exceeds the maxLength.

Just add this code to your script if you want the same warning to show up:

class Watir::TextField
  alias_method :set_value, :set
    def set(value)
      if (value.size > maxLength)
        fail(”The length of the string < \"#{value}\"> exceeds ” +
          ”the max length (#{maxLength}) of the \”#{name}\” text field.”)
      end
    set_value(value)
  end
end

Problem: Watir doesn’t yet handle JavaScript alerts

Another problem I ran into was Watir’s inability to handle JavaScript alerts and pop-ups. (It can handle pop-up browser windows fine, just not windows created with JavaScript’s alert(..) function.) There currently isn’t a very good workaround for this, but the Watir folks are working on a solution for the next release. In the meantime, they suggest using a tool call AutoIt in conjunction with Watir to automate interaction with the pop-ups. I haven’t tried this method yet.

Tip: Abstract out textual references to page elements

The site I’m using Watir to test changes quite frequently. I have no guarantee that a specific page element will be named the same thing for any length of time. Why, then, would I want to scatter references to the element throughout my Watir tests and be forced to change all of the references anytime the element itself is changed? My solution was to abstract out the common attributes of the element so that each element is only defined once. Then, whenever an element changes, I only have to change a single reference.

Ruby’s “method_missing” idiom made it very, very easy to do this. I simply defined a parent for all of my test cases and added the following method definition to it:

def method_missing(method)
  key = method.id2name
  super unless page_objects.has_key?(key)
  args = page_objects[key]
  return @ie.send(args[0], args[1], args[2])
end

Do you see what this does? Whenever a method which doesn’t exist in a subclass is called, method_missing is passed the name of the (non-existent) method. I take that name and use it as a key in a hash which I expect to be returned by a method called “page_objects” which is defined in a subclass. If the key exists, I grab the object from the hash and use it to call a method on Watir’s IE object (Ruby’s “send” method is the equivalent of an “exec” in other langages… it just allows strings to be interpreted as method calls and arguments).

I then define the “page_objects” method in each of my subclasses like so:

def page_objects
  {
  ”field1″ => [:text_field, :id, “my_field”],
  ”field2″ => [:text_field, :id, “another_field”]
  }
end

I can then simply reference “field1″ and “field2″ as if they were instance variables of my subclass. For example:

def test_example
  field1.setContents(”Hello world”)
  assert_equal(”Booyah”, field2.getContents)
end

The calls to “field1″ and “field2″ are handled by “method_missing” since those methods don’t exist, and the magic then proceeds from there. If the actual ID of either field changes, I simply make the change in my “page_objects” method and my existing tests should all continue working. This indirection follows the DRY principle (Don’t Repeat Yourself).

This trick would almost impossible to accomplish in Java without a large amount of bulky reflection code. Just another example of why dynamic typing is so nice.

Hope you find this idiom as useful as I have. Happy Watir-ing!

December 6th, 2005

20.weeks.ago

Another example why Ruby is generally the best choice when you want to get something up and running fast with a minimum amount of code and a maximum amount of clarity.

Dion Almaer’s 20.weeks.ago vs. java.util.Calendar

December 6th, 2005

Watir: Web Application Testing in Ruby

WATIR stands for “Web Application Testing in Ruby”. Watir is a free, open-source functional testing tool for automating browser-based tests of web applications. It is pronounced water.

I began experimenting with Watir over the weekend. I run a database-driven web site for a local non-profit group and have been looking for a good way to functionally test the site with a minimum time investment in a particular framework. I’ve had bad experiences with HtmlUnit and HttpUnit in the past and wanted a way to code the tests in Ruby. I’ve been told that the state of Watir a year ago was really awful, but apparently they’ve made lots of improvements since then because I didn’t have any trouble getting up and running.

As a test writer, most of your interaction with Watir takes placed through the IE object which lets you open a specific URL and then make assertions about what the page should look like. Watir’s flexibility in looking up data on the page is phenomenal. You can do lookups by name, ID, position, and so on. The pages I’ve tested thus far contain light JavaScript so I’m not sure how well Watir performs on pages with heavy scripting, but for my purposes Watir made it quick and easy to write tests that didn’t contain an enourmous amount of code, yet were powerful enough to thoroughly verify the functionality of my web app.

Couple Watir with ActiveRecord and you have a powerful way to verify that data on the backend is getting written and updated correctly from your web application.

I highly recommend you check out Watir for your next project. If you end up using it, feel free to share your thoughts about it by posting a comment here or e-mailing me directly. I’d enjoy hearing from you.

December 1st, 2005

An incredibly geeky display of Christmas lighting prowess

Someone just sent me a link to this video. How amazingly geeky. Yet another case where I’m wondering why people like this have so much extra time on their hands. There has to be an explanation!