- Understanding Selenium Timeouts
- What are Selenium Timeouts?
- 1. implicitlyWait()
- 2. setScriptTimeout()
- 3. pageLoadTimeout in Selenium
- How to handle a Timeout Exception in Selenium?
- Timeout Exception in Selenium Java
- Timeout Exception in Selenium Python
- Frequently Asked Questions
- How to handle TimeoutException in selenium, python
Understanding Selenium Timeouts
Selenium is one of the most widely used tools for automation testing. Every command in Selenium Webdriver is an asynchronous operation.
What are Selenium Timeouts?
Consider a situation in which WebDriver fails to execute the test case as the webpage takes too long to load. In such cases, it is essential to mention the wait time for the page load to avoid test case failure. This is where Timeouts play an essential role. They are used to set an interval between actions performed on the test.
Timeouts are usually performed using Selenium wait commands.
The various Selenium Webdriver timeouts used while testing an application are as follows:
Let’s discuss each method in detail.
1. implicitlyWait()
This timeout is used to specify the time the driver should wait while searching for an element if it is not immediately present.
implicitlyWait(long time, java.util.concurrent.TimeUnit unit);
When searching for a particular single element, the driver should pause page loading until the element has been found. If it doesn’t wait, the timeout expires before throwing a NoSuchElementException.
When searching for multiple elements, the driver should pause the page until at least one element has been found or the timeout has expired.
implicitlyWait(20, TimeUnit.SECONDS);
In this statement, the WebDriver will wait for 20 seconds before proceeding to the next action.
Code Snippet:
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; public class TimeoutExample < public static void main(String[] args) < System.setProperty("webdriver.chrome.driver", "Path of Chrome Driver"); WebDriver driver = new ChromeDriver(); driver.get("https://www.ebay.com/"); // Implicit wait timeout for 20seconds driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); driver.findElement(By.xpath("//input[@id='gh-ac']")).sendKeys("Mobile"); //xpath for search button WebElement search = driver.findElement(By.xpath("//input[@id='gh-btn']")); search.click(); >>
On executing the code above, the driver will wait for 20 seconds on the particular website even if the web element is not found.
Note: If a user wants to increase the implicit wait timeout, it should be done carefully, as this will affect the test run time.
2. setScriptTimeout()
This is used to set the time the WebDriver must 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.
setScriptTimeout(long time,java.util.concurrent.TimeUnit unit);
The default timeout for setScriptTimeout method is zero. If you do not set time, then there are chances that executeAsyncScript method may fail because the JavaScript code may take more than the time allotted. To avoid such failures, set the setScriptTimeout. This is mainly used for Javascript objects and executors.
// setScriptTimeout for 10 seconds driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS); ((JavascriptExecutor) driver).executeScript("alert('hello world');"); ((JavascriptExecutor) driver).executeAsyncScript("window.setTimeout(arguments[arguments.length - 1], 500);");
In the example above, if the time is not used, then there will be an error stating: “Timed out waiting for async script result”. To avoid this error, one should use setScriptTimeout.
3. pageLoadTimeout in Selenium
This sets the time to wait for a page to load completely before throwing an error. If the timeout is negative, page loads can be indefinite.
pageLoadTimeout(long time,java.util.concurrent.TimeUnit unit);
This timeout is applicable only to driver.manage() and driver.navigate.to() methods.
public class PageLoadTest < public static void main(String[] args) < System.setProperty("webdriver.chrome.driver", "Path of driver"); WebDriver driver = new ChromeDriver(); // set the time of 30 seconds for page to complete the loading driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS); driver.get("https://www.google.com/"); >>
In the code above, if your page does not load within 30 seconds, WebDriverException will be thrown.
Selenium Timeouts must be included to create effective, comprehensive and seamlessly running test cases. This article intends to help in this regard by briefly explaining how Timeouts work, and how they can be incorporated into Selenium test scripts.
To know more about Automation, refer to this piece on Selenium Automation.
How to handle a Timeout Exception in Selenium?
TimeOut Exception in Selenium mainly occurs when a given condition is not met in the specified time.
- So one way to handle timeout exceptions is to adjust the wait time according to the application behavior so that the webpage is loaded completely and all web elements are visible.
- We can also use polling, also called a fluent wait in selenium, which polls after a specified amount of time.
- For example, an element is dynamic and might be loaded after 10 seconds,20 seconds or 30 seconds, or even more.
- If we declare an explicit wait of 20 seconds, in this case, it will wait for that time before throwing an exception.
- In this case, the fluent wait is most suitable as it will try to find the element at different frequencies until the final timer runs out.
Wait wait = new FluentWait(driver) .withTimeout(timeout, SECONDS) .pollingEvery(timeout, SECONDS) .ignoring(Exception.class);
Timeout Exception in Selenium Java
Timeout exception generally occurs when a Webdriver wait has finished waiting for a particular element to be present or any condition to be satisfied.
To understand this, Let’s see an example where we will try to search for an element for a few seconds using webdriver wait.
package com.qa.bs; import java.time.Duration; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.Test; public class timeOutExample < @Test public void timeOutTest() < System.setProperty("webdriver.chrome.driver","c:\\chromedriver.exe"); ChromeOptions options = new ChromeOptions(); options.addArguments("--remote-allow-origins=*"); ChromeDriver driver = new ChromeDriver(options); driver.get("https://app.hubspot.com/login"); //This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(10)); wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username1"))); >>
For the sake of understanding, the ID for the username given in the above example is incorrect. The driver cannot find the element between 10 seconds, and it throws a timeout exception as demonstrated below.
This clearly shows that the driver tried to find the element’s visibility for 10 seconds, and as it could not find the element it threw a timeout exception.
Now let’s try to see the same example with the correct id for the username field, and we shall know the test has passed without throwing a timeout exception.
package com.qa.bs; import java.time.Duration; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.Test; public class timeOutExample < @Test public void timeOutTest() < System.setProperty("webdriver.chrome.driver","c:\\chromedriver.exe"); ChromeOptions options = new ChromeOptions(); options.addArguments("--remote-allow-origins=*"); ChromeDriver driver = new ChromeDriver(options); driver.get("https://app.hubspot.com/login"); //This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(10)); wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username"))); >>
Now we can see the same test has passed as the driver was able to find the element within the given time.
Timeout Exception in Selenium Python
Now let’s see the same timeout example in Python. In this example, we have used the presence_of_element_located() function to find the element within the given time.
from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.wait import WebDriverWait driver = webdriver.Chrome('C:/chromedriver.exe') driver.get("https://app.hubspot.com/login") WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'username1')))
Here too, we have deliberately given an invalid ID for the username field so that the driver is unable to find the element and throws a timeout exception as below.
If we give the correct ID for the username element, the driver can find the element of the specified time, and the test passes as below.
from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.wait import WebDriverWait driver = webdriver.Chrome('C:/chromedriver.exe') driver.get("https://app.hubspot.com/login") WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'username')))
Frequently Asked Questions
1. What is the default timeout in Selenium WebDriver?
The default timeout depends on the type of wait command used.
- It is 0 seconds for implicit waits. Here the Selenium Command reports immediately if it cannot find an element.
- It is 300 seconds for page loads.
- It is 30 seconds for script timeouts.
2. How does Selenium handle connection timeout?
In Selenium, you can handle a connection timeout by setting a timeout value for the WebDriver using the set_page_load_timeout() method. This method sets the maximum time (in seconds) that the driver should wait for a page to load before throwing a TimeoutException . For example to set timeout as 10 seconds, you can use set_page_load_timeout(10)
3. How long is Selenium timeout?
The timeout in Selenium is set in seconds or milliseconds, depending on the method used. For example, the set_page_load_timeout() method in the WebDriver takes the timeout value in seconds, while the pause command in Selenium IDE takes the timeout value in milliseconds.
4. How to change default timeout in Selenium?
You can change the default timeout in Selenium by using the set_page_load_timeout method of the WebDriver object. For example: driver.set_page_load_timeout(10)
You can also set a timeout for implicitly waiting for an element to be present on the page, using the implicitly_wait method.
5. What is the maximum session timeout in Selenium?
The maximum session timeout in Selenium WebDriver depends on the server configuration and the client’s capabilities. By default, there is no specific limit on the maximum session timeout in Selenium. The session can continue for as long as the client and server can communicate with each other, and until either the client or server closes the session. BrowserStack Automate supports session durations of up to 2 hours. If a session runs for more than 7200 seconds (2 hours), the session is stopped, changing the status to TIMEOUT on the dashboard.
6. What does timeout exception in Selenium mean?
In Selenium, a TimeoutException is an exception raised when an operation runs out after a specified period. For example, when using the WebDriver.get method to load a page, the default timeout is set to 30 seconds. If the page takes longer than 30 seconds to load, a TimeoutException will be raised. Similarly, when using the WebDriver.find_element method to locate an element on a page, a TimeoutException will be raised if the element is not found within a specified timeout.
Your code can handle this exception to implement appropriate error handling and recovery logic. For example, you can catch the exception, retry the operation, or log the error and move on to the next task. You can also adjust the timeout values to ensure processes are complete within the desired timeframe.
How to handle TimeoutException in selenium, python
First of all, I created several functions to use them instead of default «find_element_by_. » and login() function to create «browser». This is how I use it:
def login(): browser = webdriver.Firefox() return browser def find_element_by_id_u(browser, element): try: obj = WebDriverWait(browser, 10).until( lambda browser : browser.find_element_by_id(element) ) return obj ######### driver = login() find_element_by_link_text_u(driver, 'the_id')
Now I use such tests through jenkins(and launch them on a virtual machine). And in case I got TimeoutException, browser session will not be killed, and I have to manually go to VM and kill the process of Firefox. And jenkins will not stop it’s job while web browser process is active. So I faced the problem and I expect it may be resoved due to exceptions handling. I tryed to add this to my custom functions, but it’s not clear where exactly exception was occured. Even if I got line number, it takes me to my custom function, but not the place where is was called:
def find_element_by_id_u(browser, element): try: obj = WebDriverWait(browser, 1).until( lambda browser : browser.find_element_by_id(element) ) return obj except TimeoutException, err: print "Timeout Exception for element '' using find_element_by_id\n".format(elem = element) print traceback.format_exc() browser.close() sys.exit(1) ######### driver = login() driver .get(host) find_element_by_id_u('jj_username').send_keys('login' + Keys.TAB + 'passwd' + Keys.RETURN)
This will print for me the line number of string «lambda browser : browser.find_element_by_id(element)» and it’s useles for debugging. In my case I have near 3000 rows, so I need a propper line number. Can you please share your expirience with me. PS: I divided my program for few scripts, one of them contains only selenium part, that’s why I need login() function, to call it from another script and use returned object in it.