Selenium -- How to wait until page is completely loaded

86

I am trying to automate some test cases using Java and Selenium WebDriver. I have the following scenario:

  • There is a page named 'Products'. When I click on 'View Details' link in the 'Product' page, a popup (modal-dialog) containing the details of the item appears.
  • When I click on the 'Close' button in the popup the popup closes and the page automatically refreshes (the page is just reloading, the contents remain unchanged).
  • After closing the popup I need to click on 'Add Item' button in the same page. But when WebDriver trying to find the 'Add Item' button, if the internet speed is too fast, WebDriver can find and click the element.

  • But if the internet is slow, WebDriver finds the button before the page refresh, but as soon as the WebDriver click on the button, the page refreshes and StaleElementReferenceException occurs.

  • Even if different waits are used, all the wait conditions become true (since the contents in the page are same before and after reload) even before the page is reloaded and StaleElementReferenceException occurs.

The test case works fine if Thread.sleep(3000); is used before clicking on the 'Add Item' button. Is there any other workaround for this problem?

This question is tagged with java selenium-webdriver

~ Asked on 2016-04-13 06:27:07

The Best Answer is


102

3 answers, which you can combine:

  1. Set implicit wait immediately after creating the web driver instance:

    _ = driver.Manage().Timeouts().ImplicitWait;

    This will try to wait until the page is fully loaded on every page navigation or page reload.

  2. After page navigation, call JavaScript return document.readyState until "complete" is returned. The web driver instance can serve as JavaScript executor. Sample code:

    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. Check if the URL matches the pattern you expect.

~ Answered on 2016-04-13 06:34:41


16

It seems that you need to wait for the page to be reloaded before clicking on the "Add" button. In this case you could wait for the "Add Item" element to become stale before clicking on the reloaded element:

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();

~ Answered on 2016-04-13 11:00:01


Most Viewed Questions: