Implicit Wait vs Explicit Wait

Guillermo Jose Aiquel
Virtualmind

--

Introduction

One important thing while writing UI automated tests for web apps, is to decide how to deal with “waits” between actions, how you know that the page and its elements are loaded, or that after taking an action on a web element, you are ready to continue with the next one.

Selenium provides two ways of dealing with this and you should decide between one or the other, but never mix them because that can cause unexpected behavior on your tests. They are called “Implicit Wait” and “Explicit Wait”.

The first one, the “Implicit Wait”, is set once for the life of the WebDriver object instance. By default it is set to 0 seconds but you can change it and define how much time (in seconds) WebDriver should wait for an element, every time it requests it, to be present on DOM before throwing a TimeoutException.

The “Explicit Wait” is code defined to wait for different conditions before proceeding with the next action. For example, you can wait for element presence or for state condition of specific elements, etc.

Implicit Wait

If you decide to use implicit wait, you define the maximum amount of time to wait for an element when requesting it, of course, if the element is available before reaching timeout, Selenium won’t wait anymore and will continue.

For example, for setting Wait Timeout on 10 seconds, you define it the same way:

Java

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get(“http://www.exampe.com/some-page");
WebElement myDynamicElement = driver.findElement(By.id(“myDynamicElement”));

This could be a good approach while testing really old web pages, where each action reloads the page and renders it again. Even in that case it is hardly useful, only works on findElement and findElements (not on sendKeys, click, etc), and it’s a waste of time while waiting for an element that should not exist on the web page. So, imagine the case of removing something from your application, and you should wait for it to disappear from the page, if the element disappears in 3 seconds, you will wait 7 extra seconds before continuing with the next action.

Another negative point is that Timeout is set only once, all findElements will wait for the same maximum period of time and it doesn’t matter if you know that one action should take more time than another. There is no way to adjust it for different situations, and on a testing point of view that is wrong, because you will probably need to make a test fail if some action takes more than 5 seconds, but you will wait 10.

Explicit Wait

In my experience it is the best choice and extremely necessary when testing dynamic web pages because you can control and define “waits” for each case, the code documents what the test does, how much is the maximum amount of time it should wait after each action and it can check for presence or absence of elements and works on any conditions you might need.

For example, after taking an action on a web element, you can wait for some condition on it or on any other element as following:

Java

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id(“someid”)));

Think about next situation: on a login form, after you fill all requested inputs, the page will check if the username you choose is valid and finally the submit button will change from disabled to enabled state. So the code above will work as expected and will throw a Timeout if and only when the element is not clickable before 10 seconds.

What would happen if you use Implicit Wait? After filling all requested inputs, the button will be available but as disabled, so your test will click the button and that action will not trigger any action, so then it fails.

But most powerful “Waits” beside the ones built in the Selenium driver, are the ones you can create and customize on your own. For example, you can create a method to wait until an element or its children change any state, either attribute or text, using the following code:

Java

final String startingOuterHtml = driver.findElement(By.id(“someid”)).getAttribute(“outerHTML”);
WebDriverWait wait = new WebDriverWait(driver, 10);
Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>() {

public Boolean apply(WebDriver input) {
String currentOuterHtml = driver.findElement(By.cssSelector(selector)).getAttribute(“outerHTML”).toString();
return !startingOuterHtml.equals(currentOuterHtml);
}
};
wait.until(function);

Let’s describe what the code above does step by step.

First of all, it gets HTML code for an element and its children and stores it on the startingOuterHtml variable. Then it creates a WebDriverWait instance with a timeout of 10 seconds. Then it declares a function that gets again the same element, gets its HTML code and its children HTML code, and finally compares it to the one gotten before. It must return true when you need the “wait” to stop, in this case, when the values are different.

The final step is just to call the until method from the WebDriverWait object created, with the function created before as the parameter. Until method will throw TimeoutException if the condition is not satisfied before timeout seconds configured while creating the WebDriverWait object.

So in this way, we have the ability to wait anytime wherever we want and as long as necessary. Like I said before, the code documents in a better way what test does, and you have the control.

Conclusion

We can think that Implicit Wait is there just because it should be; it is practically unrecommended mainly because your tests will have undefined behavior and nobody wants that.

On the other hand, Explicit Wait has several advantages over Implicit Wait and it is the best choice even if it makes your code more verbose. These advantages are:

  • tests are documented and have a defined behavior.
  • nested waits can be added.
  • more expected success conditions are available.
  • it can wait for presence or absence of elements/conditions.
  • timeout can be customized on every call.
  • it runs on your code instead of the remote selenium part.

Depending on your project and what you need, you will decide which wait strategy fits better, but remember not to mix them, and the most important thing; don’t be lazy and don’t use Implicit Wait!

Check our Virtualmind magic ✨
Our websiteFacebookTwitterInstagram

--

--