The wait commands in Selenium Driver are the most important pillars behind creating a robust test script and successful execution of the test suite. Since Selenium WebDriver supports automation of only web-based applications, we do know very well that there are lots of variations in the time lag between loading different pages of the same web application.
You might have also observed that even on the sample page of an application some of the elements get loaded quickly while some of the elements take a bit longer to load. It makes it difficult for Selenium WebDriver in identifying web elements. Some of the most common reasons for automation script failure are as follows:
- The element not found
- The element is not visible
- The element is not clickable
- The element is not in the expected state
Why Do We Use Wait Commands in Selenium WebDriver?
Wait commands are used in Selenium to avoid synchronization issues and make scripts resilient to failure. Selenium WebDriver does have three wait commands to implement in tests.
- Implicit Wait
- Explicit Wait
- Fluent Wait
Implicit Wait in Selenium WebDriver
The Implicit Wait in Selenium instructs the webdriver to wait for a certain amount of time between each consecutive test step across the entire test script. The default wait setting is 0. We can set the desired wait time in seconds, milliseconds, minutes and etc. Once the time is set, the webdriver will wait for the element on the page for the defined time period and if the element is not found within the specified time it will throw “NoSuchElementException“.
The syntax of using implicit wait is as follows. I have set 10 seconds as the default wait time.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
We will have to import the following package in order to use implicit wait in our test.
import java.util.concurrent.TimeUnit;
Example of Implicit Wait In Selenium
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class ImplicitWaitExampleSelenium { public static void main(String[] args) throws InterruptedException { //Setting the path of Chrome Browser Driver String BrowserDriverPath= "C:\\SeleniumBrowserDrivers\\chromedriver.exe"; //Setting System property for Chrome browser Driver. System.setProperty("webdriver.chrome.driver",BrowserDriverPath); //Create a new Instance for Chrome Browser WebDriver driver = new ChromeDriver(); //Defining Implicit Wait for 10 Seconds driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com/ncr"); driver.findElement(By.name("q")).sendKeys("cherry" + Keys.ENTER); WebElement firstSearchResult = driver.findElement(By.tagName("h3")); System.out.println("First Search Result with Cherry is : "+firstSearchResult.getAttribute("textContent")); driver.quit(); } } |
However, the implicit wait has a drawback. It may increase the script execution time as each of the steps in the script would wait for a stipulated amount of time before resuming the test execution.
To overcome the shortcomings of Implicit Wait, WebDriver gives us the option to use Explicit waits wherein we can explicitly apply waits as per the need of the situation rather than waiting for a certain interval of time on each step while executing the test.
Explicit Wait in Selenium WebDriver
The Explicit Wait in Selenium is used to tell the WebDriver to wait for a certain amount of time until an expected condition is met or the maximum time has elapsed. If still, the defined time exceeds then Selenium will throw an exception. Unlike Implicit waits, Explicit waits are applied only for specified elements.
You can use Explicit Wait for those elements that take more time to load as compared to other elements on the page. It is a much better option to use for dynamically loaded Ajax elements.
After declaring explicit wait we have to use “ExpectedConditions“.We can also configure how frequently we want to check whether the desired condition is met using the Fluent Wait that I at later part of this tutorial. In some of my posts, you might have observed that I have used Thread.Sleep(). Having said that I am creating sample tests to give examples but it is not recommended in actual test scripts.
The following is the list of Expected Conditions that can be used in Selenium WebDriver Explicit Wait.
- alertIsPresent()
- elementSelectionStateToBe()
- elementToBeClickable()
- elementToBeSelected()
- frameToBeAvaliableAndSwitchToIt()
- invisibilityOfTheElementLocated()
- invisibilityOfElementWithText()
- presenceOfAllElementsLocatedBy()
- presenceOfElementLocated()
- textToBePresentInElement()
- textToBePresentInElementLocated()
- textToBePresentInElementValue()
- titleIs()
- titleContains()
- visibilityOf()
- visibilityOfAllElements()
- visibilityOfAllElementsLocatedBy()
- visibilityOfElementLocated()
We will have to initialize the object of WebDriverWait to use Explicit Wait. I am giving a maximum wait time of 20 seconds.
Syntax:
WebDriverWait wait = new WebDriverWait(driver,20);
You will also have to import the following two packages to use Explicit Wait.
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
Example of Explicit Wait In Selenium
The following code will wait for the Google search text box to become visible within 20 seconds. If the textbox becomes visible before 20 seconds, the required operation will be performed. if the textbox does not become visible within 20 seconds, Selenium will throw an exception “org.openqa.selenium.TimeoutException: Expected condition failed:“
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import org.openqa.selenium.By; import org.openqa.selenium.Keys; 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.WebDriverWait; public class ExplicitWaitExampleInSelenium { public static void main(String[] args) throws InterruptedException { //Setting the path of Chrome Browser Driver String BrowserDriverPath= "C:\\SeleniumBrowserDrivers\\chromedriver.exe"; //Setting System property for Chrome browser Driver. System.setProperty("webdriver.chrome.driver",BrowserDriverPath); //Create a new Instance for Chrome Browser WebDriver driver = new ChromeDriver(); driver.get("https://google.com/"); // Defining Explicit Wait WebDriverWait wait = new WebDriverWait(driver,20); WebElement searchTextBox; //Waiting until the search text box becomes visible searchTextBox= wait.until(ExpectedConditions.visibilityOfElementLocated(By.name( "q"))); driver.findElement(By.name("q")).sendKeys("cherry" + Keys.ENTER); WebElement firstSearchResult = driver.findElement(By.tagName("h3")); System.out.println("First Search Result with Cherry is : "+firstSearchResult.getAttribute("textContent")); driver.quit(); } } |
Fluent Wait in Selenium WebDriver
The fluent wait is also called Smart Wait in Selenium as it is much smarter than Explicit Wait.FluentWait is used to define the maximum amount of time to wait for a certain condition to meet, as well as the frequency with which to check the expected condition. In addition to that, the user can also configure the wait to ignore specific types of exceptions whilst waiting, such as “NoSuchElementExceptions” or “ElementNotVisibleException” and etc when searching for an element on the page.
Fluent Wait is very useful in dealing with web elements that significantly take more time to load.
The Syntax of using Fluent Wait is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Waiting 30 seconds for an element to be present on the page, checking // for its presence once every 5 seconds. Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(30, SECONDS) // Maximum Wait Time .pollingEvery(5, SECONDS) //Setting Polling time interval .ignoring(NoSuchElementException.class); WebElement foo = wait.until(new Function<WebDriver, WebElement>() { public WebElement apply(WebDriver driver) { return driver.findElement(By.id("foo")); } }); |
Note: The above code snippet is deprecated in Selenium v3.11 and above. You need to use the new syntax which is as follows.
1 2 3 4 5 6 7 8 9 10 11 |
Wait wait = new FluentWait(driver) .withTimeout(Duration.ofSeconds(10)) .pollingEvery(Duration.ofSeconds(2)) .ignoring(Exception.class); WebElement foo = (WebElement) wait.until(new Function<WebDriver, WebElement>(){ public WebElement apply(WebDriver driver ) { return driver.findElement(By.id("foo")); } }); |
Example of New Fluent Wait In Selenium
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import java.time.Duration; import java.util.function.Function; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; public class FluentWaitExampleInSelenium { public static void main(String[] args) throws InterruptedException { //Setting the path of Chrome Browser Driver String BrowserDriverPath= "C:\\SeleniumBrowserDrivers\\chromedriver.exe"; //Setting System property for Chrome browser Driver. System.setProperty("webdriver.chrome.driver",BrowserDriverPath); //Create a new Instance for Chrome Browser WebDriver driver = new ChromeDriver(); driver.get("https://www.instagram.com/"); Wait wait = new FluentWait(driver) .withTimeout(Duration.ofSeconds(30)) .pollingEvery(Duration.ofSeconds(2)) .ignoring(Exception.class); WebElement signUpLink = (WebElement) wait.until(new Function<WebDriver, WebElement>(){ public WebElement apply(WebDriver driver ) { return driver.findElement(By.xpath("//span[text()='Sign up']")); } }); //click on the Sign-up link signUpLink.click(); } } |
Code Explanation
The above code will wait for the “Sign up” link on the Instagram login page for a maximum time of 20 seconds and after every 2 seconds, it will check whether the “Sign up” link is available on the page. As soon as the link becomes available (let’s say after 6 seconds) it will click on the “Sign up” link and proceed further rather than waiting for 20 seconds.
Difference between Implicit Wait and Explicit Wait in Selenium
Implicit Wait | Explicit Wait |
---|---|
It is applied to all the elements in a Test Script | It is applied only to those elements which are intended by user |
Once Implicit Wait is defined, there is no need to specify "ExpectedConditions" on the element to be located | In Explicit Wait, we must have to specify "ExpectedConditions" on the element to be located |
It is can be used when the elements are located within the time frame specified in Selenium Implicit Wait | It is should be used when the elements are taking long time to load. It is also very useful for verifying the property of the element such as visibilityOfElementLocated, textToBePresentInElementValue(),elementToBeClickable and etc |
Conclusion
Selenium WebDriver provides us three different types of Wait command to be used in the test script. The wait commands are Implicit, Explicit, and Fluent Wait. The three wait commands can be used as per the different situations discussed in this tutorial.
Recommended Posts
- Handle Dynamic Web Tables In Selenium WebDriver
- Select Value From Multi-Select Dropdown In Selenium WebDriver And Dropdown with CheckBoxes
- Top #23 Most Useful Selenium WebDriver Commands That You Must know
- XPath in Selenium WebDriver with Example
- How to Use CSS Selector in Selenium WebDriver | 13 Examples
- How to Use AutoIT In Selenium WebDriver
- All about 8 Locators in Selenium Webdriver with Examples
- Intuitive Way of MySQL Database Testing in Selenium | LeanFT
- Read and Write Excel File in Java Using Apache POI Lib