2012-06-14 61 views
20

当使用隐式等待,as advised here,我仍然有时要断言立即隐形或元件的不存在。暂时绕过隐等待用的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; 
    } 
} 

但在上面的代码,调用until()隐含的等待时间已经过去了,即在只返回,它不做我想要的。

这是我到目前为止发现的唯一方式工作:

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

...其中,例如turnOffImplicitWaits()是常见的硒超帮手:

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

但是,这是不是很优雅,我想。 有没有更简单的方法来绕过隐含的等待时间?

+1

我不'我相信界面上有任何东西都是你想要的。我唯一能想到的就是调用findElements而不是findElement。但我不确定是否绕过了隐含的等待。 –

+2

@MikeKwan不,['findElements()'](http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebDriver.html#findElements%28org.openqa.selenium .By%29)也会在至少找到一个元素后尝试等待并返回。 –

+0

对于lambdas来说,这将是一个很好的例子 'public void bypassImplicitWaits {Bypass bypass} {return 0ffImplicitWaits(); bypass.do(); turnOnImplicitWaits(); }' – michaelsnowden

回答

16

鉴于硒似乎并没有提供什么我直接想(基于迈克关和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()时更容易丢弃测试用例本身。

也看到这些答案对同一方法的罚款调校的版本:

+0

你如何打开隐式等待? –

+0

@JeffMay:类似于'driver.manage()。timeouts()。implicitlyWait(10,TimeUnit.SECONDS);'。见例如[这个答案](http://stackoverflow.com/a/10950905/56285)。 – Jonik

+0

使用作为参数的例子,所以它会更容易,可以用于所有:) –

1

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

+0

如何在不使用implicitWait选项的情况下等待?你是否只是在某种循环中实现try/catch,并且每隔几秒轮询一次该元素,直到达到某个阈值? – AndyPerfect

+0

@AndyPerfect是的,通常的(尝试赶上,再次尝试或超时)的方法与一些基本的附加功能:可见性,禁用的元素,突出显示找到的元素,解决方法页面没有真正加载(再次启动StaleElementReference)此](http://code.google.com/p/selenium/issues/detail?id=3800)和[this](http://code.google.com/p/selenium/issues/detail?id= 3470)的错误。 –

2

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

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

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

“当然,你的定位可能应该被设计成只返回一个元素(不像‘通过’的例子:

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

这样的话,你可以,如果需要,而不仅仅是ID通过CSS搜索我迅速抓住,它返回的所有部分链接行...的CSS表)所以,一个“id”的例子看起来像

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

绝对的尝试/最后是要走的路。 –

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