Selenium has revolutionized web automation by empowering testers to streamline their workflows and improve test coverage. However, like any powerful tool, Selenium can sometimes throw curveballs in the form of unexpected exceptions.
This blog will explore a common Selenium error: org.openqa.selenium.StaleElementReferenceException
, which means the locator to the element is no longer on the page.
Whether you’re a seasoned automation engineer or just starting your Selenium journey, you’ll gain valuable insights to troubleshoot effectively and write more robust test scripts in this blog.
What is ‘org.openqa.selenium.StaleElementReferenceException’?
The StaleElementReferenceException tells you that you are trying to interact with a web element that is no longer valid or present in the DOM (Document Object Model). A “stale element” means that the reference to the element you previously found on the page is no longer valid.
Think of it like having an old phone number for a friend. If they change their number, your saved contact becomes useless. You’ll need to get their new number to call them.
Reasons for StaleElementReferenceException
Let’s take a look at the main reasons why this exception occurs:
DOM Changes Dynamically
Modern websites often update parts of the page dynamically using JavaScript without requiring a full page reload. If the element you’re working with gets replaced or refreshed during such an update, the reference to that element becomes invalid.
Page Navigation or Reload
When the page navigates or reloads, the entire DOM is rebuilt, and any previously located elements become invalid.
Time Delay Between Locating and Using the Element
If there’s a significant delay between finding an element and interacting with it, the DOM may change during that time which then makes the element stale.
JavaScript or AJAX Actions
AJAX calls can update parts of the page asynchronously without a full reload. If you interact with an element before the update is complete or after it has been replaced, the exception will occur.
Element Is Removed from the DOM
If the element you’re interacting with is explicitly removed from the DOM (e.g., by a script), the reference becomes invalid.
How to Handle Stale Element Exception in Selenium
Re-locate the Element Before Interaction
driver.findElement(By.id("refresh")).click(); // Refresh the table WebElement newRow = driver.findElement(By.id("row3")); // Re-locate new row newRow.click();
Use Explicit Waits to Wait for DOM Stability
The DOM may take some time to update. Explicit waits ensure that Selenium interacts with the element only after it’s ready.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement content = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("content"))); content.click();
Handle the Exception with a Retry Mechanism
If you suspect the DOM is changing and causing stale references, retry the action to give the test a chance to re-locate the element after a short delay.
for (int i = 0; i < 3; i++) { try { WebElement button = driver.findElement(By.id("submit")); // Locate button button.click(); // Try clicking break; // Exit loop if successful } catch (StaleElementReferenceException e) { Thread.sleep(1000); // Wait before retrying } }
Avoid Storing Element References for Too Long
Storing an element in a variable and using it later increases the risk of the DOM changing. Instead, locate the element immediately before interacting with it. Though this may be against standard procedures for some, it can help avoid this problem.
Synchronize Your Test with JavaScript or AJAX Actions
If your app uses JavaScript or AJAX to update the DOM asynchronously, waiting for those updates ensures the element remains valid.
driver.findElement(By.id("search")).sendKeys("query"); // Type in search WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement updatedSuggestion = wait.until(ExpectedConditions.elementToBeClickable(By.id("s2"))); updatedSuggestion.click();
Switch Back to the Correct Frame or Window
If you switch away from a frame or window containing your element, its reference becomes invalid. Switching back and re-locating the element ensures it’s valid.
driver.switchTo().frame("frame1"); // Switch to frame 1 WebElement button = driver.findElement(By.id("button1")); // Re-locate button button.click();
Ensure Stable Locators for Elements
Dynamic locators (like IDs that change) make it hard to reliably interact with elements. Using stable locators ensures Selenium can always find the right element.
Handle Elements Removed from the DOM
If an element is removed from the DOM (e.g., a disappearing popup), ensure it’s still present before interacting with it.
Conclusion
While exceptions can be frustrating, they often help us learn more about the way we write test scripts. By understanding what the exception is trying to tell us and taking corrective measures, we can create reliable test scripts that run without giving flakey results.