Tuesday, August 9, 2011

Watir Tutorial: Too fast for ya?

One of the first issues I encountered was my script running too fast for the browser's loading time.  Watir will click a button or tab out of a field, or any number of things that requires a little of time to load and would metaphorically trip on it's own feet.  OATS (Oracle Application Testing Suite), which is run in Java fixes this by waiting until the page is loaded and then 'sleeping' for a second or two and then continuing on.  It will actually time how long the user is paused when you are writing your scripts there.  Watir has a similar functionality in that you can code in:  "sleep 2", and it will pause for 2 seconds, wherever your heart desires.  This is nice as a second line of defense but definitely not as a first, in my opinion.  There are a number of things that can go wrong in a testing script that has 1000 cases, even if 99% of the time it will load within 2 seconds, you will inevitably have some outliers that may make your script choke because the server hung for too long, or whatever may happen.

Watir developers added a nice little method called "wait_until", and it does just that!  It will wait until a given condition is met, checking every half second for a maximum of sixty seconds.  The best way to use this is in conjunction with a method to look for something that will come up in the next screen, or better yet, the actual field that you will be using in the next screen.  There are a couple of places I have used these, which I will illustrate:

1.  Wait until text field exists

Going back to the Watir example, we can make a somewhat redundant improvement to the code that they have there. 

  1. require 'rubygems'
  2. require 'watir'
  3. browser = Watir::Browser.new
  4. browser.goto("http://bit.ly/watir-example")
  5. browser.wait_until {browser.text_field(:name => "entry.0.single").exist?}
  6. browser.text_field(:name => "entry.0.single").set "Watir"

Again:  Probably not necessary in this situation, but it illustrates a point that the difference that we see on one run between a script that includes line 5, and one that excludes it is nil.  But running and rerunning it, or in a different script it will mean the difference between a crash and the computer waiting half a second longer for the page to finish loading. 

2.  Wait until text is included

If your next screen has no fields, or even if it does, this is a good option. 

  1. b.wait_until {b.text.include? "Real Time Account Statement"}

I use this single line of code to tell Watir to wait for a screen within one of our programs.  Is it always necessary?  No.  Sometimes it can completely autopilot, but inevitably it will choke and the script will have to be restarted, this method is very nearly fool-proof.  (I say this because I have still seen it crash, albeit with much less frequency).

The example code is pretty self-explanatory, in that the first part is always the same, what is within the brackets is your conditional of either the '.include?' or '.exist?' flavors as you need.  Don't forget that within the brackets and in your include or exist statement you may have to tell it that the thing it is looking for is within a frame somewhere.  Like in our case with EnterpriseOne, you may need to specify where the specific object is so that Watir can find it. For example: 

  1. b.frame(:id => "e1menuAppIframe").text.include? "Welcome!"

I use this include statement to look for the "Welcome!" message after logging into EnterpriseOne. 

No comments:

Post a Comment