FluentWait’s newly introduced method ‘Duration.of()’ in Selenium 4
What you will Learn:
Newly introduced Duration.of() method in Fluent Wait (Selenium 4)
Code snippets
Newly introduced Duration.of() method in Fluent Wait (Selenium 4)
Let us see how we can setup FluentWait in Selenium 4 to explicitly wait for an element to load on a webpage.
The difference between FluentWait and ExplicitWait (see previous article) is that we can more customizations to FluentWait. For example, we can add polling time (keep searching for an element every 500 Millisecond) in FluentWait. We can also tell FluentWait to ignore few exceptions.
Before we practically see the enhanced FluentWait approach in Selenium 4, let us quickly see the older approach in Selenium 3.
Let us automate a simple use case:
Launch https://www.selenium-tutorial.com/courses
Fluently wait for the clickable link ‘LIFETIME MEMBERSHIP TO ALL LIVE TRAININGS’ to appear
Click the link
Validate that the url contains the string “lifetime-membership-club”
Let us inspect the link ‘LIFETIME MEMBERSHIP TO ALL LIVE TRAININGS’
Below is the code snippet for Selenium 3.
In the old approach, we used to write (<timeInSeconds>, TimeUnit.SECONDS)
//Old Approach (Selenium 3)
Wait<WebDriver> fw = new FluentWait<WebDriver>(driver)
.withTimeout(2, TimeUnit.SECONDS)
.pollingEvery(2, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
fw.until(ExpectedConditions.elementToBeClickable(By.linkText("LIFETIME MEMBERSHIP TO ALL LIVE TRAININGS"))).click();
fw.until(ExpectedConditions.urlContains("lifetime-membership-club"));
Notice below that with the older approach, we get an error:
The method withTimeout(Duration) in the type FluentWait<WebDriver> is not applicable for the arguments (int, TimeUnit)
Let us now look at the new approach.
In the new approach, we represent the same things using Duration.ofSeconds() method as shown below:
//New Approach (Selenium 4)
Wait<WebDriver> fw = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(5))
.pollingEvery(Duration.ofSeconds(1))
.ignoring(NoSuchElementException.class);
fw.until(ExpectedConditions.elementToBeClickable(By.linkText("LIFETIME MEMBERSHIP TO ALL LIVE TRAININGS"))).click(); fw.until(ExpectedConditions.urlContains("lifetime-membership-club"));
There are many other options available, example, ofDays, ofHours, ofNanos etc as can be seen below
Let us comment the old approach. Notice that there is no error in new approach:
Save and run the script. Notice that Selenium finds and clicks the link ‘LIFETIME MEMBERSHIP TO ALL LIVE TRAININGS’.
Also, the actual url does contain the expected string and hence there are no errors
Let us intentionally introduce an error in the urlContains string so that the test case fails
Save and run the test.
Notice below that Selenium waits for 5 seconds for the desired url string. When it does not find the expected string, it throws an exception. This indicates that our FluentWait is indeed working fine
See the console log
Code snippet
package sel4scripts;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import io.github.bonigarcia.wdm.WebDriverManager;
public class FluentWaitSel4 {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.get("https://www.selenium-tutorial.com/courses");
/*
//Old Approach (Selenium 3)
Wait<WebDriver> fw = new FluentWait<WebDriver>(driver)
.withTimeout(2, TimeUnit.SECONDS)
.pollingEvery(2, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
fw.until(ExpectedConditions.elementToBeClickable(By.linkText("LIFETIME MEMBERSHIP TO ALL LIVE TRAININGS"))).click();;
fw.until(ExpectedConditions.urlContains("lifetime-membership-club"));
*/
//New Approach (Selenium 4)
Wait<WebDriver> fw = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(5))
.pollingEvery(Duration.ofSeconds(1))
.ignoring(NoSuchElementException.class);
fw.until(ExpectedConditions.elementToBeClickable(By.linkText("LIFETIME MEMBERSHIP TO ALL LIVE TRAININGS"))).click();;
fw.until(ExpectedConditions.urlContains("lifetime-membership-club"));
}
}
Thank you for reading!