Selenium 2.20 WebDriverを使用して、C#でfirefoxブラウザーを作成および管理しています。ページにアクセスするには、次のコードを使用して、URLにアクセスする前にドライバーのタイムアウトを設定します。
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
driver.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 0, 0, 5)); // Set script timeouts to 5 secs
driver.Navigate().GoToUrl(myUrl); // Goto page url
問題は、ページのロードに時間がかかることがあり、Selenium WebDriverを使用してロードするページのデフォルトのタイムアウトは30秒であり、長すぎるようです。そして、設定しているタイムアウトがGoToUrl()メソッドを使用したページの読み込みに適用されるとは思わない。
したがって、ロードするページのタイムアウトを設定する方法を見つけようとしていますが、実際に機能するプロパティやメソッドは見つかりません。デフォルトの30秒のタイムアウトも、要素をクリックしたときに適用されるようです。
ページの読み込みタイムアウトを特定の値に設定する方法はありますか?GoToUrl()メソッドを呼び出すと、指定した時間だけ待機してから続行しますか?
_driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);
_
注:driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5))
は非推奨になりました。
これがまだこれに対する答えを探している人を助ける場合、C#WebDriver APIには適切なメソッドが含まれています。
driver.Manage().Timeouts().SetPageLoadTimeout(timespan)
これにより、明示的に待機を宣言できるはずです。
WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(time in seconds));
wait.until(Your condition)
暗黙の待機時間も変更できます
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
これがC#の構文だと思います。 (確かではない)
In Rubyそれは
@driver.manage.timeouts.implicit_wait = 30
@wait = Selenium::WebDriver::Wait.new(:timeout => 30)
この問題の解決策を見つけました。新しいFirefoxDriverを作成するとき、各コマンドを待機する最大時間であるコマンドタイムアウトを指定できるようにするコンストラクターのオーバーロードがあり、GoToUrl()メソッドを呼び出すときに機能しているようです。
driver = new FirefoxDriver(new FirefoxBinary(), profile, new TimeSpan(0, 0, 0, timeoutSeconds));
参照用のFirefoxDriverコンストラクタードキュメントへのリンク: http://Selenium.googlecode.com/svn/trunk/docs/api/dotnet/html/M_OpenQA_Selenium_Firefox_FirefoxDriver__ctor_2.htm
これがこの問題に出くわした他の誰かを助けることを願っています。
2018年現在:これらに加えて:
driver.Manage().Timeouts().ImplicitWait.Add(System.TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().PageLoad.Add(System.TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().AsynchronousJavaScript.Add(timespan));
それぞれアイテムの検索、ページの読み込み、スクリプトの待機を待ちます。がある:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
私たちブラジル人は、「ガンビアラ」というくだらない回避策の言葉を持っています...まあ...少なくとも彼らは仕事をしています...ここに私のものがあります:
_var url = "www.your.url.here"
try {
DRIVER.Navigate().GoToUrl(url);
} catch {
// Here you can freely use the Selenium's By class:
WaitElement(By.Id("element_id_or_class_or_whatever_to_be_waited"), 60);
}
// rest of your application
_
私のWaitElement(By, int)
の機能:
_/// <summary>
/// Waits until an element of the type <paramref name="element"/> to show in the screen.
/// </summary>
/// <param name="element">Element to be waited for.</param>
/// <param name="timeout">How long (in seconds) it should be waited for.</param>
/// <returns>
/// False: Never found the element.
/// True: Element found.
/// </returns>
private bool WaitElement(By element, int timeout)
{
try {
Console.WriteLine($" - Waiting for the element {element.ToString()}");
int timesToWait = timeout * 4; // Times to wait for 1/4 of a second.
int waitedTimes = 0; // Times waited.
// This setup timesout at 7 seconds. you can change the code to pass the
do {
waitedTimes++;
if (waitedTimes >= timesToWait) {
Console.WriteLine($" -- Element not found within (" +
$"{(timesToWait * 0.25)} seconds). Canceling section...");
return false;
}
Thread.Sleep(250);
} while (!ExistsElement(element));
Console.WriteLine($" -- Element found. Continuing...");
// Thread.Sleep(1000); // may apply here
return true;
} catch { throw; }
}
_
この後、timeout
...で遊ぶことができます。
By
をページの最後にロードすることに気づいたもの(javascript要素やcaptchasなど)を覚えておいてください。ページが完全にロードされる前に_// rest of your application
_の動作を開始するため、Thread.Sleep(1000)
念のため最後に...
また、このメソッドは、SeleniumのDRIVER.Navigate().GoToUrl(url);
から60秒の標準タイムアウト後に呼び出されることに注意してください。
最高ではありませんが...
ページ読み込みタイムアウトは、.NETバインディングにはまだ実装されていません。うまくいけば、彼らはすぐになります。
逆の効果が必要な場合:60秒より長いタイムアウトを設定します。
両方の使用が必要です:
_new FirefoxDriver(FirefoxDriverService.CreateDefaultService(), new FirefoxOptions(), TimeSpan.FromSeconds(120))
_
そして
_driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(120);
_
new FirefoxDriver(binary, profile, timeSpan)
は廃止されました。
driver.Manage().Timeouts().SetPageLoadTimeout(timespan)
動作しません。
これは動作します。プロパティセッター構文を使用します。
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(15);