Converting Selenium waitForCondition to WebDriverWait


I usually don’t write simple tutorial posts, but I’d like to share this one, because it took me some time to google the answer, and I still had to adapt it to my case.

I had the simplest possible vanilla Ajax application, that would react to keystrokes in a textfield and then return a list of words based on the entered value. You see this everywhere! My particular HTML snippet looked like this:

<body onload="document.getElementById('prefixText').focus()">
<input type="text" id="prefixText" onkeyup="checkForExpansion(document.getElementById('prefixText').value)"/>
<br/>
<span id="ajaxResults"></span>
</body>

checkForExpansion just made an asynchronous call the a servlet that returned a list of completions. However, one thing was a little untypical with this application: The results went in as strings separated by <br/> tags into the span element. The consequence of this was that there was no obvious element to wait for when testing this page; the span was there already.

Now, my first test went like this:

@Test
public void trivialAjaxListCompletionExampleUsingSelenium1StyleWait() {
    Selenium selenium = new WebDriverBackedSelenium(webDriver, testedUrl);
    webDriver.get(testedUrl);
    webDriver.findElement(By.id("prefixText")).sendKeys("a");
    selenium.waitForCondition("selenium.browserbot.getCurrentWindow().document.getElementById('ajaxResults').innerHTML.indexOf('ALEX') > 0", "1000");
}

It worked, but it relied on WebDriverBackedSelenium, which I really didn’t want it to. After some googling and experiementing, I came up with the followging:

@Test
public void trivialAjaxListCompletionExampleUsingWebDriverStyleWait() {
    webDriver.get(testedUrl);
    webDriver.findElement(By.id("prefixText")).sendKeys("a");

    boolean isListPopulated = (new WebDriverWait(webDriver, 1000))
            .until(new ExpectedCondition() {
                public Boolean apply(WebDriver d) {
                    JavascriptExecutor javascriptExecutor = (JavascriptExecutor) webDriver;
                    return (Boolean)javascriptExecutor.executeScript("return document.getElementById('ajaxResults').innerHTML.indexOf('ALEX') > 0");
                }
            });
    assertTrue(isListPopulated);
}

As a test, this sucks, but this snippet shows several interesting things. First we have the WebDriverWait class. Waiting can be quite fine-tuned using the FluentWait class.

Then we have an example of the browserbot being dropped (since it’s a Selenium 1 thing) and Javascript with a return (mandatory in Selenium 2).

Finally, we have the boolean test. Many examples on the web are written so that they wait for a certain element to appear, and then return it. Since the element (the span) was already present, I wanted to make the example a little odd.

  1. No comments yet.
(will not be published)