Showing posts with label Wait. Show all posts
Showing posts with label Wait. Show all posts

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"));
    }

}