使用 WebDriver 暂时绕过隐式等待

当使用隐式等待时,正如这里所建议的那样,我有时仍然想断言元素的直接不可见或不存在。

换句话说,我知道一些元素应该被隐藏,并希望我的测试能够快速做出断言,而不会因为(否则有用的)隐式等待而花费几秒钟。

我尝试的一件事是像这样的帮助器方法:

// NB: doesn't seem to do what I want
private boolean isElementHiddenNow(String id) {
    WebDriverWait zeroWait = new WebDriverWait(driver, 0);
    ExpectedCondition<Boolean> c = invisibilityOfElementLocated(By.id(id));
    try {
        zeroWait.until(c);
        return true;
    } catch (TimeoutException e) {
        return false;
    }
}

但是在上面的代码中,对的调用仅在隐式等待时间过后返回,即,它不执行我想要的操作。until()

这是迄今为止我发现的唯一有效方法:

@Test
public void checkThatSomethingIsNotVisible()  {
    turnOffImplicitWaits();
    // ... the actual test
    turnOnImplicitWaits();
}

...例如 是常见的硒超类中的助手:turnOffImplicitWaits()

protected void turnOffImplicitWaits() {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}

但我认为这并不是很优雅。有没有更清晰的方法来绕过偶尔的隐式等待?


答案 1

鉴于Selenium似乎没有直接提供我想要的东西(基于Mike Kwan和Slanec所说的),这个简单的助手方法就是我现在使用的:

protected boolean isElementHiddenNow(String id) {
    turnOffImplicitWaits();
    boolean result = ExpectedConditions.invisibilityOfElementLocated(By.id(id)).apply(driver);
    turnOnImplicitWaits();
    return result;
}

private void turnOffImplicitWaits() {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}

private void turnOnImplicitWaits() {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}

如果元素是隐藏的或根本不存在,则该方法返回 true;如果可见,则返回 false。无论哪种方式,检查都会立即完成。

使用上述内容至少比在测试用例本身中乱扔对 和 的调用要干净得多。turnOffImplicitWaits()turnOnImplicitWaits()

另请参阅以下答案,了解相同方法的微调版本:


答案 2

我还建议将参数更改为“By”定位器,以便在查找元素时具有更大的灵活性。

protected boolean isElementHiddenNow(By locator) {
    turnOffImplicitWaits();
    boolean result = false;
    try {
       result = ExpectedConditions.invisibilityOfElementLocated(locator).apply(driver);
    }
    finally {
       turnOnImplicitWaits();
    }
    return result;
}

这样,如果需要,您可以通过css进行搜索,而不仅仅是id:

By PartLinkLocator = By.cssSelector("div.search-result div.row a");

“当然,您的定位器可能应该设计为仅返回一个元素(与我快速抓取的”By“示例不同,该示例返回css行表中的所有零件链接...因此,“id”示例将如下所示

By usernameLocator = By.id("inputEmail");
myResult = isElementHiddenNow(usernameLocator);

推荐