Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium WebDriver How to Resolve Stale Element Reference Exception?

I have the following code in a Selenium 2 Web Driver test which works when I am debugging but most of the time fails when I run it in the build. I know it must be something to do with the way the page is not being refreshed but do not know how to resolve it so any pointers as to what I have done wrong are appreciated. I am using JSF primefaces as my web application framework. When I click on the add new link a popup dialog box appears with a input box that I can enter a date into then click save. It is on getting the input element to enter text into that I get a stale element ref exception.

Thanks in advance

import static org.junit.Assert.assertEquals;   import java.util.HashMap; import java.util.List; import java.util.Map;  import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait;   public class EnterActiveSubmissionIntegrationTest { Map<String, Map<String, String>> tableData = new HashMap<String, Map<String, String>>();  @Test public void testEnterActiveSubmission() throws Exception {     // Create a new instance of the Firefox driver     // Notice that the remainder of the code relies on the interface,      // not the implementation.     System.setProperty("webdriver.chrome.driver", "C:/apps/chromedriver.exe");     WebDriver driver = new ChromeDriver();      // And now use this to visit Google     driver.get("http://localhost:8080/strfingerprinting");     // Alternatively the same thing can be done like this     // driver.navigate().to("http://www.google.com");      // Find the text input element by its name     WebElement element = driver.findElement(By.linkText("Manage Submissions"));     element.click();     parseTableData(driver, "form:submissionDataTable_data", 1);     assertEquals(tableData.get("form:submissionDataTable_data").get("12"), "Archived");      WebElement newElement = driver.findElement(By.linkText("Add new"));     newElement.click();      WebDriverWait wait = new WebDriverWait(driver,10);     wait.until(new ExpectedCondition<Boolean>() {         public Boolean apply(WebDriver driver) {             WebElement button = driver.findElement(By                     .name("createForm:dateInput_input"));              if (button.isDisplayed())                 return true;             else                 return false;          }     });      WebElement textElement = driver.findElement(By.name("createForm:dateInput_input"));     textElement.sendKeys("24/04/2013");     WebElement saveElement = driver.findElement(By.name("createForm:saveButton"));     saveElement.click();      driver.navigate().refresh();      parseTableData(driver, "form:submissionDataTable_data", 2);      //Close the browser     driver.quit(); }    private void parseTableData(WebDriver driver, String id, int expectedRows) {     // Check the title of the page or expected element on page     WebElement subTableElement = driver.findElement(By.id(id));     List<WebElement> tr_collection=subTableElement.findElements(By.xpath("id('"+ id + "')/tr"));      assertEquals("incorrect number of rows returned", expectedRows, tr_collection.size());     int row_num,col_num;     row_num=1;      if(tableData.get(id) == null) {         tableData.put(id, new HashMap<String, String>());     }     Map<String, String> subTable = tableData.get(id);     for(WebElement trElement : tr_collection)     {         List<WebElement> td_collection=trElement.findElements(By.xpath("td"));         col_num=1;         for(WebElement tdElement : td_collection)         {             subTable.put(row_num + "" + col_num, tdElement.getText());             col_num++;         }         row_num++;     } } } 

When I run this I get the following exception but it can occur on

WebElement textElement = driver.findElement(By.name("createForm:dateInput_input"));  

or

if (button.isDisplayed()) 

exception trace

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document (Session info: chrome=26.0.1410.64)   (Driver info: chromedriver=0.8,platform=Windows NT 6.0 SP2 x86) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 56 milliseconds For documentation on this error, please visit:        http://seleniumhq.org/exceptions/stale_element_reference.html Build info: version: '2.32.0', revision: '6c40c187d01409a5dc3b7f8251859150c8af0bcb', time: '2013-04-09 10:39:28' System info: os.name: 'Windows Vista', os.arch: 'x86', os.version: '6.0', java.version: '1.6.0_10' Session ID: 784c53b99ad83c44d089fd04e9a42904 Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities [{platform=XP, acceptSslCerts=true, javascriptEnabled=true,   browserName=chrome, rotatable=false, driverVersion=0.8, locationContextEnabled=true,  version=26.0.1410.64, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true,  browserConnectionEnabled=false, nativeEvents=true, webStorageEnabled=true,   applicationCacheEnabled=false, takesScreenshot=true}] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at  sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at  sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187) at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:554) at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:268) at org.openqa.selenium.remote.RemoteWebElement.isDisplayed(RemoteWebElement.java:320) at com.integration.web.EnterActiveSubmissionIntegrationTest$1.apply(EnterActiveSubmissionIntegrationTest.java:58) at com.integration.web.EnterActiveSubmissionIntegrationTest$1.apply(EnterActiveSubmissionIntegrationTest.java:1) at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:208) at com.integration.web.EnterActiveSubmissionIntegrationTest.testEnterActiveSubmission(EnterActiveSubmissionIntegrationTest.java:53) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
like image 876
user1107753 Avatar asked Apr 23 '13 09:04

user1107753


People also ask

How did you overcome stale element exception?

Solution 1: (Handle it using POM "@FindBy") If we use Page Object Model (or) Page Object design pattern you will never get Stale Element Reference Exception.

What is stale element reference exception in selenium?

A stale element reference exception is thrown in one of two cases, the first being more common than the second: The element has been deleted entirely. The element is no longer attached to the DOM.

What is stale element exception?

There may be a case, when an element was in DOM initially but after modifications in Document Object Model (DOM), the element becomes stale and the StaleElementReferenceException is thrown if we make an attempt to access this element. This exception is caused whenever an element is not present in the DOM, or deleted.

What is StaleElementReference exception Have you encountered it how you handle it?

It uses same stored reference every time. The stored reference may not be valid when page is refreshed or its attribute changes dynamically. In this case reference becomes old or stale and when WebDriver tries to perform an action using same reference, it throws StaleElementReferenceException.


1 Answers

First of all lets be clear about what a WebElement is.

A WebElement is a reference to an element in the DOM.

A StaleElementException is thrown when the element you were interacting is destroyed and then recreated. Most complex web pages these days will move things about on the fly as the user interacts with it and this requires elements in the DOM to be destroyed and recreated.

When this happens the reference to the element in the DOM that you previously had becomes stale and you are no longer able to use this reference to interact with the element in the DOM. When this happens you will need to refresh your reference, or in real world terms find the element again.

like image 189
Ardesco Avatar answered Sep 20 '22 17:09

Ardesco