Selenium findElements() 是否必须隐式等待 return 0 个元素?

Does Selenium findElements() have to implicitly wait to return 0 elements?

我带着一个关于 Selenium 的问题来到这里。在我的测试中,我需要删除网络应用程序中的一些项目,然后我想验证项目列表是否为空。 我知道它看起来微不足道,但我有一些小问题。这就是我要检查我的项目列表是否为空的方式:

Assert.assertEquals(page.getSearchResultList().size(), 0);

简单且有效,但...由于 implicitlyWait 而变慢。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

事实上,当我删除项目时,getSearchResultList().size() 为 0,Selenium 总是在 findElements() returns 0 大小之前等待 10 秒。

为了避免这 10 秒的等待,我有一个解决方法来修改 implicitlyWait 就在我的断言之前,但我认为这不是一个好主意。

page.getDriver().manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
Assert.assertEquals(page.getSearchResultList().size(), 0);

还有其他更好的解决方案吗?

请求更新 @KunduK

在没有 WebDriverWait 的情况下断言:

    Instant start = Instant.now();
    List<WebElement> resultSearchList = page.getDriver().findElements(By.cssSelector("[ng-repeat='searchResult in $ctrl.searchResults']"));
    Assert.assertEquals(resultSearchList.size(), 0);
    Instant stop = Instant.now();
    log.debug("Assert Took: " + Duration.between(start, stop).getSeconds() + " sec");

输出:

10:49:59.081 [main] DEBUG impl.AssertNewEntityPage - Assert Took: 10 sec

使用 WebDriverWait 断言

    Instant start = Instant.now();
    new WebDriverWait(page.getDriver(), 10).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("[ng-repeat='searchResult in $ctrl.searchResults']")));
    List<WebElement> resultSearchList = page.getDriver().findElements(By.cssSelector("[ng-repeat='searchResult in $ctrl.searchResults']"));
    Assert.assertEquals(resultSearchList.size(), 0);
    Instant stop = Instant.now();
    log.debug("Assert Took: " + Duration.between(start, stop).getSeconds() + " sec");

输出:

10:57:08.215 [main] DEBUG impl.AssertNewEntityPage - Assert Took: 20 sec

可以使用ExpectedConditions.invisibilityOfElementLocated()等待元素不可见,然后取元素的size()。

new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("locator xpath")));
List<WebElement> elements = driver.findElements(By.xpath("locator xpath"));
Assert.assertEquals(elements.size(), 0);

您可以等待页面完全加载..

public static boolean waitForJSandJQueryToLoad() {
    log.info("Waiting for jQuery to load...");
    ExpectedCondition<Boolean> jQueryLoad = d -> {
        try {
            log.info("jQuery presented.");
            return ((Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active") == 0);
        } catch (Exception e) {
            log.info("No jQuery presented.");
            return true;
        }
    };
    log.info("Waiting for javascript to load...");
    ExpectedCondition<Boolean> jsLoad = d -> ((JavascriptExecutor) driver).executeScript("return document.readyState")
            .toString().equals("complete");
    return wait.until(jQueryLoad) && wait.until(jsLoad);
}    

stalenessOf()

stalenessOf() 是等待元素不再附加到 DOM.

的期望

这个用例

的这个用例...删除 Web 应用程序中的项目... 映射到 stalenessOf(WebElement element)[的 ExpectedConditions。如此有效,您的代码块将是:

new WebDriverWait(driver, 10).until(ExpectedConditions.stalenessOf(By.cssSelector("cssSelector_of_element_to_be_stale")));
Assert.assertEquals(page.getSearchResultList().size(), 0);

Note: As your usecase already involves and this answer suggests to induce WebDriverWait i.e. ExplicitWait, as per the documentation, ...Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds...

您可以在

中找到相关讨论