window.location.href behavior?

1,329 views
Skip to first unread message

bill shelton

unread,
Mar 22, 2010, 1:32:47 PM3/22/10
to webdriver
Hi,

I'm writing tests for a web app that typically executes
window.location.href=someUrl after some set of instructions (which can
take an arbitrary amount of time and usually involve a remote ajax
call). I notice that Webdriver doesn't seem to wait for the
instructions to complete before executing the window.location.href
statement. Is there something I might be missing or a different
approach I should take?

Here's how I can reproduce the behavior, which should be: load
location.html, click go, wait 1 second, load ajax.html, verify. Note
that the setTimeout simply mimics the time taken for one of the app's
ajax calls. If I simply open a browser and run it by hand, it works as
expected.

<!-- page 1 : location.html -->
<a href="javascript:void(0);" onclick="go();" id="go_link">go</a>
<script>
function go(){
window.setTimeout( function(){location.href = 'http://dev/sandbox/
ajax.html'; } , 1000);
}
</script>


<!-- page 2 : ajax.html -->
<p id="find_me">found</p>

//-------------------------------------------//
@Test
public void testLocationHref() {
InternetExplorerDriver driver = new InternetExplorerDriver();
driver.get("http://dev/sandbox/location.html");
driver.findElement(By.id("go_link")).click();
String actual = driver.findElement(By.id("find_me")).getText();
Assert.assertEquals("found", actual);
}

//------ stack-----//
org.openqa.selenium.NoSuchElementException: Unable to find element by
id using "find_me" (7)
System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1',
java.version: '1.6.0_03'
Driver info: driver.version: ie
at
org.openqa.selenium.ie.ErrorHandler.verifyErrorCode(ErrorHandler.java:
36)
at org.openqa.selenium.ie.Finder.handleErrorCode(Finder.java:219)
at org.openqa.selenium.ie.Finder.findElementById(Finder.java:93)
at org.openqa.selenium.By$1.findElement(By.java:66)
at org.openqa.selenium.ie.Finder.findElement(Finder.java:207)
at
org.openqa.selenium.ie.InternetExplorerDriver.findElement(InternetExplorerDriver.java:
322)
at tests.WindowLocationTest.testLocationHref(WindowLocationTest.java:
16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod
$1.runReflectiveCall(FrameworkMethod.java:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:
15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
41)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:
20)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:
28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:
31)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
73)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:
28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:
31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:
46)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:
38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:
467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:
683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:
390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:
197)
//------------------------//


The behavior is the same with FirefoxDriver. That is, Webdriver
appears to continue to the next statement following
driver.findElement(By.id("go_link")).click(); without waiting.

Env: Java 6, TestNG, WinXP, IE7. (Note, same behavior for JUnit)

best regards,
bill shelton


Jason Leyba

unread,
Mar 22, 2010, 3:55:45 PM3/22/10
to webd...@googlegroups.com
This is working as expected. Your click handler delays its action
with a 1 second timeout, therefore, the click() command will not
detect the load and will return immediately. For Firefox (I'm not
familiar with the IEDriver, so I can't comment), when a new command is
executed, it will check if the current window is currently loading
something. If it is, it will delay executing the command until the
load finishes... except your handler has a 1 second timeout, so the
next command is going to come in before the load even starts and will
execute immediately.

This is why we recommend using the WebDriverWait[1] class when
searching for an element after an expected load[2]. I've modified
your test below with an example usage[3]:

public void testLocationHref() {


driver.get("http://dev/sandbox/location.html");
driver.findElement(By.id("go_link")).click();

WebElement findMe = new WebDriverWait(driver, 2000)
.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("find_me"));
}
});
Assert.assertEquals("found", findMe.getText());
}

Of course, that's pretty verbose, but you can extract some helper
functions to clean it up.

-- Jason

[1] http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/support/ui/WebDriverWait.html
[2] We plan to implement implicit waiting on findElement(s) commands;
look for it in a future release (April/May *crosses fingers*).
[3] Test not tested/compiled; there may be some typos.

> --
> 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.
>
>

bill shelton

unread,
Mar 22, 2010, 4:44:09 PM3/22/10
to webdriver
Thanks, Jason. It worked well for this example and (hopefully) for the
app in question. The WebDriverWait example is also something I was
looking for. Thanks!

best,
bill

> [1]http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/sel...

Reply all
Reply to author
Forward
0 new messages