Introduction
Understanding the timeouts in Selenium is important to run your tests effectively and efficiently.Selenium provides number of options for the automation engineers. We will discuss What, Why, When ,Where , Which and How (Five wives and one husband thinking model) of Selenium Timeouts.
You will encounter various issues while automating web applications developed using JavaScript frameworks too. We will touch the issues raised by newer JavaScript test automation framework yo the test automation engineers at the later stage of this document.
What is timeout?
A definition from Wikipeidia related to computer programming could be useful to understand the timeouts.
“A specified period of time that will be allowed to elapse in a system before a specified event is to take place, unless another specified event occurs first; in either case, the period is terminated when either event takes place.”
What is timeouts in Selenium WebDriver ?
Selenium command will have to wait for specified period of time before a specific event is to take place before proceeding. Few examples of the events (wait till) available out of the box in Selenium WebDriver are listed below.
-
Page is fully loaded
-
An element is loaded
-
An element is clickable
-
An element is visible
-
An element with has given text
Full list of available conditions can be found in ExpectedConditions (Java API) documentation.
Why do we need timeouts in Selenium test automation?
In this section we shall understand the need of timeouts in Selenium.
Selenium commands are executed very fast one after another. It does not wait till the process initiated from previous command is completed.For example when you click login button Selenium does not wait till the page is fully loaded.
Some elements and data may not have loaded yet into the web page (DOM) when selenium commands are executed. Hence the WebDriver has to wait till the element or data is loaded into the DOM (or condition is satisfied) before the command is executed.
You may get “NoSuchElementException” even when you can see the element is available in the web page. This happens because the element is not loaded into the DOM at the time of command execution.
Your selenium statement has to wait till the element in the commands are loaded into the DOM.
You will get error similar to following when an element is not available
What are the different types of timeouts available?
We shall discuss following options available with Selenium WebDriver.
Implicit wait
We can tell Selenium WebDriver that we would like it to wait for a certain amount of time before throwing an exception when it cannot find the element on the page.
Once defined implicit wait is applicable for the entire browser session.
Hence implicit waits are defined at the @BeforeSuite section.
The default timeout value is zero. Hence setting the implicit wait is important to avoid no such element found exceptions.
WebDriver will keep pooling the DOM until the element is found or the timeout is reached. NoSuchElementException is thrown when element is not found even after the time timeout expiry.
Explicit wait
An explicit wait is code you define to wait for a certain condition to occur before proceeding further in the code. WebDriverWait in combination with ExpectedCondition is one way to implement explicit waits in your selenium test scripts.
Explicit wait statement will appear
Fluent wait
Fluent wait is an improved version of the explicit wait where you can define timeout value and a polling interval configured on the fly.
Use of Thread.sleep()
It is not recommended to use Thread.sleep available with Java (native solution). Sleep will pause the test execution for given amount of time even when your condition is satisfied. Hence your test will be inefficient.
You will have to add the sleep command before every statement where you want waist. Hence the code will become ugly.
You will have to judge the sleep time required and include in the code. The sleep time required may not be same for all the situation.
See the video from Sauce Labs : Breaking the myth
Which timeout should be used?
Implicit timeouts should be used when webdriver is faster than the elements loading time to DOM.
Explicit and fluent waits should be used when you know particular condition to be satisfied in advance before executing a selenium command.
Where to place timeout code ?
Implicit timeouts shall be placed when you initialize the browser instance. It should be done from @BeforeSuite in TestNG.
Explicit waits and Fluent waits should be included just before the command where you want the conditions to be satisfied. Usually common methods with explicit and fluent waits are created and included in a base class.
How do we use timeouts in Selenium scripts
We have included sample code in Java for each of the timeouts discussed
Sample code for Implicit wait
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Sample code for Explicit wait
WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("logout")));
Sample code for Fluent wait
// Waiting 30 seconds for an element to be present on the page, checking // for its presence once every 5 seconds. Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(30, SECONDS) .pollingEvery(5, SECONDS) .ignoring(NoSuchElementException.class); WebElement foo = wait.until(new Function<WebDriver, WebElement>() { public WebElement apply(WebDriver driver) { return driver.findElement(By.id("logout")); } });
PageLoadTimeout
Sets the amount of time to wait for a page load to complete before throwing an error. If the timeout is negative, page loads can be indefinite.
setScriptTimeout
Sets the amount of time to wait for an asynchronous script to finish execution before throwing an error. If the timeout is negative, then the script will be allowed to run indefinitely.
Test method execution timeout
You can set the maximum number of milliseconds a test method should take with TestNG. The time-out value can be defined at the suite level (in testng.xml) globally or in the test methods itself.
Defining at suite level
<suite name="Pragmatic Test Suite" time-out="5000" verbose="1" > <test name="Timeout Test" > <classes> <class name="com.pragmatic.testng.TimeoutTest" /> </classes> </test> </suite>
Defining at the test method level
@Test(timeOut = 15000)
public void timeTestOne() throws InterruptedException { Thread.sleep(1000); System.out.println("Time test method one"); }
Setting timeouts for the tests will help you to skip the slower tests (bottlenecks) and improve test case execution time. You can get a list of skipped tests and run them separately later.
Waiting for Angular to finish async activity
None of the above will work for asynchronous waits. This is very common is most of the applications developed using JavaScript frameworks today. Some of the test automation engineers move out of Selenium when Selenium is not capable of handling them directly (e.g. using Protractor) or use Thread.sleep() like solutions.
There are many solutions available at the moment. You can use ngWebDriver to handle asynchronous waits effectively when webdriver runs faster than the asynchronous calls.
Following is a sample code for an implicit wait defined asking webdriver to wait for angular requests to finish.
new NgWebDriver(driver).waitForAngularRequestsToFinish();
Discussing various solutions available outside the Selenium and other tools (e.g Protractor) is out of scope of this document.
References
- Seleniumhq.org. (2018). WebDriver: Advanced Usage — Selenium Documentation. [online] Available at: http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp [Accessed 22 Mar. 2018].
- En.wikipedia.org. (2018). Timeout (computing). [online] Available at: https://en.wikipedia.org/wiki/Timeout_(computing) [Accessed 22 Mar. 2018].
- Seleniumhq.github.io. (2018). ExpectedConditions. [online] Available at: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html [Accessed 22 Mar. 2018].
- Seleniumhq.github.io. (2018). FluentWait. [online] Available at: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/FluentWait.html [Accessed 22 Mar. 2018].
- GitHub. (2018). paul-hammant/ngWebDriver. [online] Available at: https://github.com/paul-hammant/ngWebDriver [Accessed 22 Mar. 2018].
- YouTube. (2018). Sauce Labs Automated Testing Mythbusters – Sleeps Are Not The Answer. [online] Available at: https://youtu.be/SCG-U8hhRFI [Accessed 22 Mar. 2018].
- Testng.org. (2018). TestNG. [online] Available at: http://testng.org/doc/documentation-main.html [Accessed 22 Mar. 2018].
Comments