2012-06-14 86 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")