Hiya everyone! This post is a continuation of the previous one, 9h. WebDriver – Implicit Waits.
Without further ado, let us harness the power of Explicit Waits. An explicit wait requires a bit more coding but has huge advantages compared to an implicit wait. Here we can wait until a certain condition occurs before proceeding with the test. If the condition is not met within the specified timeout value, then an exception is thrown.
The syntax is as below,
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("element_id")));
Thus WebDriverWait class is used to specify the maximum timeout value, 15 seconds in this case. The ExpectedCondition class has methods that cover most of the conditions that we would like to wait until they occur in our test. These conditions are used with WebDriverWait.
The above code waits until the element becomes clickable (i.e. displayed and enabled) and returns the result. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully. In this case, it tries up to 15 seconds before throwing a TimeoutException. A successful return value is either a Boolean value of true or a non-null object.
Some examples of ExpectedCondition predifined methods are,
- elementToBeClickable(Bylocator) – An expectation for checking an element is visible and enabled such that you can click it.
- elementToBeSelected(WebElementelement)- An expectation for checking if the given element is selected.
- presenceOfElementLocated(Bylocator) – An expectation for checking that an element is present on the DOM of a page.
- urlToBe(java.lang.Stringurl) – An expectation for the URL of the current page to be a specific url.
- visibilityOf(WebElementelement)- An expectation for checking that an element, known to be present on the DOM of a page, is visible.
All the available methods and their usage details for the ExpectedConditions package for Java can be found here.
Sticky Note: According to the Selenium’s official documentation, we are warned not to mix implicit and explicit waits as it can cause unpredictable wait times.
Fluent Wait
Who doesn’t like customization? For explicit waits, if that is what you are searching for, then I would suggest Fluent Wait. We can configure the following with the help of a fluent wait,
- maximum amount of time we wish to wait (timeout) for a condition to occur before throwing an exception,
- frequency with which the specified condition is to be checked and
- type of exceptions we would like to ignore while waiting for the condition to occur
Sample code snippet is as below,
public WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(20, TimeUnit.SECONDS)
.pollingEvery(2, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
}
Here we are declaring fluent wait with a timeout value of 20 seconds, polling the DOM every 2 seconds (frequency) until the element is found and ignoring NoSuchElementException during this time interval. We have created a new function in the above code snippet to identify this web element in .until();
Some points worth your time,
- Unlike implicit waits, this works on findElement(s) and any other condition that you might possibly think of encoutering while automating a web page.
- The default timeout value and frequency can be customised and applied only to specific elements unlike implicit wait which is applicable for the life of WebDriver object instance once initiated.
- We can either implement our own condition or use one of the predefined conditions from ExpectedConditions class.
- With FluentWait we have the power to ignore certain exceptions and specify a custom error message instead. This elevates our debugging experience to a whole new level.
- Fluent wait is much more reliable than implicit wait by ignoring particular exceptions until our condition is satisfied.
Agreed explicit wait includes more decoration to the code but don’t you think it’s worth the hassle?
Sticky Note: You might think, why go through all this pain? Can’t I just use Thread.sleep()? Hmmm, nope. It is not recommended as it puts the entire test script to sleep without a condition. In most cases the specified sleep time is either not enough resulting in an exception or becomes too long causing your test to wait even if the element loads faster.
Wearing my heart on my sleeve, final conclusion: Though explicit waits involve more programming part, due to it’s ability to resolve so many problems making our lives so much easier, I would prefer this over implicit waits (based on the requirement and complexity of the test automation involved wink).
Is your vision all blurry? Not to panic as all waters will settle in the posts to follow. We will see more practical examples of waits along with screenshots. A better understanding and grasp of this topic will be obtained once locator types and strategies are covered. So keep watching this space for more!
See you again in another post! Have a nice day!