Enterprise Java

Selenium Waits: Implicit, Explicit, Fluent And Sleep

Selenium waits for page load play an important part in your Selenium scripts. They help to make them less flaky and more reliable. Selenium provides multiple waits to provide adequate wait or pause in your script execution based on certain conditions. Thereby ensuring you don’t end up getting failed scripts as you perform automation testing with Selenium. In this tutorial, we will be explaining the types of Selenium waits and sleep, there real-time examples and a comparison study on them. Let us start by answering a pivotal question “Why should we use Selenium waits?”

Why Do We Need Selenium Waits?

Majority of modern application’s front-end is built on JavaScript or Ajax, using frameworks such as React, Angular, or any other which takes a certain time for the web elements to load on the page, whenever that page is loaded or refreshed. Hence, in case you tend to locate an element in your script which is yet to load on the page, selenium will throw you ‘ElementNotVisibleException’ message.

Below code snippet will help you showcase the same problem as you execute automation testing with Selenium. In this code snippet, I am using an example of easemytrip.com, where post user selects the ‘From’ and ‘To’ destination with a date of journey, the web application takes a certain time to load the required flight details. In this case, without applying wait, the user tends to book the first flight from the list. Now, since the page hasn’t loaded yet, the script failed to find the ‘book now’ button. Resulting in throwing a ‘NoSuchElementException’. Code snippet and console output below:

01
02
03
04
05
06
07
08
09
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
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
  
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor;
  
public class NoWaitImplemented {
  
    public static void main(String[] args) throws InterruptedException {
         
        System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
         
        WebDriver driver=new ChromeDriver();
         
        driver.manage().window().maximize();
         
         
        driver.get("https://www.easemytrip.com/");
         
        driver.findElement(By.id("FromSector_show")).sendKeys("Delhi", Keys.ENTER);
        driver.findElement(By.id("Editbox13_show")).sendKeys("Mumbai", Keys.ENTER);
        driver.findElement(By.id("ddate")).click();
        driver.findElement(By.id("snd_4_08/08/2019")).click();
        driver.findElement(By.className("src_btn")).click();
        driver.findElement(By.xpath("//button[text()='Book Now']")).click();
     
         
         
         
  
    }
  
}

Console Output:

I have made use of XPath for locating web elements using the scripts for automation testing with Selenium.

Read More: Complete Guide For Using XPath In Selenium With Examples

Selenium wait for a page to load helps in resolving this issue. There are different types of Selenium waits like Implicit wait and Explicit wait, that ensures the elements are loaded into the page before they are discovered by the Selenium script for further actions.

Types of Selenium Waits For Page Load

When performing automation testing with Selenium, we use the following types of waits as we generate our Selenium script:

  • Thread.Sleep() method
  • Implicit Wait
  • Explicit Wait
  • Fluent Wait

Let us understand each one of these in-depth.

Thread.Sleep() For Automation Testing with Selenium

Sleep is a static method that belongs to the thread class. This method can be called using the reference of the class name i.e Thread. If you use Thread.sleep while performing automation testing with Selenium, then this method will stop the execution of the script for the specified duration of time, irrespective of whether the element is found or not on the web page. It accepts the time duration in milliseconds. The syntax for the same is:

Thread.sleep(3000);

The sleep function throws InterruptedException so it should be handled using a try-catch block as below:

1
2
3
4
5
try{
Thread.sleep(5000);
}
catch(InterruptedException ie){
}

Why Using Thread.Sleep() Is Not A Good Idea?

I will now be highlighting some disadvantages of using the thread.sleep().

  • Selenium Webdriver waits for the specified time, irrespective of the element is found or not. In case the element is found much before the specified duration, the script will still wait for the time duration to elapse, thereby increasing the execution time of the script.
  • If the element to be present does not appear after a static time and keep changing, then you will never know an estimated time needed for the sleep function. In case it takes more time than the defined time, the script shall throw an error. Which is why, if you are dealing with dynamic elements using Selenium waits then it is wise to not use Thread.sleep().
  • Thread.sleep is intended only for the element it is written prior to. In case you have two to fours elements which need to wait for a certain duration to load, you need to specify Thread.sleep as many times in that case. And if you do that! Well, you will find your script filled with Thread.sleep() syntax all over the place.

Owing to the above disadvantages, using Thread.Sleep() in your script creation is considered as a bad practice.

