条件クラス(ExpectedConditions)
Seleniumで「特定の条件が満たされるまで待機する」をよく使います。
locatorが見えるまで待機するコードはこんな感じ。簡単。
Test.cs
public void WaitUntilElementIsVisible(By locator)
{
wait.Until(ExpectedConditions.ElementIsVisible(locator));
}
locatorが見えなくなる条件クラス
C#版だと条件クラス(ExpectedConditions)が貧相なので、新たにメソッドを作りました。
※Javaにはnot(ExpectedCondition)メソッドがいるので不要です。(Java: ExpectedConditions)
ExpectedConditionsEx.cs
public static Func<IWebDriver, IWebElement> ElementIsInvisible(By locator)
{
return (driver) =>
{
try
{
// 探す
ReadOnlyCollection<IWebElement> elements = driver.FindElements(locator);
// 見えてる要素に絞り込む
List<IWebElement> result = elements.Where(e => e.Displayed).ToList();
// なくなる or 全部見えなくなるはず
if (result.Count == 0)
// ダミーとしてページのルート要素を返す
return driver.FindElement(By.CssSelector(":root"));
else
return null;
}
catch (StaleElementReferenceException)
{
return null;
}
};
}
ExpectedConditions.ElementIsInvisibleはデフォルトでいてもよいと思う。
C#: ExpectedConditions
条件をひっくり返すメソッド Not(ExpectedCondition)
条件を否定してTrue/Falseを入れ替えるメソッド
JavaのNot(ExpectedCondition)をC#でも作れば良いのでは。
ExpectedConditionsEx.cs
public static Func<IWebDriver, IWebElement> Not(Func<IWebDriver, IWebElement> condition)
{
return (driver) =>
{
IWebElement e = condition.Invoke(driver);
return e == null ? driver.FindElement(By.CssSelector(":root")) : null;
};
}
public static Func<IWebDriver, bool> Not(Func<IWebDriver, bool> condition)
{
return (driver) => !condition.Invoke(driver);
}
ページがロードされるまで待つ
指定されたタイトルが現れるまで待ち、処理を開始します。便利。
ExpectedConditionsEx.cs
public static Func<IWebDriver, bool> TitleIs(string title)
{
return (driver) =>
{
try
{
return driver.Title == title;
}
catch (Exception)
{
return false;
}
};
}
public static Func<IWebDriver, bool> TitleStartsWith(string title)
{
return (driver) =>
{
try
{
return driver.Title.StartsWith(title);
}
catch (Exception)
{
return false;
}
};
}
アラートが表示されるまで待つ
※ブラクラ複数アラート状態で使うと、おそらく想定通りに動きません。
ExpectedConditionsEx.cs
public static Func<IWebDriver, bool> AlertIsVisible()
{
return (driver) =>
{
try
{
driver.SwitchTo().Alert();
return true;
}
catch (NoAlertPresentException)
{
return false;
}
};
}
雑感
ダミーのIWebElementを返すには何が良いのだろう。