【问题标题】:Wait.until() with Webdriver PageFactory elements带有 Webdriver PageFactory 元素的 Wait.until()
【发布时间】:2019-02-02 18:05:13
【问题描述】:

我正在使用@FindBy 注释来定位我页面上的元素。像这样:

   @FindBy(xpath = "//textarea")
    public InputBox authorField;

请帮忙。我想对带注释的元素使用 wait (ExpectedConditions)。像这样:

wait.until(visibilityOfElementLocated(authorField));

代替:

wait.until(visibilityOfElementLocated(By.xpath("//textarea")));

感谢提前

【问题讨论】:

    标签: java webdriver selenium-webdriver


    【解决方案1】:
    ExpectedConditions.visibilityOf(authorField);
    

    查看任何预期条件的源代码。编写自己的条件非常容易,可以做任何你想做的事情。

    【讨论】:

      【解决方案2】:

      问题在于,采用WebElement 的方法通常假定已经找到了 WebElement(他们是对的!PageFactory 对其进行了排列,以便在方法访问该元素之前找到它。),即存在于这页纸。当给方法一个 By 时,你说“我希望它被找到,我只是不知道它什么时候会出现。”

      你可以使用

      wait.until(visibilityOf(authorField));
      

      结合

      // right after driver is instantiated
      driver.manage().timeouts().implicitlyWait(...);
      

      这应该是你喜欢的方式。

      implicitlyWait()documentation 说:

      指定驱动程序在搜索未立即存在的元素时应等待的时间。

      当搜索单个元素时,驱动程序应该轮询页面直到找到该元素,否则在抛出 NoSuchElementException 之前超时到期。搜索多个元素时,驱动程序应轮询页面,直到找到至少一个元素或此超时已过期。

      因此,基本上,每次查找时它都会等待一个元素出现。显然,这对各种异步请求都有好处。

      【讨论】:

      • implicitlyWait 对异步页面加载有好处吗?因为我需要将它与 AJAX 一起使用?
      • 谢谢!毕竟 Pavel Zorin 是对的,即使这样做,我也必须编写自己的条件。
      • 嗯,这是混合了隐式和显式等待,Selenium 明确告诉我们不要这样做。 (见第二段警告here。)
      • 在 NO 条件下,您应该在 Selenium 中混合隐式和显式等待。这会给你带来非常糟糕的表现。
      【解决方案3】:

      我知道这个问题已经得到解答,并且在不久前被问到,但我想我会提供一个具体示例来说明如何为此编写您自己的预期条件。通过创建这个预期条件类:

      /**
       * Since the proxy won't try getting the actual web element until you
       * call a method on it, and since it is highly unlikely (if not impossible)
       * to get a web element that doesn't have a tag name, this simply will take
       * in a proxy web element and call the getTagName method on it. If it throws
       * a NoSuchElementException then return null (signaling that it hasn't been
       * found yet). Otherwise, return the proxy web element.
       */
      public class ProxyWebElementLocated implements ExpectedCondition<WebElement> {
      
          private WebElement proxy;
      
          public ProxyWebElementLocated(WebElement proxy) {
              this.proxy = proxy;
          }
      
          @Override
          public WebElement apply(WebDriver d) {
              try {
                  proxy.getTagName();
              } catch (NoSuchElementException e) {
                  return null;
              }
              return proxy;
          }
      
      }
      

      那么这将允许你这样做:

      wait.until(new ProxyWebElementLocated(authorField));
      

      这就是你真正需要的。但是如果你想更进一步的抽象,你可以创建一个这样的类:

      public final class MyExpectedConditions {
      
          private MyExpectedConditions() {}
      
          public static ExpectedCondition<WebElement> proxyWebElementLocated(WebElement proxy) {
              return new ProxyWebElementLocated(proxy);
          }
      }
      

      这将允许你做这样的事情:

      wait.until(MyExpectedConditions.proxyWebElementLocated(authorField));
      

      MyExpectedConditions 类对于一个预期条件可能有点矫枉过正,但如果您有多个预期条件,那么拥有它会让事情变得更好。

      作为最后一点,对于任何真正想要加倍努力的人,您还可以将方法添加到 MyExpectedConditions 类,将方法包装在 ExpectedConditions 类中,然后您可以获得所有预期条件的东西从一处。 (我建议扩展 ExpectedConditions 而不是使用包装器方法,但它有一个私有构造函数,因此无法扩展。这使得包装器方法成为那些真正想要所有东西都集中在一个地方的人的唯一选择。)

      【讨论】:

        【解决方案4】:

        正如其他答案中提到的,ExpectedConditions.visibilityOf(authorField); 将完成这项工作。为了更清楚,请在下面提及详细的解决方案。

        public class YourTestPage {
            private WebDriver driver;
            private WebDriverWait wait;
        
            @FindBy(xpath = "//textarea")
            private WebElement authorField;
        
            public YourTestPage(WebDriver driver) {
                this.driver = driver;
                wait = new WebDriverWait(driver, 15, 50);
                PageFactory.initElements(driver,this);
            }
        
            public void enterAuthorName() {
                wait.until(ExpectedConditions.visibilityOf(authorField)).sendKeys("Author Name");
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-09
          • 2013-10-30
          • 1970-01-01
          相关资源
          最近更新 更多