Table of Contents
Enroll in Selenium Training

While working with selenium webdriver you will (or might have) come across different exceptions. These exceptions halt the execution of your tests and indicate what went wrong depending on the type of exception. They sometimes are used for very important features that may not be developed otherwise. For instance, incorporating a feature where the user can exit the program using Ctrl+ C is just a three-line code using the KeyboardInterrupt exception. The StaleElementReferenceException is one such common exception. In general stale refers to something that is not fresh. In selenium, the StaleElementReferenceException implies the absence of an element that might have been present earlier. This is something we will talk about in this post referring to the below points-

  • What is StaleElementReferenceException in Selenium WebDriver?
  • When can we expect StaleElementReferenceException?
  • How to avoid StaleElementReferenceException?
  • Practical example demonstration.

What is StaleElementReferenceException in Selenium WebDriver?

StaleElementReferenceException in Selenium is quite common with test execution for an environment with frequent changes. The exception implies that an element that was earlier present does not exist anymore on the page. It means that the element has been removed from the DOM of the page. The StaleElementReferenceException pops up when an element that was found using the findElement method cannot be interacted with. The below snapshot shows how StaleElementReferenceException pop-up in the console logs-

In the next section, we will understand more about the cause and occurrence of this exception.

When can we expect StaleElementReferenceException?

There are two common causes leading to Selenium StaleElementReferenceException which have been highlighted in Selenium documentation as well-

  • The referenced element is not attached to the DOM anymore.
  • The referenced element has been deleted permanently.

Let's detail them one by one.

Exception due to referenced element not attached to the DOM anymore

Let's first understand how selenium works. When we try to find an element using the findElement() method in WebDriver, Selenium keeps the refrenceId of that element in memory if the element is found. Later when you try to interact with the element, instead of finding it again, it gets the saved referenceId and tries to locate the element with that referenceId.

Although, there can be situations where you perform some action on the page, due to which the reference of a few elements gets updated or refreshed. In such cases, you would get StaleElementReferenceException.

New to Selenium? Read our comprehensive tutorial series and excel in the framework with practical examples and ready-to-run code.

Permanent deletion of the referenced element

A scenario where the referenced element might have been permanently deleted may occur sometimes. For instance, if the page where the element resides has been refreshed before the interaction with the element took place, or the user has navigated to some other page. Another cause of deletion might be the replacement of the element from the Javascript library with an element having similar attributes. Although the replaced item would appear to be similar, the webdriver would not be able to identify it due to attribute similarities. Assume that you identified an element on the web page, now when you scrolled down to see the contents of the page(or any table listing on the page), the page got refreshed automatically to load the contents. In such a scenario if you try to perform an action on the element you previously identified you might stumble upon the StaleElementReferenceException.

Of the above two reasons, the second reason is one of the most common causes of StaleElementReferenceException.

How to avoid StaleElementReferenceException?

Now that we know the causes of StaleElementReferenceException, we will see the possible solutions to overcome the same.

Solution 1- Refresh the web page

You can try the refresh method on the webpage if you face the StaleElementReferenceException. Once refreshed, try searching the same element again. To do so, you may use the below code-

driver.navigate().refresh(); 
driver.findElement(By.cssSelector("web element locator")).click();

Solution 2- Use the explicit wait

We can use the Selenium webdriver explicit wait method to overcome the problem of finding an element. Now there can be two ways to use explicit wait-

  • Wait until the element is present.
  • Wait until the element is refreshed.

Wait until the element is present

Using the explicit wait, we can wait for the element to be available and then perform the intended actions. You can use the below line of code to apply wait on a web element-

wait.until(ExpectedConditions.presenceOfElementLocated("web element locator"));

The above code tells the webdriver to wait until a condition is met corresponding to an element, like the element to be present or for it to be interactive. Let us see what the complete code would look like when we try to apply explicit wait to wait for the element to be clickable.

	//Applying explicit wait to the desired web element which would ignore stale element reference exception 
		//and wait until the web element is ready to be clickable 
		new WebDriverWait(driver, Duration.ofSeconds(10))
		.ignoring(StaleElementReferenceException.class)
		.until(ExpectedConditions.elementToBeClickable(By.xpath("element locator")));
		driver.findElement(By.xpath("element locator")).click();

As you may see from the above code, we are creating an instance of WebDriverWait, waiting for the element to be clickable for up to 10 seconds, and calling the click() method. Also note that we are asking the webdriver to ignore the StaleElementReferenceException till the web driver wait has been applied.

You can learn more about Explicit Wait in our article on Selenium Wait Commands.

Wait until the element is refreshed

We can use the ExpectedConditions.refreshed method to avoid StaleElementReferenceException. Doing so, the webdriver will wait for the element to be refreshed and ready to take its reference. The below line of code shows how we can use refresh web element-

wait.until(ExpectedConditions.refreshed(ExpectedConditions.presenceOfElementLocated("web element locator")));

Let us quickly have a look at the code of how the refreshed method can be used with the wait condition.

