Last Updated: February 25, 2016
·
6.133K
· darrell

Avoiding StaleElementException in WebDriver

An important thing to remember is if you get a WebElement in Selenium WebDriver and the DOM changes (usually due to javascript), that WebElement will go stale. Any attempt to access it will cause a StaleElementException.

The most common reason for this to happen is getting a list of WebElements and iterating over them. The bigger the list the greater the change the DOM will change before you process all of them.

For example, if I have a table with id='mytable' and I want to iteration over all cells in the first column I might think this works:

List<WebElement> cells = driver.findElements(By.cssSelector("table#mytable>tbody>tr>td[1]"));
for(WebElement cell : cells) {
    System.out.println(cell.getText());
}

If there are 100 rows, this will get a list of 100 WebElement. If the DOM changes before you get to element 100 you get a StaleElementException. To fix this, get one element at a time, use it then get the next. That is:

int size = driver.findElements(By.cssSelector("table#mytable>tbody>tr>td[1]")).size();
for(int i = 1; i <= size; i++) {
    String locator = String.format("table#mytable>tbody>tr[%d]>td[1]", i);
    WebElement cell = driver.findElement(By.cssSelector(locator));
    System.out.println(cell.getText());
}

So rather than iterating over the list of WebElement (which can go stale), I iterating over the list of locator String (String doesn't go stale) and get one WebElement at a time.