The below code snippet highlights the usage of Thread.Sleep() for automation testing with Selenium. In this example, we are using the same example of easemytrip above, where we will stop the thread execution, once the user clicks on search. The code works smoothly in this case, without throwing any error.

01
02
03
04
05
06
07
08
09
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
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
  
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor;
  
public class ThreadWait {
  
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
         
        //setting the driver executable
        System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
         
        //Initiating your chromedriver
        WebDriver driver=new ChromeDriver();
         
        driver.manage().window().maximize();
         
         
        driver.get("https://www.easemytrip.com/");
         
        driver.findElement(By.id("FromSector_show")).sendKeys("Delhi", Keys.ENTER);
        driver.findElement(By.id("Editbox13_show")).sendKeys("Mumbai", Keys.ENTER);
        driver.findElement(By.id("ddate")).click();
        driver.findElement(By.id("snd_4_08/08/2019")).click();
        driver.findElement(By.className("src_btn")).click();
        Thread.sleep(5000);
        driver.findElement(By.xpath("//button[text()='Book Now']")).click();
         
         
         
         
  
    }
  
}

Now, what if I have another page of the same application that takes a certain time to load? In this case, I would not prefer to use, thread.sleep() multiple times in my script.

You may be thinking that if not Thread.sleep(), then which Selenium wait for page load will suffice the testing requirement?

This is where Implicit wait comes to rescue in such cases. Let us checkout Implicit Selenium wait in detail.

Implicit Wait For Automation Testing with Selenium

Selenium has overcome the problems provided by Thread.sleep() and have come up with two Selenium waits for page load. One of which is Implicit wait which allows you to halt the WebDriver for a particular period of time until the WebDriver locates a desired element on the web page.

The key point to note here is, unlike Thread.sleep(), it does not wait for the complete duration of time. In case it finds the element before the duration specified, it moves on to the next line of code execution, thereby reducing the time of script execution. This is why Implicit wait is also referred to as dynamic wait. If it does not find the element in the specified duration, it throws ElementNotVisibleException.

Another interesting thing to note about Implicit wait is that it is applied globally, which makes it a better option than Thread.sleep(). Meaning you only need to write it one time and it gets applicable for all of the web elements specified on a script throughout the WebDriver instance. Convenient isn’t it? The syntax to achieve the same is:

1
driver.manage().timeouts().implicitlyWait(Time Interval to wait for, TimeUnit.SECONDS);

The default time for Implicit wait is zero and it keeps polling for the required element after every 500 milliseconds. Let’s see the code snippet below, showcasing the use of Implicit wait. In this example, I am using the same easemytrip example. In this case, we are going a step ahead and continuing the booking process, where the page takes more time to load. Here the page load issue exists for two pages, which we are dealing using a single line of code using implicit wait rather than using Thread.sleep() multiple times.

01
02
03
04
05
06
07
08
09
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
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.Select;
  
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor;
  
public class ImplicitWait {
  
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
         
        //setting the driver executable
        System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
         
        //Initiating your chromedriver
        WebDriver driver=new ChromeDriver();
         
        driver.manage().window().maximize();
         
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get("https://www.easemytrip.com/");
         
        driver.findElement(By.id("FromSector_show")).sendKeys("Delhi", Keys.ENTER);
        driver.findElement(By.id("Editbox13_show")).sendKeys("Mumbai", Keys.ENTER);
        driver.findElement(By.id("ddate")).click();
        driver.findElement(By.id("snd_4_08/08/2019")).click();
        driver.findElement(By.className("src_btn")).click();
  
        driver.findElement(By.xpath("//button[text()='Book Now']")).click();
         
        JavascriptExecutor jse = (JavascriptExecutor)driver;
        jse.executeScript("window.scrollBy(0,750)");
         
        driver.findElement(By.xpath("//input[@type='email']")).sendKeys("sadhvisingh9049@gmail.com");
         
        driver.findElement(By.xpath("//span[text()='Continue Booking']")).click();
         
        WebElement title=driver.findElement(By.id("titleAdult0"));
         
        Select titleTraveller=new Select(title);
         
        titleTraveller.selectByVisibleText("MS");
        driver.findElement(By.xpath("//input[@placeholder='Enter First Name']")).sendKeys("Sadhvi");
        driver.findElement(By.xpath("//input[@placeholder='Enter Last Name']")).sendKeys("Singh");
         
        driver.findElement(By.xpath("//input[@placeholder='Mobile Number']")).sendKeys("9958468819");
         
