WebDriver not waiting for page to load after a button click

11,269 views
Skip to first unread message

Phil

unread,
Jun 6, 2011, 5:26:29 AM6/6/11
to webdriver
Hi all,

WebDriver doesn't seem to be waiting for any pages to reload after it
clicks a button. When dealing with links it seems to be working fine,
but for buttons it moves on to the next component straight away and
obviously throws an error when that component doesn't exist yet.
Here's the code I'm using to interact with buttons;

private void invokeButton(IWebDriver driver, string value)
{
string input = "//input[contains(@value, '" + value + "')
and (@type='button' or @type='submit')]";

driver.FindElement(By.XPath(input)).Click();
}

It is clickign the button ok, just not waiting for the page reload
afterwords. Before, I was using the selenium.WaitForPageToLoad()
function but as far as I know this doesn't work when using
WebDriverBackedSelenium. Any help is greatly appreciated.

Phil

Tan

unread,
Jun 6, 2011, 8:34:21 AM6/6/11
to webdriver
Hi Phil

By default, WebDriver should wait for the full page reload before
proceeding. It, however, might not be able to wait for XHR (AJAX)
requests.

Could you use FireBug > Net to manually inspect if there is any XHR
requests being send as part of the button click? If possible, could
you also include the minimal HTML/JS here in this post

Cheers,
Tan

Phil

unread,
Jun 6, 2011, 8:55:57 AM6/6/11
to webdriver
Hey Tan,

I switched to the NET > XHR tab and there doesn't seem to be any AJAX
requests, HTML for the button is listed below;

<input type="submit" style="margin-bottom: 20px; margin-left: 20px;"
onclick="javascript:WebForm_DoPostBackWithOptions(new
WebForm_PostBackOptions(&quot;ctl00$SPWebPartManager1$g_45d3cf2e_d74f_4e93_95b5_8f6c0f935d44$ctl00$map1$ctl04$ctl12&quot;,
&quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))"
value="Next"
name="ctl00$SPWebPartManager1$g_45d3cf2e_d74f_4e93_95b5_8f6c0f935d44$ctl00$map1$ctl04$ctl12">

Thanks
Phil

SeleniuMaddog

unread,
Jun 6, 2011, 12:49:38 PM6/6/11
to webdriver
I have also noticed that when I click on buttons the next line is
immediately executed - no XHR involved.
It happens a lot.

On Jun 6, 8:55 am, Phil <owe...@hotmail.co.uk> wrote:
> Hey Tan,
>
> I switched to the NET > XHR tab and there doesn't seem to be any AJAX
> requests, HTML for the button is listed below;
>
> <input type="submit" style="margin-bottom: 20px; margin-left: 20px;"
> onclick="javascript:WebForm_DoPostBackWithOptions(new
> WebForm_PostBackOptions("ctl00$SPWebPartManager1$g_45d3cf2e_d74f_4e93_95b5_8f6c0f935d44$ctl00$map1$ctl04$ctl12",
> "", true, "", "", false, false))"

SeleniuMaddog

unread,
Jun 6, 2011, 12:51:49 PM6/6/11
to webdriver
oh sorry, I realized I mostly just send Keys.Return when it happens.

Simon Stewart

unread,
Jun 6, 2011, 5:49:51 PM6/6/11
to webd...@googlegroups.com
If you're on Windows then the keyboard and mouse emulation is done at
the OS, not the browser, level. That means that it's hard for
webdriver to know whether or not a page load is expected. The
recommended way of dealing with this is to have the next line use a
wait, either by using the WebDriverWait class, or by using the
implicit waits. My preference is to make waits clear and obvious.

Regards,

Simon

> --
> You received this message because you are subscribed to the Google Groups "webdriver" group.
> To post to this group, send email to webd...@googlegroups.com.
> To unsubscribe from this group, send email to webdriver+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/webdriver?hl=en.
>
>

SeleniuMaddog

unread,
Jun 6, 2011, 8:50:20 PM6/6/11
to webdriver
Sorry for hijacking the thread a bit...

