1. Selenium Implicitly Wait is not recommended
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0, meaning disabled. Once set, the implicilyWait() method applies for all instances of a driver.
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
The first reason that you should NOT use implicitly Wait is because It is applied globally for all elements of a driver, this makes it not flexible to use in selenium tests. We normally expect various amount of wait time for different elements.
Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.
That is the second reason, implicitly Wait and Explicit wait cannot work together. You can only choose one of these two wait methods. And because Explicit wait is more flexible and powerful, we should select it. Remember never mix these two waits.
2. Set Page Load Time Out for WebDriver instance
driver.set_page_load_timeout(EnvConf.PAGE_LOAD_TIMEOUT_SECONDS)
This method will set the amount of time to wait for a page load to complete. By default, when Selenium WebDriver loads a page, it follows the normal pageLoadStrategy. It is always recommended to stop downloading additional resources (like images, css, js) when the page loading takes lot of time.
The document.readyState property of a document describes the loading state of the current document. By default, WebDriver will hold off on responding to a driver.get() (or) driver.navigate().to() call until the document ready state is complete
In SPA applications (like Angular, React, Ember) once the dynamic content is already loaded (I.e once the pageLoadStrategy status is COMPLETE), clicking on a link or performing some action within the page will not make a new request to the server as the content is dynamically loaded at the client side without a full page refresh.
SPA applications can load many views dynamically without any server requests, So pageLoadStrategy will always show COMPLETE status until we do a new driver.get() and driver.navigate().to()
That’s why for SPA applications, you should always handle element/page loading by yourself.
you can use below code to wait the page load due to element/page is re-rendering (AJAX call rendering):
void waitForPageLoaded(WebDriver driver) {
new WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}
3. Wait AJAX calls completed by checking jQuery.active state
If the application is using jQuery then the JavaScript Executor can be used to wait for an Ajax call. The waiting is done till jQuery.active command yields 0.
while (true){
Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0");
if (ajaxIsComplete){
break;
}
Thread.sleep(500);
}
4. Handle Page loading using Selenium Explicitly Wait
Explicit wait allows your code to halt program execution, or freeze the thread, until the condition you pass it resolves.
In most case which you want to handle page loading, you should use this wait.
Firstly, Using Explicitly Wait to make sure elements are ready before doing any interactions. e.g. waiting element clickable before click element, waiting element to be clickable before typing text, waiting element to be visible before getting text..
Next, Using Explicitly Wait to wait any spinner, loading icon to be invisible/disappeared.
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(EC.
invisibilityOfElementLocated(By.xpath("//*[@class='spinner-small']")));
5. Another interesting solution to handle AJAX calls in Selenium Assertion is “Retry”
refer this post to find more details.
driver.find_element(:xpath,"//input[@value='Pay now']").click
try_for(6) {
expect(driver.find_element(id: "pay-success").text).to include("Order is confirmed !")
}
6. document ready state flow and load event
readystate: interactive
DOMContentLoaded
readystate: complete
load
Reference Links:
https://www.selenium.dev/documentation/webdriver/waits/
https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
https://www.selenium.dev/documentation/en/webdriver/page_loading_strategy/