java 使用 WebDriver 暂时绕过隐式等待

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11034710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:32:29  来源:igfitidea点击:

Temporarily bypassing implicit waits with WebDriver

javaseleniumselenium-webdriverwebdriverwait

提问by Jonik

When using implicit waits, as advised here, I still sometimeswant to assert the immediateinvisibility or non-existence of elements.

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

In other words, I knowsome elements should be hidden, and want my tests make that assertion fast, without spending several seconds because of the (otherwise useful) implicit wait.

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

One thing I tried was a helper method like this:

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

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

But in the above code, the call to until()only returns after the implicit wait time has passed, i.e., it doesn't do what I wanted.

但是在上面的代码中,调用until()在隐式等待时间过去后返回,即它没有做我想要的。

This is the only way I've found so far that works:

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

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

... where e.g. turnOffImplicitWaits()is a helper in common Selenium superclass:

... 其中 egturnOffImplicitWaits()是普通 Selenium 超类中的帮手:

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

But that is not very elegant, I think. Is there any cleaner way to bypass the implicit wait occasionally?

但这不是很优雅,我认为。有没有更简洁的方法可以偶尔绕过隐式等待?

采纳答案by Jonik

Given that Selenium doesn't seem to offer what I want directly (based on what Mike Kwan and Slanec said), this simple helper method is what I went with for now:

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

If the element is hidden or not present at all, the method returns true; if it is visible, returns false. Either way, the check is done instantly.

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

Using the above is at least much cleaner than littering the test cases themselves with calls to turnOffImplicitWaits()and turnOnImplicitWaits().

使用上面的方法至少比通过调用turnOffImplicitWaits()和来乱丢测试用例本身要干净得多turnOnImplicitWaits()

See also these answers for fined-tuned versions of the same approach:

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

回答by Mindshadow71

I would also suggest changing the parameter to a "By" locator for more flexibility when looking for the element.

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

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

That way, you could search by css if needed rather than just id:

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

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

'Course, your locator should probably be designed to return only one element (unlike the "By" example I quickly grabbed, which returns all part links in a css table of rows...) So, an "id" example would look like

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

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

回答by magnusarinell

My implementation:

我的实现:

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

With extension method:

使用扩展方法:

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

And class:

和类:

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

回答by 3urdoch

@Jonic's answerhelped me, however I would add a try { } finally { }and call turnOnImplicitWaits()in the finallyblock to make sure it always turns back on.

@Jonic 的回答对我有帮助,但是我会在块中添加一个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;
}

回答by Petr Jane?ek

My approach was to bypass Implicit wait entirely and reimplement it (with an addition of a visibility check etc.) in my own findElement()and findElements()methods which I now use by default. This way, when I want to check something instantly, I can call the original WebDriver method which does, of course, not wait.

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

回答by JayZee

In an existing code relying a lot on implicit wait way of thinking, and without CSS to the rescue, I found a way out nfor that kind of things, complementing it with Jsoup, and going on with Jsoup:

在大量依赖隐式等待思维方式的现有代码中,没有 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")