【问题标题】:How to avoid timeouts when migrating isElementPresent() from Selenium 1 to Selenium 2?将 isElementPresent() 从 Selenium 1 迁移到 Selenium 2 时如何避免超时?
【发布时间】:2012-09-21 06:35:37
【问题描述】:

我正在尝试将 Java 代码从 Selenium 1 (RC) 迁移到 Selenium 2 (WebDriver),看起来像这样:

1:  selenium.click(someButton);
2:  selenium.waitForPageToLoad();
3:  if (!selenium.isElementPresent(errorMessageElement)) {
4:     Assert.fail("Test failed! No error msg should be displayed on page.");
5:  }

关键部分是第 3 行,根据Rostislav Matl 的建议,我尝试将其转换为 Selenium 2:

3:  if (!driver.findElements(By.xpath(errorMessageElement)).size() > 0) {

不幸的是,WebDriver 等待整个超时(在我的情况下为 60 秒)来检测元素确实 存在。虽然这可行,但它引入了太多的时间开销......

Selenium 2 中是否有任何方法可以高效地检查当前在 Web 浏览器中显示的 HTML 页面上是否存在某个元素?

【问题讨论】:

    标签: java selenium migration webdriver integration-testing


    【解决方案1】:

    这是一个两部分的答案

    1. 时间开销是正确的:因为您希望确保元素确实没有被渲染。也就是说,考虑到页面渲染时间、AJAX 元素等。我知道错误消息将与页面加载一起显示,但如果您想检查是否存在(或不存在)以几毫秒延迟显示的 ajax 元素,则超时很有用。

    2. 减少等待开销的技巧:您仍然可以像这样创建一个方法来临时重置隐式等待时间

    public boolean isElementNotPresent(By by) {
        boolean flag = true;
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
        if (!driver.findElements(by).size() > 0) {
            flag = false;
        } 
        driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
        return flag;
    }
    

    并在您要检查缺席的地方调用此方法,例如第 3 行和第 4 行将是

    if (!isElementNotPresent(By.xpath(xpathoferrorelement))) {
        Assert.fail("Test failed! No error msg should be displayed on page.");
    }
    

    【讨论】:

    • 这将只需要两秒钟来确保没有找到的元素。
    • IsElementNotPresent?叫 IsElementPresent 不是更好吗?
    • LOL...是的,您可以这样称呼它或您喜欢的任何名称...但这是逻辑...如果元素存在则该方法将返回false,如果不存在则返回true..所以' isElementNotPresent'.... ;)
    • 感谢您的想法。使用 driver.getPageSource() 然后在其中搜索元素的名称是否有意义?
    • @Dominik,不,这是一个非常糟糕的主意,更重要的是因为您没有验证用户不存在的内容(仅显示在页面上),但它也会在整个页面源中移动非常缓慢。
    【解决方案2】:

    尝试使用 FluentWait 类,它可以轻松配置您想要使用的条件: http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/support/ui/FluentWait.html

    【讨论】:

      【解决方案3】:

      当页面已经呈现时,我通常使用的几种方法(验证存在或不存在)。 方法一:

      input.findElements(By.xpath("//xpath")).size() > 0
      

      方法二:

      driver.findElement(By.cssSelector(propertyKeysLoader(key))).isDisplayed()
      

      方法3:

      public bool IsElementPresent(By selector)
      {
          return driver.FindElements(selector).Any();
      }
      

      如果你想要渲染元素(以防页面上没有所有 AJAX),那么你最好使用 Arek 提到的 fluent wait。

       public WebElement fluentWait(final By locator){
              Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                      .withTimeout(30, TimeUnit.SECONDS)
                      .pollingEvery(5, TimeUnit.SECONDS)
                      .ignoring(NoSuchElementException.class);
      
              WebElement foo = wait.until(
      new Function<WebDriver, WebElement>() {
                  public WebElement apply(WebDriver driver) {
                              return driver.findElement(locator);
                      }
                      }
      );
                                 return  foo;              }     ;
      

      在字符串.pollingEvery(5, TimeUnit.SECONDS) 中,您可以设置任何迭代超时。很舒服。 希望这对您有所帮助)

      【讨论】:

        猜你喜欢
        • 2011-08-07
        • 1970-01-01
        • 2020-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-05
        相关资源
        最近更新 更多