Start automating your tests 10X Faster in Simple English with Testsigma
Try for freeSelenium is a popular automation testing framework, and we all know about it. Its features and performance metrics have garnered positive reviews from testers ranging from freshers to veterans. If we talk about its working by considering a small task of handling iFrames in Selenium, as soon as we execute the script, the browser opens and starts to find out its target based on locators. This is how we generally do almost all the tasks in Selenium.
In the popular movie Sully, the experts mimic an airplane crash by sitting in a flight simulator. Consider this scenario equivalent to testing a web page. Maybe we are trying to test a failed element on a website. So, as soon as the birds strike the engine, the pilots change direction towards the airport.
This means that once the browser opens up the webpage, we are running the script over it. Captain Sullenberger then asks the same question that I intend to ask you here, “Are we considering the human factor?” except that I would just make a slight change of “human” to “web.”
All our reasonings above should converge while Selenium webdriver wait for page to load. However, we will discuss them in detail in their respective sections. These sections would be as follows:
Table Of Contents
Page loading and Why is it Important?
Page loading concerns all the divisions of teams working on a web page. It is a vast concept in which various strategies are implemented to improve user experience. How much relevance it holds is evident when we look at these three facts:
- 53% of mobile visitors will close the tab if your website takes more than 3 seconds to load.
- Bounce probability would increase to 32% if page load time goes from 1 second to 3 seconds.
- Google stated,“2 seconds is the threshold for e-commerce website acceptability.”
Our aim, therefore, is to improve our website’s page load time, and we generally take the following strategies during web development.
Isolating the Elements
“Load only what is required” is a motto exercised by web developers to decrease their page load time and present their web page quickly to the users. This technique isolates various elements and loads them at different times. The first element is loaded automatically as it is the most important.
For example, in a blog post, the heading and content are essential (preferably only within the viewport). But, we need not load other articles that are beneath the current one as they are out of the viewable area. We can do that when the user scrolls down to that point. This way, we ask for lighter bandwidth from the user’s network. Read here – Scrolling in Selenium.
Lazy Loading the Images
Lazy loading is the same concept we discussed above, except it applies to images specifically. We can implement this to even the main content (that we loaded first, as mentioned in the previous section).
Lazy loading images means to load an image only when the user scrolls and reaches the point that it falls under the viewable area (viewport of the browser).
This is done because images can be the heaviest elements on a web page. With improvements in global network infrastructure, the usage of high-quality images is normal. Therefore, if a user is on a slower network, he can face a high loading time (even higher than before when low-quality images were used). With the lazy loading of images, we can save bandwidth and decrease the page load time for all our users.
Implementing AJAX-Based Elements
AJAX is an acronym for Asynchronous JavaScript and XML. It helps implement techniques on a web page that can help us load the elements asynchronously. In layman’s terms, with AJAX, we can load only those elements we need to load and not the complete page based on a user’s request. For example, in the following image, we are loading the list without fully loading the page.
AJAX helps us save a lot of bandwidth as we do not request all the source code or eat valuable bandwidth.
Why Do We Care About Page Load in Selenium?
The above-discussed strategies that help us load pages faster contribute to the reasons (directly or indirectly) why we need to learn about page load in Selenium as a tester.
Web Development Strategies
The web development strategies mentioned in the previous section intentionally put a few elements on hold until the user reaches that point. This means that if we are looking to test those elements, we may not find them on the web page (if they are JS enabled).
If they are not produced by JS in between the user interaction but rather hidden intentionally, the Selenium script would find them even without load. But the problem is that it will defy our whole purpose of testing. What if when the user visits the page, the element never turns visible? Our tests would already have turned green on such scenarios, which could be dangerous.
Slower Networks
Apart from considering the intentional load delay on web pages, we should also consider the practical conditions in which users use their mobile devices.
A user operates a mobile device on the move a lot of the time. The geographical area and the movement speeds depend on the user. For instance, if a user is walking in a good coverage area, the web page can be expected to load as anticipated. Also, we presume that since the user’s movements are slow, moving into a low coverage area is not that probable.
Another factor is when the user is on the move at a higher speed, such as on a bus. The chances of regularly falling into lower coverage areas are high. The problem in these scenarios is that we cannot predict what users would do while operating our website.
From our end, we should always be prepared for every situation. So, as a tester, we would want to test a page by making it load at different speeds mimicking the user’s conditions. This way, we can be prepared for the best as well as worst conditions.
Concerns About Delayed Acknowledgements
One use case that entirely depends on a web application’s design is the implementation of conditional elements and delayed acknowledgements. These elements belong to the category where a user’s action prompts certain logic at the backend that only gets activated on the UI when the action is completed.
Uploading a file is one such scenario where these types of elements are implemented. In this particular case, the confirmation (let’s assume through a modal) only comes when the file is uploaded or cannot be uploaded due to external conditions.
This would also depend on the user’s network connection; therefore, exact time limits cannot be applied.
In addition, we know you must have found your “go-to” methods for page loads in Selenium. Let us know in the comment section when you feel the need to test for page load except for the ones discussed above.
How to Apply Waits in Selenium for Page Load?
Now that we know why we implement page load and why a tester needs to always take care of it, it is time to understand the methods that can help us achieve the same.
When we intend to implement something related to the Selenium waits in page load, we refer to it as Selenium wait.
Selenium offers us three methods to implement waits, know the types of wait in selenium below:
Implicit waits
Explicit waits
Fluent waits
Let’s see each of Selenium Waits for Page Load with examples and understand their specific use cases.
Implicit Waits in Selenium
An implicit wait is the most basic type of wait in Selenium. With implicit wait, we specify a time till which we would want to wait for the element. Once the time is elapsed, we move on to the next test. Also, if the element is not found within the time frame, the NoSuchElementFound exception is thrown.
This type of wait is termed implicit because even if we request the time delay once, it is “implicitly” applied to all the elements. Under this umbrella, Selenium provides three types of commands:
- implicitlyWait()
- pageLoadTimeout()
- scriptTimeout()
All of them can be used to apply implicit wait, depending on the situation.
implicitlyWait Command in Selenium
In this command, we specify a time unit that acts as the maximum time Selenium will wait for that element to appear. If the element appears before time, the test is executed without waiting till the maximum time. If the element is not found, NoSuchElementFound exception is returned.
implicitlyWait Command Syntax
The syntax for implicitlyWait command is as follows:
driver.manage().timeouts().implicitlyWait(<time unit>(<time>);
Here we pass two parameters as arguments into the command. One is <time> which is the numerical number such as 10 or 20. The other parameter is the <time unit> which means the unit of time you are considering for <time> such as seconds.
For example, (Duration.ofSeconds(12)) means we want Selenium to wait for 12 seconds. You can choose a time unit from a vast list given in the TimeUnit library.
A simple example of implementing implicitlyWait command would look as follows:
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(12));
driver.get(“https://www.testsigma.com”);
WebElement myDynamicElement = driver.findElement(By.id(“header”))
Apart from this direct implementation of waiting for X time units, implicitlyWait also has an in-built polling mechanism. The polling (a Selenium technical term) is the frequency in which Selenium wait will look for the occurrence of the element after the time has elapsed.
It is done to provide additional details to the tester. Since we are only providing the maximum time here as a parameter, there is no way through which tester can control the polling time in implicitlyWait. You can also assume it to be a feature of browser drivers for better testing.
So, each driver may have adjusted their polling time according to themselves. It might range between 500 milliseconds to 1.5 seconds. However, this is not a strict bracket and depends entirely on your browser driver.
pageLoadTimeout Command in Selenium
The pageLoadTimeout command in Selenium implicit wait does exactly what its name suggests. It waits for the page to load for a specified number of seconds. If the page doesn’t load within that time, an exception is thrown.
Syntax for pageLoadTimeout Command
The syntax for pageLoadTimeout command looks as follows:
driver.manage().timeouts().pageLoadTimeout(<time>, <time unit>);
Here, too, we pass two parameters: time and time unit. They have the same relevance as before. Also, “driver” is a WebDriver instance.
An example of the pageLoadTimeout command can be as follows:
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(12));
driver.get(“https://www.testsigma.com/”);
Here we have set the time unit as seconds and the time as 12. You can also specify a negative value here, meaning that you are ready to wait for an infinite amount of time. However, this is not a good practice.
scriptTimeout Command in Selenium
In the section “Page loading and why is it important?” an option of AJAX-based elements was mentioned. This command helps in testing the same part of the web page through Selenium.
The scriptTimeout command defines a time limit for the asynchronous elements to load on the page. The test passes if the tests are loaded within that time.
Syntax for the scriptTimeout Command
The syntax for the scriptTimeout command is as follows:
driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(10));
Here we have set the time unit as seconds and the time as 10. Similar to pageLoadTimeout, you can feed a negative value as “time”. However, it will result in an infinite wait which is never advisable with async scripts.
Since async scripts have a job to do and are expected to do it within time, providing a negative value would never determine whether your AJAX would never load, or even if it does, the resulting metrics are not helpful.
Also, since this command is used on the asynchronous elements, you need to remember that it affects the JavaScript code with the executeAsyncScript block only. The default timeout value for both pageLoadTimeout and scriptTimeout command is 0.
So, with the introduction to these commands, a question pops up when we find ourselves writing Selenium wait code – which scenario calls for which one to use?
implicitlyWait command is the most common of the lot and would be your first choice in most cases. Since it gives us the flexibility of using a timeout without any specific condition like “it has to be an async script,” it can be used safely when you rule out the other two.
pageLoadTimeout command is essential in performance-related testing. Since users’ expectations are high for page load, pageLoadTimeout gives us an inside view of the metrics our web pages are achieving. Then, we can optimize our code to present it quicker on the user’s screen.
scriptTimeout command is imperative because of the high usage of asynchronous elements on a web page. Requesting a complete web page repeatedly is a terrible choice considering the heavy components we use today and the load it would put on the server.
The user’s network coverage also plays an important role here. scriptTimeout helps us analyze how our AJAX scripts are working and if there is a need to optimize them. They are used popularly in Selenium wait tests.
Demerits of Implicit Wait
The usage of implicit wait in Selenium has garnered positive and negative reviews from the community and experts. As far as I have explored it, most reviews fall on the negative side because of its demerits. The most popular ones are discussed below:
Once Written – Applied to All
The most popular drawback among the community of the implicit wait is that once you have written an implicit wait, it will be applied to all the test cases. This is not a good strategy as your total test case run would become a number of test cases * time you choose in implicit wait.
So, 1000 tests with an implicit wait of just 3 seconds would be 3000 seconds in the worst case, which is a long time. This could be achieved in far less time if we use another type of wait, and sometimes we can clock manual testing in less time too.
Slows Down Test Execution
A direct result of the previous point is that it slows the overall test execution time. So testing phase will start to take more time with each releasing version. This is contrary to what we should aim for practically.
Raises Performance Issues for Testers
The implicit wait is not an excellent method to choose from when you are concerned about the performance of your test scripts and, in a way, the developed code. The scripts wait a certain amount of time that may vary across elements. You may never get the exact time you can vouch that your tests would work.
It is always recommended to use implicit wait in Selenium only when it is highly required. If there is a doubt about using it, it is better to avoid it than reiterate it later in the future.
Explicit Wait in Selenium
The implicit wait is called “implicit” because we do not specify anything explicitly. It just waits and does that for all the tests. Contrary to this behavior, Selenium presents the concept of explicit waits. Here, we define explicitly when we would want to wait and for how long we want to wait for it. This is done using certain conditions Selenium offers as part of their library. We have listed all these conditions below.
To implement the explicit wait in our tests, we use the WebDriverWait command.
WebDriverWait Command in Selenium
WebDriverWait is a class in Selenium that helps us implement explicit waits. It has a simple syntax as follows:
WebDriverWait(<browser driver instance>, <time units>(time)) .until(condition);
In the above syntax, we witness three arguments:
- Browser driver instance: This is a browser driver instance related to the driver you are using.
- Time units: The unit of time such as seconds.
- Time: The time count in numerals.
- Condition: The condition for which you wish to look out for and wait for it to happen until a maximum time of <time units>(time)
To construct a simple snippet with WebDriverWait command, we can follow these steps:
First, create a browser driver instance:
WebDriver driver = new FirefoxDriver();
Call a URL with the help of this driver instance:
driver.get(“https://www.testsigma.com”);
Implement the WebDriverWait to wait until the link becomes clickable with a maximum timeout limit of 15 seconds:
WebElement res = new WebDriverWait(driver, Duration.ofSeconds(15))
.until(ExpectedConditions.elementToBeClickable(By.xpath(“//a/h1”)));
And that’s it. We get our Selenium explicit wait ready to be used in the test cases. But before concluding this command, let me list down the available conditions for your reference (as elementToBeClickable used in the above example):
- alertIsPresent()
- elementSelectionStateToBe()
- elementToBeClickable()
- elementToBeSelected()
- frameToBeAvaliableAndSwitchToIt()
- invisibilityOfTheElementLocated()
- invisibilityOfElementWithText()
- presenceOfAllElementsLocatedBy()
- presenceOfElementLocated()
- textToBePresentInElement()
- textToBePresentInElementLocated()
- textToBePresentInElementValue()
- titleIs()
- titleContains()
- visibilityOf()
- visibilityOfAllElements()
- visibilityOfAllElementsLocatedBy()
- visibilityOfElementLocated()
While constructing the WebDriverWait test cases, we should know about polling time and its effect. Polling time is the frequency (or interval) in which the command looks again for the condition to be true after it failed the last time.
Unfortunately, we cannot control the polling time in WebDriverWait; this could impact our test case results if you want them to be precise to a point less than 500ms. You can check your polling time by visiting the class code.
FluentWait in Selenium
WebDriverWait is a great command, except that it does not let us handle the polling time for the test cases. Instead, it comes with a fixed time that might change the resulting metrics. FluentWait is a version of WebDriverWait with polling time control to the tester.
Due to its resemblance in working, it is sometimes considered as part of the explicit wait. However, sometimes it is kept out of that pool. Here, we will consider it as part of an explicit wait.
Syntax of FluentWait Command
The syntax of FluentWait is as follows:
Wait<WebDriver> wait = new FluentWait<WebDriver>(<browser driver instance>)
.withTimeout(<time unit>(<time number>))
.pollingEvery(<time unit>(<time number>))
.ignoring(<exception to ignore>);
In the above syntax, the first line creates an instance of the class. The second line defines the timeout, i.e., the maximum time for which the Wait has to work. The third line defines the polling time i.e. the frequency of poll. The final line is an optional command that defines which exception to ignore while in the process.
So, you must have guessed that since there is no mention of the condition we are using here, we need to write an extra line for that. Combining them as a practical snippet, the code becomes as follows:
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(15))
.pollingEvery(Duration.ofSeconds(3))
.ignoring(NoSuchElementException.class);
WebElement we = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id(“myHeader”));
}
});
You can now wait for elements with a longer polling time to reduce CPU cycles or make them fast according to your needs.
Conclusion
Waiting in web development is an important concept that is implemented in both development as well as testing. While developers try to make the process faster by letting a few elements wait before loading, testers face a tough situation in handling them.
If you run a script normally, it would mark that element absent and fail all the test cases within that element range. The only thing that helps us rescue this situation is Selenium waits.
Selenium waits is a collection of commands that fall within implicit or explicit wait. In this post, we tried to highlight each of these divisions in detail with their merits, demerits, and situations that call for implementation.
With this, we hope you have recalled your experience, so we would love to listen to them in the comment section. If you are someone who is trying your hands on Selenium waits for the first time, we hope you liked this post.
Frequently Asked Questions
Does Selenium Wait Until Page to Load Python?
Some components or elements of certain websites are concealed or not visible at first. By default, the web driver will wait for a page to load before searching for a specific element using the.get() method.
How Will You Wait Until a Web Page has been Loaded Completely?
Waiting is implied.
The Implicit Wait instructs WebDriver to wait a specified period of time (say, 30 seconds) before moving on to the next phase.
PageLoadTimeout
This command specifies how long WebDriver must wait for a page to fully load before throwing an error. If the timeout is set to zero, the page load time will be unlimited.
How Do I Make Selenium Wait for Sometime?
The Implicit Wait command instructs the Selenium WebDriver to wait for a specified amount of time before issuing an exception.
The explicit Wait command instructs the WebDriver to wait for a specific condition to occur before running the code.
The Fluent Wait indicates how long the Selenium Driver wait for a given (web element) to become visible.
What is Wait Command in Selenium?
Implicit Wait
Explicit Wait
Fluent Wait
Selenium 4Selenium 4.0(alpha) – What Test Automation Engineers can expect!Challenges in Selenium
Top Limitations and Challenges in Selenium & SolutionSelenium Standalone Server
Selenium Standalone Server vs Selenium Server [Updated]