@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オブジェクトを返す関数です。2番目のパラメーターは秒単位のタイムアウトです(タイムアウトのコードはFireFoxのSelenium IDEからコピーされました)。このコードを使用すると、次の方法で古い要素の例外を回避できます。
MyTestDriver.WaitForDisplayed(driver.SpecificElementToGet,5);
上記のコードは、例外がスローされずに評価され、5秒が経過するdriver.SpecificElementToGet().Displayed
まで呼び出されます。5秒後、テストは失敗します。driver.SpecificElementToGet()
.Displayed
true
反対に、要素が存在しなくなるのを待つには、次の関数を同じ方法で使用できます。
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);
}
}