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
Temporarily bypassing implicit waits with WebDriver
提问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 finally
block 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")