Using Implicit Wait in Selenium WebDriver

Agenda :-

  1. Introduction of implicit wait
  2. Working of implicit wait
  3. Disadvantages of implicit wait?

Previously we have seen “Using Thread.sleep() in Selenium WebDriver” and learnt why we need wait mechanisms in Selenium WebDriver. We implemented waiting mechanism using sleep() method provided by Thread class which is provided by Java. Let’s see what waiting mechanisms are provided by Selenium WebDriver.

Selenium WebDriver provides two types of dynamic waits :-

  1. Implicit Wait
  2. Explicit Wait

Note that I used the word “Dynamic waits“.

What is implicit wait?

Implicit wait specifies the amount of time the driver should wait when searching for an element if it is not immediately present. As we see in previous post that after typing “Ban” in From field, it takes some time to show the suggestions i.e. desired WebElement takes some time to be present or desired element is not present immediately. In this case we can use Implicit wait as well instead of sleep method.

Official java document says that When searching for a single element, the driver should poll the page until the element has been found, or this timeout expires before throwing a NoSuchElementException. When searching for multiple elements, the driver should poll the page until at least one element has been found or this timeout has expired.

You must be thinking, sleep() and implicit wait sound same in behavior then what is difference? Why should we use implicit wait over sleep()?

Because Implicit wait is a dynamic wait. When we use sleep() method, it makes the current thread idle unconditionally. It means if we set sleep timeout as 5 seconds, thread will wait for 5 seconds completely (If not interrupted). But if we use implicit wait, it waits for an element to be present but does not sit idle. It keeps polling for element and returns as soon as element is found.

So if we set implicit wait as 10 seconds and element is found in 5 seconds, driver will NOT wait for remaining 5 seconds. It saves 5 seconds of execution time. In short , sleep will sit idle for specified timeout and after timeout we need to look for element explicitly but implicit wait does both steps together and that too dynamically.

Syntax of implicit wait:

WebDriver interface contains an inner interface “Timeouts“. This interface consists of three methods :-

  1. Timeouts implicitlyWait(long time, TimeUnit unit);
  2. Timeouts setScriptTimeout(long time, TimeUnit unit);
  3. Timeouts pageLoadTimeout(long time, TimeUnit unit);

Class RemoteWebDriver has an inner class “RemoteTimeouts” which implements “Timeouts” interface. RemoteTimeouts overrides all above three methods. Let’s discuss about implicitlyWait method more in this post.

implicitlyWait method takes two parameters :-

  1. time :- The amount of time to wait
  2. unit :- The unit of measure for time of type TimeUnit. TimeUnit is an enum which provides constants like SECONDS, NANOSECONDS, MICROSECONDS etc.

implicitlyWait method returns a self reference i.e. Timeouts so that if you want to call any other method of Timeouts class.

Syntax :-

Step by step break up :-

// setting implicit time step by step
Options options = driver.manage();
Timeouts timeouts = options.timeouts();
timeouts.implicitlyWait(30, TimeUnit.SECONDS);

Using method chaining :-

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

If you want to know about above method chaining, refer this post.

Let’s implement implicit wait in stead of sleep in example from previous post.

Selenium Code :-

package WaitExamples.ImplicitWaitExamples;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import io.github.bonigarcia.wdm.WebDriverManager;

public class UsingImplicitWait {
	
	public static void main(String[] args) 
{
		
		WebDriverManager.chromedriver().setup();
		// Opening a browser
		WebDriver driver= new ChromeDriver();
		driver.manage().window().maximize();
		
		// setting implicit time step by step
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		
		// Loading a URL
		driver.get("https://www.redbus.in/");
		
		// Locating and typing in From text box. 
		WebElement fromTextBox= driver.findElement(By.id("src"));
		fromTextBox.sendKeys("Ban");
		
		System.out.println("Wait starts at :"+new Date());
		// Clicking on first search result
		driver.findElement(By.xpath("//li[@select-id='results[0]']")).click();
		System.out.println("Wait ends at:"+new Date());
		//Closing browser
		driver.quit();
		
	}

}

Output :-

Wait starts at :Sun Apr 19 11:25:22 IST 2020
Wait ends at:Sun Apr 19 11:25:23 IST 2020

