Know the role of Thread.sleep() in Selenium

Learn Thread Sleep Command in Selenium Java to use it effectively when running Selenium Tests on Real Devices & Browsers

Get Started free
Home Guide Understanding Role of Thread.sleep() in Selenium

Understanding Role of Thread.sleep() in Selenium

By Sonal Dwivedi, Community Contributor -

Automation testing of web applications uses automation tools to execute the test cases instead of a human manually executing them. It has benefited many organizations by reducing the time of manually testing the build/product, increasing test coverage, supporting cross browser testing, and leveraging automatic concise reports for better debugging.

Creating a robust automation framework is the desire of every automation tester. To achieve this, it is a must to write test cases in such a manner that automation test results are always genuine. 

However, at times it is observed that there are some failures while running the automation suite, and the same use case, when performed manually, actually passes the test. Such cases make tests flaky, causing false positives. Hence, it is essential to find a workable solution that can reduce flakiness and enhance the overall test accuracy.

Why do you need wait commands in Selenium?

Most modern web applications are built using Ajax and JavaScript and are based on popular frameworks such as AngularJS and ReactJS. These technologies take a certain time to load elements when the page is loaded for the first time or refreshed. 

While using browser automation and trying to locate web elements in such applications using Selenium, it cannot find the element as the event happens in a fraction of a second, and hence it throws NoSuchElementException.

This might be quite surprising since you can easily see the element present on the DOM while inspecting the page. This is one of the unpredictable behaviours, which needs to be handled by applying proper wait commands.

Providing proper wait commands in Selenium script is very important as they make the scripts more reliable, thereby ensuring automation yields accurate results.

Types of Selenium Wait Commands

Implicit wait: This is used to tell the WebDriver to wait for a certain amount of time before it throws a “NoSuchElementException”. This wait is applied globally, which means that the same wait mechanism will work for all the elements in the given code.

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

In the above example, if the element is not located on the webpage within 20 secs, it will throw an exception automatically.

  • Explicit wait: This is used to tell the WebDriver to wait for certain expected conditions or maximum time exceeded before throwing an “ElementNotVisibleException” exception. It is an intelligent kind of wait but can be applied only for specified elements.
WebDriverWait wait=new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOf(element));

In this case, Webdriver will wait explicitly for 20 secs for the element to be visible, and if it is not visible, it will throw an exception.

Why and when to use Thread.sleep in Selenium?

Now, the question arises, if Selenium provides these two types of wait commands, why would an automation tester opt for using Thread.sleep(). It would be interesting to know the role of Thread.sleep() command. 

Below are some of the scenarios where Thread.sleep() comes to the rescue when none of the wait mechanisms works.

1.  Testing dynamic Web Elements

Many web applications have a carousel implementation to display dynamic content. If you need to verify the visibility of the next item in the carousel, it is always better to use Thread.sleep() instead of Selenium waits as the carousel items are very dynamically displayed.

2. Third-party testing

Nowadays, almost every web application has integration with third-party websites. Along with testing AUT (Application Under Test), you also need to validate that after clicking on any third-party link, it navigates to the valid webpage, and the page loads properly. 

To assert this behaviour it is wise to use Thread.sleep() as it is very unpredictable to verify the load time of any third-party website.

3. Switching Windows or Tabs

Clicking on some of the links on the webpage opens them in a new browser window tab or a new browser instance. In such cases, to perform browser automation tests, you need to switch the driver to the new browser window tab/ browser instance and perform actions on it. 

When you switch and directly perform any automation event, it will throw NoSuchElementException as the WebDriver has just switched and it is unable to locate the element. Applying Thread.sleep() after the switch command helps to solve this.

4. Switching iFrame

Some web applications use iframe within the webpage. In such cases, to perform any action on the iframe elements, you first need to switch to the iframe and then perform the required action on it.

When you switch and perform any automation event on the iframe web elements without applying any wait, Selenium will throw NoSuchElementException. Thread.sleep() can be applied after the iframe switch command to avoid the exception.

Thread.Sleep in Selenium Java

While the above scenarios justify why Thread.sleep() command in Selenium Java is important. Let’s understand Thread.sleep() function in detail using some points below:

  • As per the official definition from the Oracle Java Documentation, Thread.sleep() causes the current thread to suspend execution for a specified period.
  • Thread.sleep() is not a Selenium wait, it is provided by Java.
  • It suspends the code for the specified time and can be useful in debugging the script under test.

Thread class is a class present in Java.lang package that is basically a thread of execution of the programs.

Thread class has two overloaded sleep methods, Thread.sleep(long millis) and Thread.sleep(long millis, int nanos).

  • Thread.sleep(long millis) 