        driver.findElement(By.xpath("//div[@class='con1']/span[@class='co1']")).click();
         
  
    }
  
}

Now, here we are aware of the fact, that pages shall we loaded in a certain duration, but what if we do not know the element to be visible/clickable at loading time. As in the time of its appearance is dynamic and keeps on changing from time to time. In this case, Explicit wait will help you overcome this problem. Let’s investigate its detail.

Explicit Wait For Automation Testing with Selenium

The Explicit wait is another one of the dynamic Selenium waits. Explicit wait help to stop the execution of the script based on a certain condition for a specified amount of time. Once the time goes overboard, you will get the ElementNotVisibleException. In a scenario where you do not know the amount of time to wait for, this explicit wait comes in handy. Using conditions like elementToBeClickable() or textToBePresentInElement(), one can wait for the specified duration. One can use these predefined methods using the combination of classes WebDriverWait and ExpectedConditions. In order to use this case, import the below packages in your class:

1
2
import org.openqa.selenium.support.ui.ExpectedConditions
import org.openqa.selenium.support.ui.WebDriverWait

Post this one needs to create a reference variable for the WebDriverWait class and instantiate it using the WebDriver instance and providing the amount of Selenium wait for page load, one may need. The unit of time is in seconds. One can define it as below:

1
WebDriverWait wait = new WebDriverWait(driver,30);

In order to use the predefined methods of the ExpectedCondition Class, we will use the wait reference variable as below:

1
wait.until(ExpectedConditions.visibilityOfElementLocated(Reference of Element to be  located using locator));

Types of Expected Conditions:

Below are the few types of expected conditions commonly used as you perform automation testing with Selenium.

  • visibilityOfElementLocated()- Verifies if the given element is present or not
  • alertIsPresent()- Verifies if the alert is present or not.
  • elementToBeClickable()- Verifies if the given element is present/clickable on the screen
  • textToBePresentInElement()- Verifies the given element have the required text or not
  • titlels()- Verify the condition wait for a page that has a given title

There are many more expected conditions available, which you can refer through the Selenium official GitHub page. Like Implicit wait, the explicit wait also keeps polling after every 500 milliseconds.

Below is the code snippet highlighting the usage of an Explicit Selenium wait. In this example, we are using the ‘rentomojo’ application, where a modal appears at a dynamic time on the homepage. Using explicit wait, based on the element visibility, we will wait for the element and close the pop-up. Referenced code:

01
02
03
04
05
06
07
08
09
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
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
  
public class ExplicitWait {
  
    public static void main(String[] args) {
        // TODO Auto-generated method stub
         
        //setting the driver executable
                System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
                 
                //Initiating your chromedriver
                WebDriver driver=new ChromeDriver();
                 
                 
                 
                driver.manage().window().maximize();
                 
                driver.get("https://www.rentomojo.com/");
                 
                driver.findElement(By.xpath("//span[@class='rm-city__selectorBoxLoca'][contains(text(),'Delhi')]")).click();
                 
                 
                 
                WebDriverWait wait=new WebDriverWait(driver, 120);
                 
                 
                wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//div[@class='Campaign__innerWrapper']/button"))));
                driver.findElement(By.xpath("//div[@class='Campaign__innerWrapper']/button")).click();
  
    }
  
}

Note- When implicit wait and explicit wait are given in conjunction, then they work on cumulative time, rather than on a single wait condition. For example, if the Implicit wait is given for 30 seconds and the Explicit wait is given for 10 seconds, then the explicit element it is looking for will wait for 40 seconds.

The Difference Between Selenium Waits: Explicit Vs Implicit

Now, since you are aware of the usage of implicit and explicit waits, let us investigate the difference between these 2 Selenium waits:

Implicit Wait

Explicit Wait

It is by default applied to all the elements in the script.It is applicable to only a certain element which is specific to a certain condition.
We cannot wait based on a specified condition like element selectable/clickable unlike explicit.In explicit, we can specify the wait based on a specific condition.
It is usually used when you are sure the element may be visible in a certain timeIt is usually used, when you are not aware of the time of the element visibility. It is subjected to dynamic nature.

Fluent Wait For Automation Testing with Selenium

