Monday, July 16, 2018

Wait APIs in Selenium WebDriver

Sometimes we need to wait until a WebElement present so that we can do further test steps. Here are common Waits in Selenium WebDriver APIs.

  • Thread sleep 
  • Implicitly Wait 
  • FluentWait 
  • WebDriverWait 
  • AjaxWait (depends on how slow the ajax call, probably not the stable one)

Here is the sample test case.

package me.simplejavautomation;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitApiTest {

    private WebDriver driver;
    private String url;

    @Before
    public void setUp() {
        driver = new ChromeDriver();
        url = "http://simplejavautomation.blogspot.com/2018/07/demo-page-for-selenium-webdriver-apis.html";
        // go to the demo page
        driver.get(url);
        // maximize the browser window
        driver.manage().window().maximize();
    }

    @After
    public void tearDown() {
        driver.quit();
    }

    @Test(expected = NoSuchElementException.class)
    public void testImplicitlyWaitWithException() {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

        // find element
        WebElement waitLink = driver.findElement(By.linkText("WebDriver Wait"));
        assertNotNull(waitLink);
    }

    @Test
    public void testImplicitlyWait() {
        // wait 10 seconds if web element is not present
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        // find element
        WebElement waitLink = driver.findElement(By.linkText("WebDriver Wait"));
        assertNotNull(waitLink);
    }

    @Test
    public void testFluentWait() {
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(Duration.ofSeconds(10))
                .pollingEvery(Duration.ofSeconds(1)).ignoring(NoSuchElementException.class);
        // find element
        WebElement waitLink = wait.until(new Function<WebDriver, WebElement>() {

            @Override
            public WebElement apply(WebDriver driver) {
                return driver.findElement(By.linkText("WebDriver Wait"));
            }

        });
        assertNotNull(waitLink);
    }

    @Test
    public void testWebDriverWait() {
        WebDriverWait wait = new WebDriverWait(driver, 10);

        // find element
        WebElement waitLink = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("WebDriver Wait")));
        assertNotNull(waitLink);
    }

    @Test
    public void testHtmlWait() {
        driver.manage().timeouts().pageLoadTimeout(100, TimeUnit.SECONDS);
        driver.manage().timeouts().setScriptTimeout(100, TimeUnit.SECONDS);
    }

    @Test
    public void testAjaxWait() {
        Select citySelect = new Select(driver.findElement(By.id("cities")));
        citySelect.selectByVisibleText("London");

        driver.findElement(By.id("weather")).click();

        // wait ajax finish
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(new Function<WebDriver, Boolean>() {
            @Override
            public Boolean apply(WebDriver t) {
                Boolean isJqueryCallDone = (Boolean) ((JavascriptExecutor) driver)
                        .executeScript("return jQuery.active==0");
                return isJqueryCallDone;
            }
        });

        // weather info retrieved
        WebElement weatherInfo = wait.until(new Function<WebDriver, WebElement>() {
            @Override
            public WebElement apply(WebDriver t) {
                WebElement info = driver.findElement(By.id("weatherInfo"));
                if (info != null) {
                    if (info.getText().startsWith("City:")) {
                        return info;
                    }
                    return null;
                }
                return info;
            }
        });
        assertTrue(weatherInfo.getText().startsWith("City: London"));
    }

}

No comments:

Post a Comment