Above program proves:

  1. We are able to make WebDriver to wait for locating web element using implicit wait.
  2. It is dynamic wait as WebDriver waited just for a second not for entire specified time. Many interviewer asked to prove this point. Just write above code and show it.

If a element is not found within specified timeout, WebDriver will throw NoSuchElementException not TimeOutException. This point also proves that implicit wait is only applicable for finding a web element of a list of web elements.

Let’s put a wrong locator so that it would not be able to locate element within timeout.

Selenium Code :-

package WaitExamples.ImplicitWaitExamples;

import java.util.Date;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import io.github.bonigarcia.wdm.WebDriverManager;

public class UsingImplicitWaitWithTimeOut {
	
	public static void main(String[] args) {
		
		WebDriverManager.chromedriver().setup();
		// Opening a browser
		WebDriver driver= new ChromeDriver();
		driver.manage().window().maximize();
		
		// setting implicit time step by step
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		
		// Loading a URL
		driver.get("https://www.redbus.in/");
	
		// Locating and typing in From text box. 
		WebElement fromTextBox= driver.findElement(By.id("src"));
		fromTextBox.sendKeys("Ban");
		
		System.out.println("Wait starts at :"+new Date());
		// Passing wrong locators and catching exception to show waiting time
		try {
		driver.findElement(By.xpath("//li[@select-id='results[30]']")).click();
		}catch(NoSuchElementException e)
		{
			e.printStackTrace();
		}
		System.out.println("Wait ends at:"+new Date());
		//Closing browser
		driver.quit();
		
	}

}

Output :-

Wait starts at :Sun Apr 19 11:41:21 IST 2020
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//li[@select-id='results[30]']"}
  (Session info: chrome=80.0.3987.163)
For documentation on this error, please visit: https://selenium.dev/exceptions/#no_such_element
Build info: version: '4.0.0-alpha-5', revision: 'b3a0d621cc'
System info: host: 'WKWIN6962993', ip: '192.168.0.6', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_231'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 80.0.3987.163, chrome: {chromedriverVersion: 80.0.3987.106 (f68069574609..., userDataDir: C:\Users\amomahaj\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:59081}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify}
Session ID: 5cab0ca00ca7f7447794a5b8d114c88e
*** Element info: {Using=xpath, value=//li[@select-id='results[30]']}
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:196)
	at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:129)
	at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:53)
	at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:161)
	at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
	at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:582)
	at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:333)
	at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:451)
	at org.openqa.selenium.By$ByXPath.findElement(By.java:394)
	at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:325)
	at WaitExamples.ImplicitWaitExamples.UsingImplicitWaitWithTimeOut.main(UsingImplicitWaitWithTimeOut.java:40)
Wait ends at:Sun Apr 19 11:41:52 IST 2020

Observe above that implicit wait makes WebDriver to wait for 30 seconds which is timeout specified by implicit wait in case element is not found.

Do we need to write multiple implicit wait statements like Thread.sleep()?

  • We have seen that you need to write Thread.sleep() wherever you want WebDriver to wait. It is not the case with Implicit wait. Once you set implicit wait, it will be applicable to all calls of findElemnt() and findElements() methods. There is no need to write implicit wait code again and again before locating an element. Reason behind this is that implicitlyWait() method sets the timeout for driver not for an individual element. So whenever we find a element or list of elements, set implicit wait will be applicable.
  • If you write implicit wait statement multiple times, time specified in latest implicit wait statement will be applicable. For example: You specify implicit wait as 30 seconds at line no 5 and another implicit wait as 60 seconds at line no 10, then implicit wait as 30 seconds will be applicable for all calls to findElement() and findElements() methods from line no 6-9 and implicit wait as 60 seconds will be applicable from line no 11 onward. So, if interviewer asks you how to change implicit time, you can answer easily.
  • The default setting is Zero and polling interval depends upon browsers. Different browser have different polling interval time. Selenium does not bother about that as it serves the purpose at the end by any means. Since implicit wait is set for WebDriver session, that is the reason setting polling interval is not possible like we do for WebDriverWait and FluentWait. In WebDriverWait and FluentWait actually we have retry mechanism rather than holding the control at a statement till element is found or condition is satisfied.