Thread.sleep(2000): Duration is in milliseconds for which thread will sleep. 

  • Thread.sleep(long millis, int nanos) 

Thread.sleep(2000, 2000): The second parameter is an additional time in nanoseconds for which thread will sleep. It ranges from 0 to 999999. 

  • Thread.sleep() does not have a return type, and it returns void.

Thread.sleep methods throws InterruptedException when any other thread interrupts the current thread and should be handled by the throws method or try catch block.

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

OR

public void threadTest() throws InterruptedException {
Thread.sleep(2000);
}
  •  It throws an IllegalArgumentException when sleep time is negative.
Thread.sleep(-2000;)
  • Both the sleep() methods of Thread class are static methods. Hence, they should be accessed in a static way by using class name.
Thread.sleep(2000);

Now that it is discussed, why and how to use Thread.sleep() in the Selenium test, let’s see an example demonstrating the same.

In the example, using the MakeMyTrip website, which will take some time to load after clicking on the “Hotels” tab. And when Selenium tries to locate and click on the Search button on the “Hotels” page, it will throw NoSuchElementException as the element was not loaded before clicking on it.

Example 1: Testing Dynamic Web Elements

public class ThreadSleep { 
static WebDriver driver;
static String url = "https://www.makemytrip.com/";

@BeforeClass
public static void setUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
//Launch MakeMyTrip website
driver.get(url);
} 
@Test
public void search () throws InterruptedException {
//Click on Hotels tab
driver.findElement(By.cssSelector("li.menu_Hotels")).click();
//Click on Search button
driver.findElement(By.cssSelector("button#hsw_search_button")).click();
List<WebElement> hotels = driver.findElements(By.xpath("//span[contains(@id, 'htl_id_seo_')]"));
//Click on the first search result
hotels.get(0).click();
}

@AfterClass
public void tearDown() {
driver.quit();
}
}

Run the above program and observe that Selenium will throw NoSuchElementException at line 34.

Add Thread.sleep(2000) after line 33 and run the program again. This time the program will pass as the thread got paused for 2 secs, and the Search web element was loaded before clicking on it.

Talk to an Expert

Example 2: Third-Party Testing

In this example, on the MakeMyTrip home page, click on the facebook link from footer links and verify that it is redirecting to the MakeMyTrip facebook page.

public class ThreadSleep { 
static WebDriver driver;
static String url = "https://www.makemytrip.com/";

@BeforeClass
public static void setUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
// Launch MakeMyTrip website
driver.get(url);
}

@Test
public void facebookClick() throws InterruptedException {
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement wb = driver.findElement(By.xpath("//a[contains(@href, 'facebook')]/span"));
js.executeScript("arguments[0].click();", wb);
Assert.assertEquals(driver.getCurrentUrl(), "https://www.facebook.com/makemytrip/");
}

@AfterClass
public void tearDown() {
driver.quit();
}

Run the above program and observe that Selenium throws AssertionError since the expected page was [https://www.facebook.com/makemytrip/] but Selenium found [https://www.makemytrip.com/]

This happens as Selenium could not wait for the redirected page to load completely and returns the previous page url instead of the redirected url. Hence, using Thread.sleep() gives the redirected page a time window of few seconds to load completely, before returning the page URL. 

Limitations of Thread.sleep 

Using Thread.sleep() frequently in an automation framework is not a good practice. If the applied sleep is of 5 secs and the web element is displayed in 2 secs only, the extra 3 secs will increase the execution time. And if you use it more often in the framework, the execution time would increase drastically. 

BrowserStack Automate Banner

You always have to guess and apply Thread.sleep() seconds in advance, as there is no guarantee that the web element would be discoverable under that specified time.

On a closing note

However, as discussed in this article, when none of the Selenium wait commands work to locate the web element, Thread.sleep() can be used to avoid unnecessary failures in the automation script.

Just as Thread.sleep() avoids flaky tests and false positives, running Selenium Tests on real devices will help improve the overall accuracy of the tests. By using Cloud Selenium Grid like BrowserStack Automate, you can access 3000+ real devices and browser combinations to test under real user conditions

Moreover, you can speed up your cross browser compatibility tests by running them on different browsers simultaneously using Parallel Testing. This way, Selenium Testing becomes a lot easier and helps deliver a high-quality user experience.

Try BrowserStack for Free

Tags
Selenium Selenium Webdriver

Featured Articles

How to get Selenium to wait for a page to load

Selenium Wait Commands: Implicit, Explicit, and Fluent Wait

Automation Tests on Real Devices & Browsers

Seamlessly Run Automation Tests on 3500+ real Devices & Browsers