无法理解FluentWait中until()方法的实现

时间:2015-07-16 11:18:49

标签: java selenium selenium-webdriver lambda webdriver

until()中的org.openqa.selenium.support.ui.FluentWait方法因Predicate<T>Function<? super T, V>接口而被重载为参数。

它应该作为以下参数之一(实现apply()方法):

  • 匿名课程
  • Lambda表达
  • 方法参考

我定义为此方法的参数的任何lambda都会抛出以下错误:

对于WebDriverWait类型

,(Predicate)方法不明确

我的Lambda:

x -> x.findElement(byLocator).isDisplayed()

我假设任何lambda都是这种情况,因为函数或谓词的apply()可以通过使用这些lambda来实现。

所以我的问题是什么是使用谓词作为参数的until方法?

更新: 删除了@drkthng回答的问题的第一部分。

4 个答案:

答案 0 :(得分:2)

回答您的第一个问题:

查看Selenium API docs for ExpectedConditon

我引用:

public interface ExpectedCondition<T>
extends com.google.common.base.Function<WebDriver,T>

你看,ExpectedCondition继承自google的Function接口,因此你可以将它用作until()方法的参数。

至于你的第二个问题:

我认为你不能像那样交出一个lambda。直到方法等待谓词或函数(正如您正确提到的那样)。

关于Predicates和lambdas之间的区别,请查看示例here

所以你可以尝试这样的东西,仍然使用你的lambda表达式:

Predicate<WebDriver> myPredicate = x ->x.findElement(By.id("id")).isDisplayed();

WebDriverWait wait = (WebDriverWait)new WebDriverWait(driver, 10);
wait.until(myPredicate);

答案 1 :(得分:0)

正如您所说,方法until已超载且预期参数为Predicate<T>Function<? super T, V>

你的lambda表达式匹配两个签名,所以对方法的调用是不明确的,为了解决歧义,有几个选项:

将lambda表达式转换为所需类型:

until((Predicate<WebDriver>) x -> x.findElement(byLocator).isDisplayed());

如果为lambda表达式创建变量,则不需要强制转换:

Predicate<WebDriver> p = x.findElement(byLocator).isDisplayed();
until(p);

如果您有使用此功能的方法,则可以使用方法参考:

boolean testMethod(WebDriver x) {
    return x.findElement(byLocator).isDisplayed();
} 

until(MyClass::testMethod);

答案 2 :(得分:0)

您收到错误,因为您的lambda表达式与谓词和函数匹配。

考虑将selenium升级到v3.2.0 - &gt;其中不推荐使用FluentWait.until(Predicate<?>)方法。这应该使lambdas现在可以正常使用Wait实例。

答案 3 :(得分:0)

下面的功能接口实现应解决问题:

FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
    wait.pollingEvery(500, TimeUnit.MILLISECONDS);
    wait.withTimeout(5, TimeUnit.MINUTES);
    wait.ignoring(NoSuchElementException.class);
    wait.until((WebDriver arg0) ->{
    WebElement element = arg0.findElement(By.id("colorVar"));
    String color = element.getAttribute("style");
    System.out.println("The color if the button is " + color);
    if(color.equals("color: red;"))
    {
        return true;
    }
    return false;
    });