4

After reading an article about JDK1.8 and Lambda expressions, I realized that the ExpectedCondition block that I have been using for the last few years is probably suitable to be expressed as a Lambda expression.

Given this wait object:

Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring( NoSuchElementException.class );

Can anyone tell me how I can convert this ExpectedCondition expression, for Selenium, into a Lambda expression?

  WebElement foo = wait.until( new ExpectedCondition<Boolean>() {
       public WebElement apply( WebDriver webDriver ) {
           return webDriver.findElement( By.id("foo") );
       }
  } );
3
  • 3
    wait.until(webDriver -> webDriver.findElement(By.id("foo"))) Commented Aug 31, 2013 at 21:15
  • That looks right to me. Thanks for the quick answer. I am still trying to wrap my head around that syntax. Commented Aug 31, 2013 at 21:19
  • I've added it as an answer since I figured it'd do better service to the site as an answer than a comment. Commented Aug 31, 2013 at 21:54

3 Answers 3

3

From Selenium version 3.2.0 the until() method will only accept Function<T,K> as parameter and taking in Predicate<T> as a parameter is deprecated.

The above decision is to make use of lambda expressions.

So to answer you question:

Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring(NoSuchElementException.class);

//lamda expression:
WebElement foo = wait.until(d -> d.findElement(By.id("foo")));
Sign up to request clarification or add additional context in comments.

3 Comments

Can you please explain this to me or give me a link to an article about this?
What is that you want to explain, lamda expressions or FluentWait?
Lambda Expression
2

Basically, while lamdas are not just anonymous classes - they really help when you want to discuss verbs and offer more concise code in places anonymous classes had to be used in the past.

We want to tell Selinium to wait until an action occurs. With the old syntax we'd have to create a new anonymous implementation of the ExpectedCondition interface - with lambdas this is no longer the case.

So assuming that Selinium will support this syntax, it should be something like :

wait.until(webDriver -> webDriver.findElement(By.id("foo")))

Reducing the length of your code, and making it more readable.

More generally:

new Interface{
    public ReturnValue action(Type first,Type second...){
         return SomeExpression();
    }
}

Becomes:

(first,second) -> SomeExpression();

Comments

0

Not quite. With Java 8 we should be able to replace an anonymous inner class implementing a "single abstract method interface" with a lambda as follows:

new FluentWait<WebDriver>( driver )   // Would be nice!
   .withTimeout(30, SECONDS)
   .pollingEvery(5, SECONDS)
   .ignoring( NoSuchElementException.class )
   .until(wd -> wd.findElements(By.id("foo")).size() == 1);

The problem is that this only works if the receiving method FluentWait.until only accepts ONE "single abstract method interface". Because until accepts more than one, you would get the following compile time error:

The method until(Predicate) is ambiguous for the type FluentWait

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.