What is the difference between using lambda function in FluentWait usage and not using it?

1k Views Asked by At

The wait for an element can be coded as

WebElement foo = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("foo")));

In the docs of the FluentWait, an example as given below excluding the definitions of the timeout, polling interval, exception ignoring.

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
 public WebElement apply(WebDriver driver) {
   return driver.findElement(By.id("foo"));
 }
});

What is the difference between the two? any added benefit?

I've searched for lambda expressions, functional interface. But I didn't quite get the picture.

2

There are 2 best solutions below

0
On BEST ANSWER

WebDriverWait

WebDriverWait is the specialization of FluentWait that uses WebDriver instances.

The constructors are:

  • WebDriverWait(WebDriver driver, java.time.Clock clock, Sleeper sleeper, long timeOutInSeconds, long sleepTimeOut)
  • WebDriverWait(WebDriver driver, long timeOutInSeconds): Inducing this Wait will ignore instances of NotFoundException that are encountered (thrown) by default in the 'until' condition, and immediately propagate all others.
  • WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis): Inducing this Wait will ignore instances of NotFoundException that are encountered (thrown) by default in the 'until' condition, and immediately propagate all others.

Lambda Implementation for WebDriverWait

Example A:

(new WebDriverWait(driver(), 5))
    .until(new ExpectedCondition<WebElement>() {
        public WebElement apply(WebDriver d) {
            return d.findElement(By.linkText(""));
        }
    });

Example B:

WebElement wer = new WebDriverWait(driver, 5).until((WebDriver dr1) -> dr1.findElement(By.id("q")));

Exmaple C:

(new WebDriverWait(driver(), 5)).until((driver) -> driver.findElement(By.linkText("Google")));

FluentWait

FluentWait is the implementation of the Wait interface that may have its timeout and polling interval configured on the fly.

Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.

Sample usage:

// Waiting 30 seconds for an element to be present on the page, checking for its presence once every 500 milliseconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(Duration.ofSeconds(30))
    .pollingEvery(Duration.ofMillis(500))
    .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.name("q"));
    }
});

Note: This class makes no thread safety guarantees.

You can find a working example of FluentWait in the discussion Selenium Webdriver 3.0.1: Selenium showing error for FluentWait Class

0
On

The difference between 2 Methods you mentioned above, is that second one is going to create an extra class in the memory (which is also known as Anonymous inner class), and first one will do no such thing. If an implementation of "Function" Interface is really needed, create a lambda and like mentioned above and you will see the same effect, and in this case it will not create a new Inner Class instance. Instead a call will be made to the interface method through "InvokeDynamic".