Simon - I've used this method - to wait for an element on the next
page, but then there's danger that the page is not loaded yet, is
there a way to know if DomLoad or window.onload have already occured?

Thank you

Simon Stewart

unread,
Jun 7, 2011, 4:24:39 AM6/7/11
to webd...@googlegroups.com
Not without the page notifying you. If I'm really concerned about
that, I wait for an element in the footer of the page, and then check
to see whether my JS libraries have intialized themselves.

Simon

Phil

unread,
Jun 7, 2011, 4:55:47 AM6/7/11
to webdriver
I'm not sure how Firebug finds these XHR requests but more than a few
showed up when sumbitting a couple of forms. Does this mean then that
there's no way for WebDriverBackedSelenium to know if a page ahd
loaded? I've got a rough re-try clause that doesn't interact with a
component if selenium.isElementPresent is false, and it tries this 3
times before giving up, if I'm understanding it right I'd have to
extend this to say 10 or 15 re-tries to cover page loads and this
seems pretty sloppy. Is there really no way to get the old
selenium.WaitForPageToLoad() to work?

Phil

On Jun 6, 1:55 pm, Phil <owe...@hotmail.co.uk> wrote:
> Hey Tan,
>
> I switched to the NET > XHR tab and there doesn't seem to be any AJAX
> requests, HTML for the button is listed below;
>
> <input type="submit" style="margin-bottom: 20px; margin-left: 20px;"
> onclick="javascript:WebForm_DoPostBackWithOptions(new
> WebForm_PostBackOptions("ctl00$SPWebPartManager1$g_45d3cf2e_d74f_4e93_95b5_8f6c0f935d44$ctl00$map1$ctl04$ctl12",
> "", true, "", "", false, false))"

Simon Stewart

unread,
Jun 7, 2011, 9:00:34 AM6/7/11
to webd...@googlegroups.com
You're right that WebDriver can't really tell when a page has finished
loading. The problem is that it's hard to tell the difference between
a slowly responding AJAX request and a deliberate comet-style hanging
GET. Effectively, determining whether a page is fully loaded is a
variation of the halting problem, which is non trivial to solve.

Fortunately, you, as the app author, know how to check that the page
is loaded. One popular approach I've seen to this is what I like to
think of as the "Eternal Optimist" pattern: rather than limiting page
loaded checks to a set duration or number of retries, the wait class
continues checking indefinitely, relying on an external controller
(such as a continuous build server) to kill the test if it takes too
long.

Simon

SeleniuMaddog

unread,
Jun 7, 2011, 4:22:26 PM6/7/11
to webdriver
Simon, maybe the mechanisms WebDriver uses for its' waits can be
exposed to the user - so it doesn't have to use heuristics, but we can
tell it what to expect. Does that make sense in any way?

Simon Stewart

unread,
Jun 8, 2011, 9:11:26 AM6/8/11
to webd...@googlegroups.com
Things get interesting when you consider native events. Your call to
"click" boils down to webdriver figuring out where on the page an
OS-level click should go. This event is dispated, and then the call
returns. We don't actually know whether or not a new page load is
expected from this event (particularly when you're dealing with an
AJAX heavy app)

Which is a long way of saying that even if we exposed all the bells
and whistles, you'd still not get consistent behaviour, and you'd
_still_ need to have waits in your tests.

Simon

Phil

unread,
Jun 8, 2011, 9:38:00 AM6/8/11
to webdriver
Thanks Simon, I'll some other method to verify a page has loaded. =)

Phil

On Jun 8, 2:11 pm, Simon Stewart <simon.m.stew...@gmail.com> wrote:
> Things get interesting when you consider native events. Your call to
> "click" boils down to webdriver figuring out where on the page an
> OS-level click should go. This event is dispated, and then the call
> returns. We don't actually know whether or not a new page load is
> expected from this event (particularly when you're dealing with an
> AJAX heavy app)
>
> Which is a long way of saying that even if we exposed all the bells
> and whistles, you'd still not get consistent behaviour, and you'd
> _still_ need to have waits in your tests.
>
> Simon
>