new WebDriverWait(driver, Duration.ofSeconds(10))
	.until(ExpectedConditions.refreshed(ExpectedConditions.presenceOfElementLocated(By.xpath("element locator"))));
	driver.findElement(By.xpath("element locator")).click();

Similar to the normal explicit wait approach, we have applied a webdriver wait for 10 seconds wherein we ask the webdriver to wait for the element to be visible until the DOM manipulation has happened. Ideally, the refresh method is best suited when we know that DOM manipulation might happen on the web page, and the webdriver would wait for the element to be refreshed within the time specified.

Solution 3- Use the try-catch statement

The tester may also use the try-catch block to find the element throwing StaleElementReferenceException.

I wont agree to this, if it is stale no matter how many times u try it will remain stale. U dont need the for loop, in catch refresh the page and try finding element again.

Please dont bring the approach from other websites if you yourself do not understand- DONE

try {
			driver.findElement(By.cssSelector("webelement locator")).click(); 
		} catch(StaleElementReferenceException e) { 
			driver.navigate().refresh(); 
			driver.findElement(By.cssSelector"webelement locator")).click(); 
		}

Using the retry method, the tester can try finding the web element again in the catch block after refreshing the webpage and performing the desired action.

Solution 4- Using POM

In POM design pattern or while using the principles of Page Factory, we locate an element using the @FindBy annotation. It helps in updating the reference of the web element each time before any action is performed on it. This becomes very useful in eliminating the occurrence of StaleElementReferenceException.

After having known the three different solutions to resolve StaleElementReferenceException, you can identify the best approach that would suit your requirement and remove the blockage from your code execution. For this article and your understanding, we will now replicate the StaleElementReferenceException and resolve the same using one of the approaches mentioned above.

Practical example demonstration

We will use the below use case to replicate the StaleElementReferenceException-

  1. Navigate to www.google.com.
  2. Locate the search text box on the web page.
  3. Refresh the web page.
  4. Send a string to search in the web element located in step #2.

The code for the above steps would look like this -

package demo2;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class RefreshWeb2 {

	public static void main(String[] args) {

				  System.setProperty("webdriver.chrome.driver",
				  "---Path to chrome driver on your system---"); 
				  WebDriver driver = new ChromeDriver(); 
				  driver.manage().window().maximize();
				 
				  driver.get("https://google.com");
				  //Locate the search text box
				  WebElement ele = driver.findElement(By.xpath("//input[@class=\"gLFyf gsfi\"]"));
				  //Refresh the web page
				  driver.navigate().refresh();
				  //Pass string using sendkeys to the web element
				  ele.sendKeys("Testing String");
				  driver.quit();
				  
				 
	}

}

The output of executing the above code will be as shown in the screenshot below- Console Output for stale element reference exception.jpg

We will now use the retry method discussed above to avoid StaleElementReferenceException.

package demo2;

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;

public class RefreshWeb2 {

	public static void main(String[] args) {

				  System.setProperty("webdriver.chrome.driver",
				  "---Chrome driver location on the machine---"); 
				  WebDriver driver = new ChromeDriver(); 
				  driver.manage().window().maximize();
				 
				  driver.get("https://google.com");
				  //Locate the search text box
				  WebElement ele = driver.findElement(By.xpath("//input[@class=\"gLFyf gsfi\"]"));
				  //Refresh the web page
				  driver.navigate().refresh();
				  
				  try {
				  //Pass string using sendkeys to the web element
				  ele.sendKeys("Testing String");
				  }
				  catch(StaleElementReferenceException e) {
					  WebElement elem = driver.findElement(By.xpath("//input[@class=\"gLFyf gsfi\"]"));
					  elem.sendKeys("Testing String from catch block");
					  //Fetching the string entered in the search text box
					  String str = elem.getAttribute("value");
					  System.out.println("The string entered from catch block is - " +str);
				  }
				  
				  driver.quit();
				  
				 
	}

}

Upon executing the above code, when the webdriver would not be able to locate the web element 'ele' in the try block, it will jump to the catch block and again try to locate the web element. Upon finding it, it would send the desired text string into the text box without throwing any exceptions. The console output would look like the below- Console output upon resolving stale element reference exception.jpg

Key Takeaways

  • StaleElementReferenceException in selenium is quite common. It occurs due to the absence of an element from the DOM.
  • The exception may occur either due to the permanent removal of the element reference from the DOM or the element reference being updated. Additionally, it might happen because the page is refreshed before any action is performed on the element.
  • StaleElementReferenceException can be avoided by using some workarounds like refreshing the webpage before accessing the web element, using the try-catch block, using explicit wait(wait for the expected condition or wait for the refresh of DOM), or using POM.
  • POM makes use of the initElements() which would load the element but before initializing it would fetch the latest address of the web element.
Junit Test with Selenium WebDriver
Junit Test with Selenium WebDriver
Previous Article
Log4j Introduction
Log4j Introduction
Next Article

Similar Articles

Feedback