使用隐式等待 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);
}
但我觉得这不是很优雅。 有没有更干净的方法偶尔绕过隐性等待?
答案 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")