Nigel Charman

unread,
Jun 9, 2011, 3:50:55 AM6/9/11
to webdriver
On this topic, we've already added waits to our tests but there's one
edge case we don't know how to handle. This occurs when the exact
same page is returned as the result of a click (normally when a
validation error on the page hasn't been resolved). After click()
returns, we don't know whether the page has started refreshing,
potentially leading to the wait returning immediately even though the
page hasn't yet started refreshing.

An ugly solution might be:

footer = driver.findElement(By.id("footer"));
submit.click();
wait.until(elementIsStale(footer)); // wait for the
current page to be refreshed
wait.until(elementPresent(By.id("footer"))); // wait for the new
page to finish loading

where elementIsStale() checks for StaleElementException.

Would this be guaranteed to work? Are there any cleaner solutions for
this?

Nigel

On Jun 9, 1:11 am, Simon Stewart <simon.m.stew...@gmail.com> wrote:
> Things get interesting when you consider native events. Your call to
> "click" boils down to webdriver figuring out where on the page an
> OS-level click should go. This event is dispated, and then the call
> returns. We don't actually know whether or not a new page load is
> expected from this event (particularly when you're dealing with an
> AJAX heavy app)
>
> Which is a long way of saying that even if we exposed all the bells
> and whistles, you'd still not get consistent behaviour, and you'd
> _still_ need to have waits in your tests.
>
> Simon
>

Shannon Null Code

unread,
Jun 28, 2011, 12:42:24 PM6/28/11
to webdriver
My solution for these cases was to create my own waitForPageLoaded
method that checked the browser readystate

public void waitForPageLoaded() {

ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return
document.readyState").equals("complete");
}
};

Wait<WebDriver> wait = new WebDriverWait(INSTANCE_OF_YOUR_WEBDRIVER,
30);
try {
wait.until(expectation);
} catch(Throwable error) {
fail("Timeout waiting for Page Load Request to complete.");
> >> >> WebForm_PostBackOptions("ctl00$SPWebPartManager1$g_45d3cf2e_d74f_4e93_95b5_ 8f6c0f935d44$ctl00$map1$ctl04$ctl12",

Simon Stewart

unread,
Jun 28, 2011, 10:33:35 PM6/28/11
to webd...@googlegroups.com
You've still got a race condition to deal with: the one where the load
hasn't even started yet when you do your check.

One way of dealing with this problem is to add a unique key to the
"window" global before performing the action that loads the page. A
page reload will cause this variable to be deleted, so it's an easy
thing to check for.

Regards,

Simon

Simon Stewart

unread,
Oct 14, 2012, 6:11:54 PM10/14/12
to webd...@googlegroups.com
I'm not quite sure what you're saying here. The implicit waits most
certainly work, and the explicit waits are far more than just "white
elephants". You may be running into a problem that the locator you
think should only ever return one element actually matches several
(that can be really hard to track down).

Simon

On Fri, Oct 12, 2012 at 4:44 AM, VINOD KUMAR CHAUHAN
<jmdvi...@gmail.com> wrote:
> I think two ways to wait, defined in WebDriver doesn't work at all. These
> are -
> 1. implicit waiting using-------------
>
> driver.manage().timeouts().implicitlyWait(30,
> TimeUnit.SECONDS);
> driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
> driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
> as per definnition this sets the waits for the entire life of the driver,
> but actually this doesn't work.
>
> 2. Explicit waiting using--------
> WebDriverWait & Expected conidtion also not work.
> These methods seem to be mere white elephants in WebDriver.
>
> Although we can use the Thread.sleep(time) method in java for explicit
> waiting. But yes it is not an efficient way...
> To view this discussion on the web visit
> https://groups.google.com/d/msg/webdriver/-/iLf3t29o14cJ.
Reply all
Reply to author
Forward
0 new messages