Disadvantages of using implicit wait in Selenium:

  • Java doc says that Increasing the implicit wait timeout should be used judiciously as it will have an adverse effect on test run time, especially when used with slower location strategies like XPath.
  • You can not wait till some specific condition is satisfied like invisibility of element, when alert is present etc.
  • A major disadvantage is that it does not wait till all elements are found when we use findElements().

If a list of web elements appears with some delay, implicitly wait will not let WebDriver wait till all elements are displayed. It returns as soon as it finds the first element.

Sample HTML code :-





Calling a Function Repeatedly with setInterval() Method




    

In above web page, three buttons will appear at intervals of 5,10 and 15 seconds respectively. Let’s set a implicit wait and call findElements method and observe output.

Selenium Code :

package WaitExamples.ImplicitWaitExamples;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import io.github.bonigarcia.wdm.WebDriverManager;

public class UsingImplicitWaitWithFindElements {
	
	public static void main(String[] args) {
		
		WebDriverManager.chromedriver().setup();
		// Opening a browser
		WebDriver driver= new ChromeDriver();
		driver.manage().window().maximize();
		
		// setting implicit time step by step
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		
		// Loading a URL
		String fileURL = System.getProperty("user.dir");
		driver.get(fileURL + "/src/test/resources/htmlFiles/ElementsWithDelay.html");
		
		// Locating and typing in From text box. 
		System.out.println("Wait starts at :"+new Date());
		List allButtons = driver.findElements(By.xpath("//button[@style != 'display: none;']"));
		System.out.println("Wait ends at:"+new Date());
		System.out.println("Size of found buttons : "+allButtons.size());
		//Closing browser
		driver.quit();
		
	}

}

Output :

Wait starts at :Sun Apr 19 12:59:52 IST 2020
Wait ends at:Sun Apr 19 12:59:57 IST 2020 Size of found buttons : 1

So point is proved that implicit wait for findElements() will not wait till all elements are found. It will return whatever elements are available when it finds a match.

You can clone the above example from my repo.

If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappyLearning

You can find all Selenium related post here.
You can find all API manual and automation related posts here.
You can find frequently asked Java Programs here.

17 thoughts on “Using Implicit Wait in Selenium WebDriver”

  1. The default polling interval for explicit wait is 500 milliseconds, plz let us know what is the default polling interval for implicit wait??

    1. Implicit wait is dependent on driver implementation i.e. browser. We have an API in JSON Wire Protocol to set implicit wait. As we know that implicit wait is set for driver session which also proves that mechanism of implicit wait depends upon browsers.

  2. “If you use the implicit wait in selenium it applies to the web driver globally and increases the execution time for the entire script.”
    Why does this increase the execution time of the script?? I read that so often but never understood this part. This is a dynamic wait, means if the element could be found the script is going on with the next script command and it does not wait until the whole implicit waiting time is over. If the element cannot be found it does not make any sense to go on. So we need to wait until the element we want to be found is really found. Elements found earlier do not wait anymore.
    And if we (for whatever reason) need to use a slower location strategy like xpath, still we need to wait until the element with our slow xpath is found. Then not the implicit wait method is bad, the location strategy is. So why to be careful using implicit waits??

    1. Once you set implicit wait, it will be used whenever webdriver will try to find any webelement or webelements. Suppose you have a scenario where you need to check element should not be present. You will try to locate element and when it throws no such element exception the you will conclude that Yes webelement is not found and your test is pass. If you use implicit wait, it will wait till your specified timeout occurs not before that. Just imagine you have many such scenarios. There are other disadvantages of using implicit waits as well.

  3. Hi Amod,
    I have used the same code but still getting error:
    org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {“method”:”xpath”,”selector”:”//li[@select-id=’results[0]’]”}

    I have checked the Xpath as well it is same for this element .
    Please guide me.

  4. Well Explained Amod. But,in one place you used the term explicit wait.
    1)Behaviour of Explicit wait when time runs out.
    Hope it is a typo.

    Thanks,
    Priya.

Leave a Reply

Your email address will not be published. Required fields are marked *