JavaとSelenium WebDriverを使用して、いくつかのテストケースを自動化しようとしています。次のシナリオがあります。
ポップアップを閉じた後、同じページの[アイテムの追加]ボタンをクリックする必要があります。しかし、WebDriverが[アイテムの追加]ボタンを見つけようとしてインターネット速度が速すぎる場合、WebDriverは要素を見つけてクリックできます。
しかし、インターネットが遅い場合、WebDriverはページの更新前にボタンを見つけますが、WebDriverがボタンをクリックするとすぐにページが更新され、StaleElementReferenceException
が発生します。
StaleElementReferenceException
が発生する前であっても、すべての待機条件が真になります(リロードの前後でページの内容が同じであるため)。[アイテムの追加]ボタンをクリックする前にThread.sleep(3000);
を使用すると、テストケースは正常に機能します。この問題の他の回避策はありますか?
3つの答え。これらは組み合わせることができます。
1.)Webドライバーインスタンスを作成した直後に暗黙の待機を設定します:driver.manage().timeouts().implicitlyWait()
。これは、ページナビゲーションまたはページのリロードごとにページが完全にロードされるまで待機しようとします。
2.)ページナビゲーションの後、return document.readyState
が返されるまでJavaScript "complete"
を呼び出します。 Webドライバーインスタンスは、JavaScriptエグゼキューターとして機能します。サンプルコード:
C#
new WebDriverWait(driver, MyDefaultTimeout).Until(
d => ((IJavaScriptExecutor) d).ExecuteScript("return document.readyState").Equals("complete"));
Java
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
3.)2.)の後、URLが期待するパターンと一致するかどうかを確認します。
「追加」ボタンをクリックする前に、ページがリロードされるのを待つ必要があるようです。この場合、「アイテムの追加」要素が古くなるのを待ってから、リロードされた要素をクリックします。
WebDriverWait wait = new WebDriverWait(driver, 20);
By addItem = By.xpath("//input[.='Add Item']");
// get the "Add Item" element
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(addItem));
//trigger the reaload of the page
driver.findElement(By.id("...")).click();
// wait the element "Add Item" to become stale
wait.until(ExpectedConditions.stalenessOf(element));
// click on "Add Item" once the page is reloaded
wait.until(ExpectedConditions.presenceOfElementLocated(addItem)).click();
アイテムの追加をクリックする前に、さまざまな方法でこれを行うことができます。
WebDriverWait wait = new WebDriverWait(driver, 40);
wait.until(ExpectedConditions.elementToBeClickable(By.id("urelementid")));// instead of id u can use cssSelector or xpath of ur element.
or
wait.until(ExpectedConditions.visibilityOfElementLocated("urelement"));
このように待つこともできます。前のページ要素が表示されなくなるまで待機する場合:
wait.until(ExpectedConditions.invisibilityOfElementLocated("urelement"));
ここに、待機に使用できるすべてのSelenium Webdriver APIとそのドキュメントを見つけるためのリンクがあります。