Automating web apps having AJAX with Selenium Webdriverwait
By – Divas Pandey
Initially when I started working on Web Automation the biggest challenge I faced was to create synchronization between speed of automation script execution & the response of the browser corresponding to the action preformed. Response of the browser can be fast/ slow, it’s normally slow due to a number of reasons like – Slow internet speed, Slow performance of the browser/ testing machine used etc. On analyzing the automation results we can see that maximum number of test cases FAIL due to the reason—element not found during the step execution. The solution to this problem of proper synchronization between automation speed and object presence is proper wait management. Selenium WebDriver provides various types of wait.
A simple scenario of synchronization is – suppose a button exists on a page and on clicking this button a new object should appear but this new object appears very late due to slow internet speed and as a result our test case fails. Here ‘Wait’ helps the user to troubleshoot issues while re-directing to different web pages by refreshing the entire web page and re-loading the new web elements.
“Dependent on several factors, including the OS/Browser combination, WebDriver may or may not wait for the page to load. In some circumstances, WebDriver may return control before the page has finished, or even started, loading. To ensure robustness, you need to wait for the element(s) to exist in the page using Explicit and Implicit Waits.”
We have 3 main types of wait.
- Implicit Wait
- Explicit Wait
- Fluent Wait
1) Implicit Wait:
The implicit wait remains alive for lifetime to the WebDriver object. In other words we can say that it is set for the entire duration of the web driver object. The implicit wait implementation will first ensure that element is available in DOM (Data Object Model) or not if not then it will wait for the element for a specific time to appear on webpage.
Once the specified time is over, it will try to search the element once again the last time before throwing exception.
Normally Implicit wait do the polling of DOM and every time when it does not find any element then it waits for that element for certain time and due to this execution of test becomes slow because implicit wait keep script waiting.Due to this people who are very sophisticated in writing selenium WebDriver code advise not to use it in script and for good script implicit wait should be avoided.
Example:
Here are the steps mentioned below to apply implicit wait.
Import java.util.concurrent.TimeUnit package;
Create an Object of webdriver.
WebDriver driver=new FirefoxDriver();
Define the Implicit wait timeout.
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
importorg.openqa.selenium.*;
importorg.openqa.selenium.firefox.FirefoxDriver;
Class ImplicitWait_test
{
privateWebDriver driver;
public static void main(String[] str)
{
driver = new FirefoxDriver();
baseUrl = “http://www.wikipedia.org/”;
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(URL for navigate….);
}
}
2) ExplicitWait:
The difference between the explicit and implicit wait is implicit wait will be applied to all elements of test case by default while explicit will be applied to targeted element only.
Suppose there is a scenario, when a particular element takes more than a minute to load. In that case we would definitely not like to set a huge time to implicit wait, as if we do this, browser will go to wait for the same time for every element. In order to avoid such situation, Introduce a separate time on the required element only. By following this browser implicit wait time would be short for every element and it would be large for specific element.
There are two classes WebDriverWait and ExpectedConditions for this purpose.
Here are some Conditions of ExpectedConditions class are mentioned below:
alertIsPresent() : Is Alert Present?
elementSelectionStateToBe: Is the element selected?
elementToBeClickable: Is the element clickable?
elementToBeSelected: Element is selected
frameToBeAvailableAndSwitchToIt: Is frame available and selected?
invisibilityOfElementLocated: Is the element invisible?
presenceOfAllElementsLocatedBy: All elements presence location.
refreshed: Wait for a page refresh.
textToBePresentInElement: Is the text present for a particular element?
textToBePresentInElementValue: Is the element value present for a particular element?
visibilityOf: Is the element visible?
titleContains: Is that title contain?
Example:
- Firstly Create an instance of webDriverWait.
WebDriverWait wait = new WebDriverWait(driver, time period);
time period : Here time value is given as input. How many seconds the driver has to wait is given here.
WebDriverWait wait = new WebDriverWait(driver, 30);
- Use Until method with webdriverwait object.
wait.until(ExpectedConditions.Conditions(By.xpath(“xxxxxxxxxx”), ” XXXXXXXXXXXX”));
Here is a code given below for to wait for elements to become clickable.
Class ExplicitWait_test
{
Private WebDriver driver;
Public static void main(String[] str)
{
Driver=new firefoxDriver();
Driver.get(“URL to launch…”);
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id(“someid”)));
}
}
3) FluentWait:
Fluentwait defines a maximum amount of time to wait for a specific condition, and we can define a frequency with which we can check the condition.
We can implement the fluent wait in two ways. First one is using predicates and other one is using function. The difference between the two is the function can return any object or Boolean value but the predicate only returns a Boolean value. We can use any one of them as per our requirement.
To implement fluentwait we need to add guava jar with our project. Here I am explaining the example of fluent wait with the function and predicate.
Fluent Wait with Function:
A scenario for fluent wait with function-A button exists in a web page, and when user clicks on the button an alert modal appears in the page, here I am trying to verify that when I am clicking on the button, alert is present in the page or not. Here I mentioned a maximum amount of time is 30 seconds and polling time (frequency with which we can check the condition) is 3 seconds. When I will launch the page then it will wait for 30 seconds for the expected alert modal and after every 3 seconds it will look for the alert modal, and will print a message ‘Alert not present’ until it finds the alert on the page. If alert does not appear after 30 seconds it will throw alertnotpresent exception, if user clicks on the button in between 30 seconds it will accept the Alert modal.
In this code I have used function to implement the fluentwait, I am returning a Boolean value using function and we can also return an element here.
Alert alert=null;
Alert a=w.switchTo().alert();
Wait<Alert> w111=new FluentWait<Alert>(a).withTimeout(30, TimeUnit.SECONDS).pollingEvery(3,TimeUnit.SECONDS).ignoring(TimeoutException.class);
w111.until(new Function<Alert, Boolean>()
{
@Override
public Boolean apply(Alert arg0)
{
Boolean result=false;
if(arg0!=null)
{
arg0.accept();
result=true;
}
else
{
System.out.println(“Alert not present”);
result=false;
}
return result;
}
});
Fluent wait with predicate:
A scenario for fluent wait with predicate – Herea button exists in a web page having ID :‘popup_container’, and when user clicks on the button an HTML popup appears in the page, here I am trying to verify that when I click on the button a pop-up appears on the page. Maximum waiting time and pooling time are same as above example.
When I will launch the page then it will wait for 30 seconds for the expected popup and after every 3 seconds it will look for the popupwindow, until alert does not present it will print ‘Element is not present…’ after every 3 seconds. If modal does not appear after 30 seconds it will throw Elementnotpresent exception, if user clicks on the button in between 30 seconds it will print ‘got it!!!!! element is present on the page….’.
FluentWait<WebDriver>fw=new FluentWait<WebDriver>(w).withTimeout(30,TimeUnit.SECONDS).pollingEvery(3,TimeUnit.SECONDS).ignoring(ElementNotFoundException.class);
fw.until(new Predicate<WebDriver>()
{
Boolean result=false;
@Override
publicboolean apply(WebDriver arg0)
{
WebElement e;
e=getElement(arg0,”id”,”popup_container”);
if(e!=null)
{
System.out.println(“got it!!!!! element is present on the page….”);
result=true;
}
else
{
System.out.println(“Element is not present…”);
}
return result;
}
});
Keep looking for our blog section for more on automating web apps.