Synchronizing a test with custom-expected conditions

With the explicit wait mechanism, we can also build custom-expected conditions along with common conditions using the ExpectedConditions class. This comes in handy when a wait cannot be handled with a common condition supported by the ExpectedConditions class.

In this recipe, we will explore how to create a custom condition.

How to do it...

We will create a test that will create a wait until an element appears on the page using the ExpectedCondition class as follows:

@Test
public void testExplicitWait() {

  WebDriver driver = new FirefoxDriver();
  // Launch the sample Ajax application
  driver.get("http://cookbook.seleniumacademy.com/AjaxDemo.html");

  try {
    driver.findElement(By.linkText("Page 4")).click();
    WebElement message = new WebDriverWait(driver, 5)
        .until(new ExpectedCondition<WebElement>() {
          public WebElement apply(WebDriver d) {
            return d.findElement(By.id("page4"));
          }
        });
    assertTrue(message.getText().contains("Nunc nibh tortor"));
  } finally {
    driver.quit();
  }
}

How it works...

The Selenium WebDriver provides the ability to implement the custom ExpectedCondition interface along with the WebDriverWait class to create a custom-wait condition, as needed by a test. In this example, we created a custom condition, which returns a WebElement object once the inner findElement() method locates the element within a specified timeout, as follows:

WebElement message = new WebDriverWait(driver, 5)
.until(new ExpectedCondition<WebElement>(){
    @Override
    public WebElement apply(WebDriver d) {
    return d.findElement(By.id("page4"));
}});

There's more...

A custom wait can be created in various ways. In the following section, we will explore some common examples to implement a custom wait.

Waiting for an element's attribute value update

Based on the events and actions performed, the value of an element's attribute might change at runtime. For example, a disabled textbox gets enabled based on the user's rights. A custom wait can be created on the attribute value of the element. In the following example, ExpectedCondition waits for a Boolean return value, based on the attribute value of an element:

new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {
    public Boolean apply(WebDriver d) {
        return d.findElement(By.id("userName")).getAttribute("readonly").contains("true");
}});

Waiting for an element's visibility

Developers can hide or display elements based on the sequence of actions, user rights, and so on. The specific element might exist in the DOM but are hidden from the user, and when the user performs a certain action, it appears on the page. A custom wait condition can be created based on the element's visibility, as follows:

new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {
    public Boolean apply(WebDriver d) {
        return d.findElement(By.id("page4")).isDisplayed();
}});

Waiting for DOM events

The web application may be using a JavaScript framework such as jQuery for AJAX and content manipulation. For example, jQuery is used to load a big JSON file from the server asynchronously on the page. While jQuery is reading and processing this file, a test can check its status using the active attribute. A custom wait can be implemented by executing the JavaScript code and checking the return value, as follows:

new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {
    public Boolean apply(WebDriver d) {
        JavascriptExecutor js = (JavascriptExecutor) d;
        return (Boolean)js.executeScript("return jQuery.active == 0");
}});

See also

  • The Synchronizing a test with an implicit wait recipe
  • The Synchronizing a test with an explicit wait recipe
  • The Synchronizing a test with FluentWait recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.144.194