How to get Selenium to wait for a page to load
Shreya Bose, Technical Content Writer at BrowserStack - February 11, 2023
Think of a fairly common scenario involving websites in the real world.
A user clicks on a URL, and due to slow internet connection/inadequate website optimization/heavy website content/any other reason, the web page takes a while to load. Obviously, the user would wait for the page to load before clicking on a button, link, or image to continue their browsing journey.
In automation testing, all possible (or at least a larger number of) user scenarios must be automated so that QAs can monitor how the website would act in the real world. The scenario detailed above must also be automated for the same reason.
Given that Selenium is the most popular automated testing framework in global usage, this article will explore how QAs can use Selenium to wait for a page to load during an automated test.
Before proceeding further with how to get Selenium to wait for a page to load, take note that:
- Generally, page load waits are triggered until the DOM loads before letting the WebDriver proceed. For example, if an automated test clicks on a website’s Add to Cart button, WebDriver will execute the next line in the script only when the page loads completely. In such cases, there’s no need to instruct WebDriver to wait for page load separately.
- It is usually necessary to introduce a wait time in the Selenium script when navigating Ajax-based or dynamic elements that may continue to load after the page loads.
- Certain elements may only become visible after the page loads or after a user action but be available for interaction after a few seconds have passed. Think of a dropdown menu with dynamic values. It’s always available on the DOM, but its values are populated based on the user’s action.
In this case, once a value is selected, WebDriver must wait for the value to make an element visible before it becomes available for interaction.
So how does a tester use Selenium to wait for a web page to load?
The answer: Wait Commands.
How to implement Selenium wait for page to load
Selenium Wait commands instruct a test to pause for a predetermined length of time before moving onto the next step in the script. The pause lets the page load and the web elements become visible/present/populated/clickable before WebDriver can interact with them and proceed with the test.
Wait commands are beneficial because Selenium will throw an Element Not Visible Exception if it cannot locate the element required for the test to run. With wait commands, the test will wait for the element to become available, thus preventing the exception from showing up.
Read More: Exception Handling in Selenium WebDriver
There are three ways to implement Selenium wait for page to load:
- Using Implicit Wait
- Using Explicit Wait
- Using Fluent Wait
Using Implicit Wait
The Implicit Wait tells WebDriver to wait a specific amount of time (say, 30 seconds) before proceeding with the next step. If the tester knows how much time the page and element will take to load, they should use Implicit Wait.
Let’s say a website under test takes ten seconds to load a page until a particular element shows up. In that case, set implicit wait for 10 seconds. The test will pause, and once the time passes, Webdriver will continue to run the script as planned.
WebDriver driver => new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://url_that_delays_loading"); WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
Note that the Implicit Wait function will be applicable as long as the current browser is open. That means all elements being searched for by the Selenium script will take the time laid out in the Implicit Wait.
Using Explicit Wait
The Explicit Wait is more advanced in its functioning. It instructs WebDriver to pause a test until a predetermined condition is fulfilled.
Let’s say the website under test has a feature displaying a pop-up. The user has to enter some data, following which a pop-up appears. This feature needs to be tested in this exact sequence, including the time taken for the user to input data, server response time, etc.
In this case, the Explicit Wait will wait for the pop-up to appear before proceeding with the test. However, since the test cannot wait an infinite amount of time, testers also insert a duration for WebDriver to pause before carrying on.
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox() driver.get("http://www.example.com") #This is a dummy website URL try: elem = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.ID, "Element_to_be_found")) #This is a dummy element ) finally: driver.quit()
The code will instruct WebDriver to wait for 30 seconds. If the specified condition is met before that, the test will proceed, If not, it will wait the whole 30 seconds before moving forward.
In order to declare an explicit wait, one has to use “ExpectedConditions”. The following Expected Conditions in Selenium can be used in Explicit Wait:
Using Fluent Wait
The Fluent Wait is an advancement on the Explicit Wait. Using it, testers can define a specific condition and the frequency for which WebDriver should check for the condition to appear in a particular length of time.
Let’s say the website under test includes some elements that load dynamically. The tester knows it takes a total of 5 seconds to load, not more. But it can become visible anytime between zero to five seconds.
In this case, Fluent Wait comes to the rescue. The tester can use it to instruct Selenium WebDriver to keep checking on the element at regular intervals.
//Declare and initialise a fluent wait FluentWait wait = new FluentWait(driver); //Specify the timout of the wait wait.withTimeout(5000, TimeUnit.MILLISECONDS); //Specify polling time wait.pollingEvery(250, TimeUnit.MILLISECONDS); //Specify what exceptions to ignore wait.ignoring(NoSuchElementException.class) //This is how we specify the condition to wait on. wait.until(ExpectedConditions.alertIsPresent());
Fluent Wait operates with two main parameters: timeout value and polling frequency. The code defines timeout value as 5 seconds and polling frequency as 0.25 seconds. That means WebDriver will wait no more than 5 seconds to verify the specified condition. If the condition occurs (the element populates) during 5 seconds, it will move on to the next step in the test script. If not, it will return “ElementNotVisibleException”.
Read More: How to start with Selenium Debugging
Using Selenium Wait for page to load is quite necessary for automated Selenium testing since it is a common occurrence in everyday internet users’ browsing journey. Selenium Wait commands are exceptionally effective in doing so, and implementing them is fairly uncomplicated, making Browser Automation seamless, as the examples above have demonstrated.
Selenium Waits help detect and debug issues that may occur due to variations in time lag. However, for the results of these commands to be 100% accurate all the time, they must be run on real browsers and devices.
No matter the software, Selenium WebDriver tests must be executed on real devices and browsers. Remember that device fragmentation is a major concern for every developer and tester. Every website has to work seamlessly on multiple device-browser-OS combinations. With 9000+ distinct devices being used to access the internet globally, all software has to be optimized for different configurations, viewports, and screen resolutions.
In this state, no emulator or simulator can replicate real user conditions. Software needs to be tested on real devices so that they can work in real-world circumstances such as a low battery, incoming calls, simulating slow network conditions, and so on. If an in-house lab is not accessible, opt for a cloud-based testing option that offers real devices.
BrowserStack’s cloud Selenium grid offers 3000+ real devices and browsers for automated testing. That means users can run tests on multiple real devices and browsers by simply signing up, logging in, and selecting the required combinations. Testers can also conduct Cypress testing on 30+ real browser versions across Windows and macOS. Detect bugs before users do by testing software in real user conditions with BrowserStack.