The Fluent wait is similar to explicit wait in terms of its functioning. In Fluent wait, you perform a Selenium wait for an element when you are not aware of the time it may take to be visible or clickable. The few differential factors that Fluent wait offers are:

  • The polling frequency- In case of Explicit wait, this polling frequency is by default 500 milliseconds. Using Fluent wait, you can change this polling frequency based on your needs, i.e you can tell your script to keep checking on an element after every ‘x’ seconds.
  • Ignore Exception- During polling, in case you do not find an element, you can ignore any exception like ‘NoSuchElement’ exception etc.

Apart from these differential factors, like Explicit wait or Implicit wait, you can define the amount of time to wait for the element to be visible or actionable. The below syntax or lines of code are used to define Fluent wait in Selenium:

1
2
3
4
5
6
7
8
Wait<WebDriver> fluentWait = new FluentWait<WebDriver>(driver)
       .withTimeout(60, SECONDS) // this defines the total amount of time to wait for
       .pollingEvery(2, SECONDS) // this defines the polling frequency
       .ignoring(NoSuchElementException.class); // this defines the exception to ignore
      WebElement foo = fluentWait.until(new Function<WebDriver, WebElement>() {
     public WebElement apply(WebDriver driver)  //in this method defined your own subjected conditions for which we need to wait for
     {  return driver.findElement(By.id("foo"));
}});

The syntax appears to be complex, but once you start using, it may become handy. Probably this is one of its biggest reason where testers opt to go for explicit wait more than Fluent wait. Also, the major difference between the Explicit wait and the Fluent wait is, that the Explicit Selenium Wait provides predefined conditions, which are applied on elements we need to wait for, whereas, in case of Fluent Selenium wait, you can define your own customized conditions within the apply method.

My opinion on Fluent Selenium Wait?

I personally haven’t found any useful implementation of fluent wait in a real-time example, hence would like to refrain myself from the implementation of it, as of now. I am as eager as you, for the launch of Selenium 4. I am hoping that after the launch we may get more insights on the practical advantage of using Fluent wait over the other Selenium waits. So far based on my experience, I happen to lean towards the use of Explicit Selenium wait, owing to its easier implementation of code than Fluent Selenium wait. If you feel otherwise then let me know in the comments below.

Role Of Selenium Waits For Cloud-Based Selenium Grid

Majority of testers usually prefer to perform automated website testing using a cloud-based service provider for Selenium testing such as LambdaTest, a cross browser testing tool on cloud. Wondering why?

So what happens if you are running your automation scripts on a cloud-based Selenium Grid such as LambdaTest? How can Selenium waits contribute to an effective test result?

Every cloud-based provider will offer a default time limit before throwing Selenium timeout exception. This is done to prevent over-exploitation of the cloud’s resources. At LamdaTest, you get a default timeout of 90 seconds. Now, if your loading time for web elements is more than 90 seconds then what can you do?

This is where Selenium wait comes into the picture. If your test suite is a complex one, which may face a timeout issue on cloud Selenium Grid then you can use Selenium wait to pause the WebDriver for more than 90 seconds default time limit. Thereby, avoiding a timeout error as you successfully run your automation script.

The Final Verdict On Selenium Waits!

Selenium Waits helps to make your scripts less flaky and more reliable. Whichever wait you choose to go with, make sure it does the business to help you achieve your purpose behind automation testing with Selenium. Another key thing to note is to ensure not keeping unnecessary Selenium waits in your application. Thread.sleep() may have been an option in the past, but now that we have new Selenium waits up & coming, I would rather recommend you to drive your Selenium automation testing away from Thread.sleep(). So, the next time, you are stuck with the elements or page loading issue, you know where to look for. Happy testing!

Published on Java Code Geeks with permission by Sadhvi Singh, partner at our JCG program. See the original article here: Selenium Waits: Implicit, Explicit, Fluent And Sleep

Opinions expressed by Java Code Geeks contributors are their own.

Sadhvi Singh

Sadhvi Singh is a QA Manager. In 7 years of her professional journey, she has worked on multiple domains and testing techniques like Automation testing, Database testing, API testing, Manual testing, and Security testing. With multiple tools exposure added to her experience, she has skilled herself further through her two major accolades at International level through ISTQB with foundation and advanced levels. She has a technical blog named as qavibes.blogspot.com where she caters to all the challenges offered in the day to day journey of the quality assurance aspirants. In her spare time, she also works as a technical trainer and mentor to many budding QA professionals.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Jochen Delabie
4 years ago

Another cloud provider is https://testingbot.com which offers over 1800 browser and mobile device combinations to run your Selenium tests. It records a screencast of your test, together with screenshots and log files to easily see test results.

Back to top button