Waits in Selenium from scratch

Reading Time: 6 minutes

Hi folks,

Initially, In this blog we will learn about what and why part of selenium waits, then we will briefly see all the types of selenium waits. At the end of this blog, we will discuss why we should not consider the Thread.sleep() method for best practices.

It has been proven that selenium is a good framework for automation testing. Automation testing has accelerated  the whole testing process. Although we consider speed as a vital thing while testing an application, Sometimes you need to slow down and wait. Speeding up and slowing down are contradictory, But if you want quality and accuracy then it’s ok to wait when required.

Why “waits” in selenium

Now let’s understand why this wait concept is there in the selenium web driver:

Waits are in the selenium web driver to resolve the synchronization problem. Synchronization problem occurs when two things do not have the same speed.

  1. Software under test / Application under test [not having constant speed]
  2. Selenium [constant speed]

Suppose you enter a username password and if you click on the login button then it takes a little time to load the next page. But if the selenium is not waiting and firing the next command. in this case, you will get a message  “NoSuchElementException”.

We can say this problem is a synchronization problem and to overcome this we have selenium wait commands in the selenium web driver.

What is “wait” in selenium

Selenium waits are used to pause the execution of the code for a moment. We use it to wait for elements of the application to load so that actions can be performed on them.

Types of waits

Now, We will discuss different types of waits in selenium. There are mainly three types of waits in selenium.

  • Implicit Wait
  • Explicit Wait
  • Fluent Wait

1. Implicit Wait

  • In implicit wait, We tell web driver to wait for a certain amount of time when the selenium web driver tries to find out an element/elements if they are not immediately available. We should note that implicit waits are globally applicable, Which means they will be in place for the entire time the browser is open.
  • In other words, We can say that we use implicit wait when we want to configure the web driver’s wait time as a whole for the application under test.
  • Suppose that we have hosted a web-based application on a local server and a remote server. Clearly, the time to load for a web page hosted on a local server will be less than the time for the same page hosted on a remote server, because of network latency. At the moment, if we want to execute our test cases against each of them, we may have to configure the wait time suitably, such that our test case does not end up spending more time waiting for the page or spending far too little time and timeout. To deal with these kinds of wait time issues, web driver will give an option to set the implicit wait time for all of the operations that the driver does using the manage() method.

When to use implicit wait

When we want to state a maximum wait time, which is generally common for most of the web elements on your web-based application. Based on those conditions as a developer of your web driver test cases, we have to arrive at a value for the maximum implicit wait time, such that our test cases do not take much time to execute and at the same time do not get timed out very frequently.

Example of implicit wait with java implementation

public class ImplicitWait {
    public static void main(String[] args) {

System.setProperty("webdriver.chrome.driver","/home/knoldus/Documents/selenium/chromedriver_linux64/chromedriver");

        WebDriver driver = new ChromeDriver();
        
        //setting implicit wait//
        driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
        
        //navigate to gmail.com//
        driver.get("https://www.gmail.com");
        
        //input of mail id//
        driver.findElement(By.xpath("//*[@type='email']")).sendKeys("xyz@gmail.com");
        
        //navigate to next button and click//
        driver.findElement(By.id("identifiernext")).click();
        
        //input of password and click//
        driver.findElement(By.xpath("//*[@name='password']")).sendKeys("password");
        driver.findElement(By.xpath("//*[type='Next']")).click();
    }
}

2. Explicit Wait

  • We can simply say the explicit wait is conditional wait. Explicit wait tells the web driver to wait for certain conditions before it exceeds maximum time.
  • Explicit Wait plays a vital role in scenarios where some of the web elements take much time to load. We can apply explicit wait for specific elements on the page which take more time to load.
  • Let’s suppose, we are testing an application that displays an alert box. Developers designed the application in such a way the moment we enter some text in a text box and click on the Next button, a prompt or an alert box is displayed. The time taken for the alert box to display its content depends on distinct factors for instance user input, server response time & network can use an explicit wait in cases where we know we have to wait for the alert box to be displayed but we do not know how much time it would take for the alert box to be displayed.

When to use explicit wait

When we want to wait for any condition we might need. Normally, we use some of the pre-built expected conditions to wait for elements to become clickable, visible, invisible, etc.

Explicit wait conditions in selenium webdriver

  • alertIsPresent()
  • elementSelectionStateToBe()
  • elementToBeClickable()
  • elementToBeSelected()
  • frameToBeAvaliableAndSwitchToIt()
  • invisibilityOfTheElementLocated()
  • invisibilityOfElementWithText()
  • presenceOfAllElementsLocatedBy()
  • presenceOfElementLocated()
  • textToBePresentInElement()
  • textToBePresentInElementLocated()
  • textToBePresentInElementValue()
  • titleIs()
  • titleContains()
  • visibilityOf()
  • visibilityOfAllElements()
  • visibilityOfAllElementsLocatedBy()
  • visibilityOfElementLocated()

