使用WebDriver暂时绕过隐式等待

时间:2012-06-14 13:57:57

标签: java selenium selenium-webdriver webdriver wait

使用隐式等待 as advised here 时,我仍然有时想要断言立即隐身或不存在元素

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

我尝试过的一件事是这样的辅助方法:

// 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()是常见Selenium超类的助手:

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

但我觉得这不是很优雅。 有没有更干净的方法偶尔绕过隐性等待?

6 个答案:

答案 0 :(得分:19)

鉴于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(),使用上述内容至少要比调试案例本身更加清晰。

请参阅相同方法的罚款版本的这些答案:

答案 1 :(得分:7)

我还建议将参数更改为&#34; By&#34;定位器在寻找元素时具有更大的灵活性。

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");

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

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

答案 2 :(得分:4)

我的实施:

using (driver.NoImplicitWait())
{
    ....
}

使用扩展方法:

public static NoImplicitWait NoImplicitWait(this IWebDriver driver)
{
    return new NoImplicitWait(driver);
}

上课:

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));
    }
}

答案 3 :(得分:2)

@Jonic's answer帮助了我,但是我会添加try { } finally { }并在turnOnImplicitWaits()区块中调用finally以确保它始终重新开启。

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

答案 4 :(得分:1)

我的方法是完全绕过Implicit等待并在我自己的findElement()findElements()方法中重新实现它(加上可见性检查等),我现在默认使用这些方法。这样,当我想立即检查某些内容时,我可以调用原始的WebDriver方法,当然不会等待。

答案 5 :(得分:0)

在一个现有的代码中,很多依赖于隐式等待的思维方式,没有CSS来解救,我找到了解决这类问题的方法,用Jsoup补充它,继续使用Jsoup:

# this is straightforward Scala... put the types and it is Java.
val innerHtml = seleniumWebElementFatherInstance.getAttribute("innerHTML")
val jsoupElements = Jsoup.parse(innerHtml).select("div.your.css.selector")