【问题标题】:Can not understand the implementation of until() method in FluentWait无法理解 FluentWait 中 until() 方法的实现
【发布时间】:2015-07-16 11:18:48
【问题描述】:

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

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

  • 匿名类
  • Lambda 表达式
  • 方法参考

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

方法 until(Predicate) 对于 WebDriverWait 类型不明确

我的 Lambda:

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

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

所以我的问题是,以 Predicate 作为参数的 until 方法有什么用?

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

【问题讨论】:

    标签: java selenium selenium-webdriver lambda webdriver


    【解决方案1】:

    回答您的第一个问题:

    看看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);
    

    【讨论】:

    • 是的,我从未观察到,ExpectedConditions 类中的每个方法都返回ExpectedCondition&lt;T&gt; 其中extends Function&lt;T&gt;。所以我对问题的第一部分的所有头发撕裂只是由于疏忽。感谢您的回答,现在是第二部分,我希望这也不会成为失败者。
    • 刚要推送我答案的第二部分,当您发表评论时 ;-)
    • 再次感谢。一般来说,我也可以直接传递 Lambda,但在 until() 中,我不得不使用对 lambda 的引用。这就引出了一个问题,为什么当第一个(以Function&lt;T&gt; 作为参数)可以实现相同的方法时重载一个方法。
    • 嘿@Husam,“一般情况下我可以通过 Lambda”是什么意思?您的意思是其他仅采用 Function super F, T> 作为参数,您可以将它们交给您的裸 lambda 表达式吗?你有一个例子,它可以像你期望的那样工作吗?
    • String s = (String) squareInWords(i -&gt; String.valueOf(i*i), 2); static CharSequence squareInWords (java.util.function.Function&lt;Integer, ? extends CharSequence&gt; f, Integer n) { return f.apply(n); }
    【解决方案2】:

    如你所说,until 方法重载,预期参数为Predicate&lt;T&gt;Function&lt;? super T, V&gt;

    你的 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);
    

    【讨论】:

      【解决方案3】:

      当您的 lambda 表达式同时匹配谓词和函数时,您会收到错误消息。

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

      【讨论】:

        【解决方案4】:

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

        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;
            }); 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-17
          • 1970-01-01
          • 2018-07-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-24
          • 2014-01-25
          相关资源
          最近更新 更多