为了增加@jarib的答案,我提出了几种扩展方法来帮助消除竞争状况。
这是我的设置:
我有一个叫做“ Driver.cs”的类。它包含一个静态类,其中包含用于驱动程序的扩展方法和其他有用的静态函数。
对于通常需要检索的元素,我创建了一个扩展方法,如下所示:
public static IWebElement SpecificElementToGet(this IWebDriver driver) {
return driver.FindElement(By.SomeSelector("SelectorText"));
}
这使您可以使用以下代码从任何测试类中检索该元素:
driver.SpecificElementToGet();
现在,如果结果为StaleElementReferenceException
,则在驱动程序类中有以下静态方法:
public static void WaitForDisplayed(Func<IWebElement> getWebElement, int timeOut)
{
for (int second = 0; ; second++)
{
if (second >= timeOut) Assert.Fail("timeout");
try
{
if (getWebElement().Displayed) break;
}
catch (Exception)
{ }
Thread.Sleep(1000);
}
}
该函数的第一个参数是任何返回IWebElement对象的函数。第二个参数是超时(以秒为单位)(该超时代码是从Selenium IDE for FireFox复制的)。该代码可用于通过以下方式避免过时的元素异常:
MyTestDriver.WaitForDisplayed(driver.SpecificElementToGet,5);
上面的代码将driver.SpecificElementToGet().Displayed
一直调用直到不driver.SpecificElementToGet()
引发任何异常并且.Displayed
计算结果为true
5秒为止。5秒后,测试将失败。
另一方面,要等待某个元素不存在,可以以相同方式使用以下函数:
public static void WaitForNotPresent(Func<IWebElement> getWebElement, int timeOut) {
for (int second = 0;; second++) {
if (second >= timeOut) Assert.Fail("timeout");
try
{
if (!getWebElement().Displayed) break;
}
catch (ElementNotVisibleException) { break; }
catch (NoSuchElementException) { break; }
catch (StaleElementReferenceException) { break; }
catch (Exception)
{ }
Thread.Sleep(1000);
}
}