When you ask selenium tester what is the most common issues he is facing during his automation testing experience, the first thing he would say is Sync problem.
Let’s take a bird eye view on this and will take deep dive on the synchronization issues and how to address them.
Selenium framework has several methods to address the synchronization issues. Mainly they are segregated into two different varieties.
- Implicit waits
- Explicit waits
This is the most common wait type we use; it is also called as default wait. The page load time out, and the timeouts.implicitwait is the two types of implicit wait. The implicit wait meaning that the driver has to wait until the web element is existed on the dom. It will come out of the waiting loop if element exists beforehand. Example you have given 10 seconds on element x, and it has loaded in 2 seconds web driver knows it and goes to next step without waiting for 10 seconds. It is called as implicit wait.
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Explicit waits are defined on the particular web element to wait until the property value becomes true.
It will pole every 500 milliseconds to get the property value and verifies it with defined value.
//webdriver wait class WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.xpath(menu)))); //for multiple elements WebDriverWait wait = new WebDriverWait(driver, 30); List options = driver.findElements(By.xpath(option_to_select)); wait.until(ExpectedConditions.visibilityOfAllElements(options)); //Another example WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(ExpectedConditions.invisibilityOfElementWithText(By.className("jqx-fill-state-normal"), "Loading..."));
Fluent waits also called as explicit waits, but only difference being we can define interval to pole and can tell to ignore any exceptions. It will be useful to save resources not to check every 500 milliseconds if element load takes long time.
Wait<WebDriver> fluentwait = new FluentWait<WebDriver>(driver) .withTimeout(20, TimeUnit.SECONDS) .pollingEvery(1, TimeUnit.SECONDS) .ignoring(java.util.NoSuchElementException.class); fluentwait.until(ExpectedConditions.invisibilityOfElementWithText(By.className("jqx-fill-state-normal"), "Loading..."));
The another type of wait is normally not recommended is static wait or pause the program.
So, the gist is the know when to use what. Fluent wait is used when application slower and running in a slow paced machine where we don’t want driver to hit every 500 milliseconds, and you know it will not come till 2 sec or 3 seconds, we can define the polling interval. I am guessing this as it is synonymous to implicit wait where the default polling is 500 ms.
We can use web driver wait almost in all cases where we know element loading is taking place, but the properties are not loaded until some other action is completed, example, state dropdown is enabled only when country drop down is selected, in that case we can use expected conditions on the enabled of the state dropdown after country select.
Default waits or implicit waits are used when we know dom loading is taking some time and not to give wait on existence of each element. Normally this would serve the purpose, but angular applications waits plays key role in test execution failures.
If we use waits wisely and where ever we need depending the application behavior with limited use of static waits will improve the script quality drastically.