Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium Java Lambda Implementation for Explicit Waits

I am trying to implement Java Lambda concept for selenium webdriver waits. I need to convert custom webdriver wait something like this

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

to

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

But it does not matches the functional interface of 'until' refers to and throws error.

So i tried passing the Lambda as it supports.

Attempt1

Predicate<WebDriver> isVisible = (dr) -> dr.findElement(
     By.linkText("")).isDisplayed();
     webDriverWait.until(isVisible);

It kind of works but is not what i require because it returns only void.

Need your help or advice on this.

like image 739
Vish Shady Avatar asked Jun 28 '15 16:06

Vish Shady


2 Answers

The problem is with your syntax.The below worked perfectly for me

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

Your code Problem

 //What is this driver() is this a function that returns the driver or what
 //You have to defined the return type of driver variable in until() function
 //And you cant use the same  variable names in both new WebdriverWait() and until() see my syntax

(new WebDriverWait(driver(), 5)).until((driver) -> driver.findElement(By.linkText("")));
like image 124
Madhan Avatar answered Nov 13 '22 19:11

Madhan


Because the method WebDriverWait#until is overloaded: until(Function) and until(Predicate), the compiler cannot infer the type of the argument to the lambda method.

In this case, both functional interfaces Function and Predicate take a single argument, which in this case is either <? super T> or T. Therefore the declarative syntax is needed here:

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

Note that the lambda return types do not help the compiler to distinguish these cases. In your example, since #findElement returns WebElement, this is conceptually enough to distinguish a Function from a Predicate, but apparently not enough for the compiler.

See also: http://tutorials.jenkov.com/java/lambda-expressions.html#parameter-types

like image 28
jordanpg Avatar answered Nov 13 '22 20:11

jordanpg