Example of explicit wait with java implementation

public class ExplicitWait {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver","/home/knoldus/Documents/selenium/chromedriver_linux64/chromedriver");
        WebDriver driver = new ChromeDriver();

        //setting explicit wait//
        WebDriverWait wait = new WebDriverWait(driver, 20);

        //navigate to gmail.com//
        driver.get("https://www.gmail.com");

        //input of mail id//
        WebElement gmail = driver.findElement(By.xpath("//*[@type='email']"));
        wait.until(ExpectedConditions.visibilityOf(gmail));
        gmail.sendKeys("xyz@gmail.com");

        //navigate to next button and click//
        driver.findElement(By.id("identifiernext")).click();

        //input of password and click//
        driver.findElement(By.xpath("//*[@name='password']")).sendKeys("password");
        driver.findElement(By.xpath("//*[type='Next']")).click();
    }
}

3. Fluent Wait

  • We can simply say that fluent wait is the type of conditional wait but with frequency. It means we can use fluent wait to wait for a condition with a regular frequency/time interval to be checked before throwing “ElementNotVisibleException”.
  • Every fluent wait instance defines the maximum amount of time to wait for a specified condition, along with frequency to check the condition. Moreover, the user may configure the wait to ignore specific types of exceptions while waiting, such as NoSuchElementExceptions when the user wants to search for an element on the page.
  • Let’s say we have an element which that sometimes appears in just 1 second and some time it takes minutes to appear. In this case, It will be better to use fluent wait, as fluent wait tries to find elements again and again until it finds the element or until the final timer runs out.

When to use fluent wait

We use fluent wait commands mainly when we have web elements that are sometimes visible in a few seconds and sometimes take more time than usual. Mainly in Ajax applications. We can set the default polling period based on our requirements. We can pass over any exception while polling an element.

Example of fluent wait with java implementation

public class FluentWait {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver","/home/knoldus/Documents/selenium/chromedriver_linux64/chromedriver");
        WebDriver driver = new ChromeDriver();

        //setting explicit wait//
        WebDriverWait wait1 = new WebDriverWait(driver, 20);

        //navigate to gmail.com//
        driver.get("https://www.gmail.com");

        //input of mail id//
        WebElement gmail = driver.findElement(By.xpath("//*[@type='email']"));
        gmail.sendKeys("xyz@gmail.com");
        FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                .withTimeout(30, TimeUnit.SECONDS)
                        .pollingEvery(5, TimeUnit.SECONDS)
                                .ignoring(NoSuchElementException.class);
        
        WebElement nextbutton = wait1.until(new Function<WebDriver, WebElement>() {
            public WebElement apply(WebDriver webDriver) {
                WebElement next=driver.findElement(By.id("identifierNext2"));
                return next;
            }
        });
        nextbutton.click();

        //input of password and click//
        driver.findElement(By.xpath("//*[@name='password']")).sendKeys("password");
        driver.findElement(By.xpath("//*[type='Next']")).click();
    }
}

Why we should not use Thread.sleep() ?

  • One of the ways to achieve synchronization, implement wait is by calling the Thread.sleep function however, it is not a good idea to use Thread.sleep because this is not very stable and unreliable. The time has to be specified in milliseconds.
  • According to me, We consider Thread.sleep is the worst case of an explicit wait because of Thread.sleep. Where it waits for the full time specified as the argument of Thread.sleep, Before proceeding further.
  • it is not related to other waits such as Implicit wait, Explicit wait and Fluent wait, So you should not get confused due to commonality in the sync method in Selenium and Thread.sleep.
  • When we talk about the downside of Thread.sleep, There is a bit chance of needless waiting time even though the application is ready.
  • We can fulfil synchronization using Thread.Sleep. however, is not considered good practice in programming. As it’s the same thing that we are asking selenium to stop executing for given some milliseconds so that our control could be loaded and it is not guaranteed that within that hardcoded some value in milliseconds, Control could be fully loaded and our test code could be executed safely.

Ex: Thread. Sleep (20000);

Here the execution halts for 20 Seconds, even if the object we are looking for exists at that instant. So it unnecessarily waits for 20 seconds or Control exists after 10 seconds. So here also selenium needless waits for more than 10 seconds.

That’s all for this blog and you can click here to read other blog and explore more about selenium waits.

References

https://www.selenium.dev/documentation/webdriver/waits/

Written by 

Sujeet is a Software Consultant(Test Automation) at Knoldus Software. Knoldus does niche Reactive and Big Data product development on Scala, Spark, and Functional Java. He is always charged up for new things & learning. He is dedicated to his work and believes in quality output. On a personal front, he loves to play volleyball and is a big foodie.

1 thought on “Waits in Selenium from scratch9 min read

Comments are closed.