19

Using watir-webdriver, how do I wait for a page to load after I click a link?

At the moment I am using:

sleep n

But this is not ideal as the page response varies so much.

Is there a way to test whether the page is ready or whether there is a certain element in the page? I understand in the normal Watir gem there is Watir::Waiter.wait_until or something similar, but I don't see this in the webdriver version.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • 3
    Are you trying to make something wait until after the page is fully loaded? I thought that was standard behavior... – NinjaCat Aug 17 '10 at 15:53
  • Actually you are correct. However the reason I am having to sleep is because I have some ajax updating the page content. I want to wait until the response is successful. –  Aug 17 '10 at 16:14

7 Answers7

11

I don't know if they're the best way, but this is how I'm handling this for waiting for an updating div to clear:

while browser.div(:id=>"updating_div").visible? do sleep 1 end

This is how I handle waiting for something to display:

until browser.div(:id=>"some_div").exists? do sleep 1 end
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
marc
  • 509
  • 3
  • 7
  • 1
    cool this works perfectly in firefox, not so great in chrome. i've gone with: sleep 1 until browser.div(:foo => 'bar').exists? –  Aug 18 '10 at 09:33
  • 8
    The above method is not recommended because it may never return and lock up your scripts (javascript error, code change, etc.). Watir::Waiter.wait_until(15) { browser.div(:id => "updating_div).visible? } – JEH Oct 25 '10 at 15:57
7

Today's release adds an optional require that brings in some helpers for waiting for elements. These are not (at the moment) available in Watir 1.6, so be aware if you use both libraries side by side.

Check "AJAX and waiting for elements" in the Watir-webdriver Wiki for more information.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
jarib
  • 6,028
  • 1
  • 24
  • 27
4

The best summary is found in "Waiting".

This is it in a nutshell:

require 'watir-webdriver'
b = Watir::Browser.start 'bit.ly/watir-webdriver-demo'
b.select_list(:id => 'entry_1').wait_until_present
b.text_field(:id => 'entry_0').when_present.set 'your name'
b.button(:value => 'Submit').click
b.button(:value => 'Submit').wait_while_present
Watir::Wait.until { b.text.include? 'Thank you' }
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
genegc
  • 1,630
  • 18
  • 16
1

browser.wait_until can be used.

It's more helpful because you can define what to wait for in the parameters (()), as in:

browser.wait_until(browser.text.include("some text"))
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Uday Swami
  • 395
  • 8
  • 22
1

This is how I wait for AJAX in my project:

ajax_loader = $b.element(:xpath  => "//*[@id='spinner-modal-transparent' and @aria-hidden='true']/div/div/div/div/img[@alt='Ajax transparent loader']")

if ajax_loader.exists?
  ajax_loader.wait_while_present(timeout=350)
else
  puts "The AJAX loader was not present."
end
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
C Scordias
  • 21
  • 2
0

I had the same problem, and I tried to fix it by combining wait_until_present and

until browser.div(:id=>"some_div").exists? do sleep 1 end

tricks povided by @marc:

some_div = browser.div(:id => 'some_div')

begin 

  Watir::Wait.until
    some_div.visible?
  end

rescue Watir::Wait::TimeoutError

  until some_div.visible?
    sleep 1
  end
end

Notice that it is your own responsibility to make sure that

div(:id => "some_div")

does exist.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
shuke0327
  • 16
  • 1
0

You can use the wait_until or waituntilExists methods.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
puzzle
  • 1