使用WebDriver暂时绕过隐式等待

Jon*_*nik 22 java selenium webdriver wait selenium-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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是在上面的代码中,调用until()在隐式等待时间过去后才返回,即它不能完成我想要的操作.

到目前为止,这是我发现的唯一方法:

@Test
public void checkThatSomethingIsNotVisible()  {
    turnOffImplicitWaits();
    // ... the actual test
    turnOnImplicitWaits();
}
Run Code Online (Sandbox Code Playgroud)

...例如turnOffImplicitWaits(),Selenium超类中的助手:

protected void turnOffImplicitWaits() {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}
Run Code Online (Sandbox Code Playgroud)

但我觉得这不是很优雅.是否有任何更清洁的方法偶尔绕过隐式等待?

Jon*_*nik 20

鉴于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);
}
Run Code Online (Sandbox Code Playgroud)

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

使用上述内容至少比通过调用turnOffImplicitWaits() 和调用测试用例本身更加清洁turnOnImplicitWaits().

另请参阅这些相同方法的精细调整版本的答案:


小智 7

我还建议将参数更改为"By"定位器,以便在查找元素时获得更大的灵活性.

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

这样,你可以根据需要搜索css,而不仅仅是id:

By PartLinkLocator = By.cssSelector("div.search-result div.row a");
Run Code Online (Sandbox Code Playgroud)

'当然,你的定位器应该设计为只返回一个元素(不像我快速抓取的"By"示例,它返回行的css表中的所有部分链接...)所以,"id"示例看起来像

By usernameLocator = By.id("inputEmail");
myResult = isElementHiddenNow(usernameLocator);
Run Code Online (Sandbox Code Playgroud)


mag*_*ell 5

我的实现:

using (driver.NoImplicitWait())
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

使用扩展方法:

public static NoImplicitWait NoImplicitWait(this IWebDriver driver)
{
    return new NoImplicitWait(driver);
}
Run Code Online (Sandbox Code Playgroud)

和类:

public sealed class NoImplicitWait : IDisposable
{
    private readonly IWebDriver _driver;

    public NoImplicitWait(IWebDriver driver)
    {
        _driver = driver;
        _driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0));
    }

    public void Dispose()
    {
        _driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
    }
}
Run Code Online (Sandbox Code Playgroud)