Timing out Watir with Timeout::timeout

I’ve been writing a script to monitor our production app that has been playing up a lot lately. The problem is that the service on the server continues to run but when trying to access the main page it just sits there loading indefinitely.

The idea is to write a Watir script that brings up the main page every minute and notifies us if it displays an error, or, as has been happening, sits there loading indefinitely.

One of the things I love about Watir is how it handles browser synchronization: it’s really neat. To quote Bret’s design objective:

“Watir is deterministic. Watir does not wait X seconds. It waits until the page is loaded. Period.”
- Bret Pettichord

So this is great when you’re writing a test script, but as my page sometimes loads indefinitely, so does my Watir script:

require 'watir'
check_url = 'www.google.com'
ie = Watir::IE.new()
ie.goto(check_url)
puts ie.check_for_http_error()

I did some research and found a ruby Timeout class that I figured I could use. My first attempt was to do something like this:

require 'watir'
check_url = 'www.google.com'
ie = Watir::IE.new()
begin</pre>
Timeout::timeout(30) do
 ie.goto(check_url)
 puts ie.check_for_http_error()
 end
rescue
 puts 'timed out'
end

This seemed to work when the page didn’t timeout, but for some reason it wasn’t catching the timeout. So I did a bit of digging and found out a rescue clause in ruby with no following class only catches exceptions of type StandardError, a subclass of Exception. So it wasn’t catching the Timeout::Error exception. The way to catch this exception is to always include the Exception clause, and to pass it to a variable such as ‘e’.

The final script looked something like:

require 'watir'

check_url = 'www.google.com'
ie = Watir::IE.new()
begin
 Timeout::timeout(30) do
 ie.goto(check_url)
 puts ie.check_for_http_error()
 end
rescue Exception => e
 puts 'timed out: '+e
end

In my research on Timeout::timeout I found this article that explains how it’s actually dangerous to use Timeout::timeout, but until I figure out a better solution it seems to work pretty well for me.

8 thoughts on “Timing out Watir with Timeout::timeout

  1. Thanks for the article.
    I’m having the same issue, where browser loads indefinitely.

    It would be nice if this was built-in in Watir::IE class, or some where more appropriate.

    • Got it working… with some tweaks!!

      browser_loaded=0
      while (browser_loaded == 0)
      begin
      browser_loaded=1
      Timeout::timeout(10) do
      browser.goto(“http://mysite.com”)
      end
      rescue Timeout::Error => e
      puts “Page load timed out: #{e}”
      browser_loaded=0
      retry
      end
      end

        • Thanks a lot to ya, without your insight, I would be stuck for a long time with the browser loading/waiting indefinitely issue…

      • Converted usage into blocks and yield:

        def sureLoadLink(mytimeout)
        browser_loaded=0
        while (browser_loaded == 0)
        begin
        browser_loaded=1
        Timeout::timeout(mytimeout) do
        yield
        end
        rescue Timeout::Error => e
        puts “Page load timed out: #{e}”
        browser_loaded=0
        retry
        end
        end
        end

        Examples of calling:
        1. sureLoadLink(10)
        {$ie.goto(“siteURL”)}

        2. sureLoadLink(10)
        {$ie.button(:index,2).click}

        3. sureLoadLink(10)
        {$ie.link(:text,viz_type).click}

        It uses a timeout as a parameter, the time within which you want your code to be executed.

        The chunk of code you want executed within this timeout is specified in the curly braces when the block is called.

        yield is the place where the passed code chunk is executed.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s