How To Handle Stale Element Reference Exceptions In Selenium Java
Posted On: October 3, 2022
19 Min Read
While using Selenium with Java, we experience several exceptions while developing our automation code. An exception is an event that interrupts a program’s execution flow. It occurs at run time (during the execution of a program). In alphabetical order, here is a list of the common Selenium exceptions.
- ElementClickInterceptedException – Target element is obscured and cannot be clicked.
- ElementNotInteractableException – WebElement is present but not in an interactable state.
- NoAlertPresentException – An attempt is made to access an alert that is not present. It is thrown by switchTo().alert().
- NoSuchElementException – An attempt is made to access an element that is not available. It is thrown by findElement(By by).
- NoSuchFrameException – An attempt is made to access a frame that is not available. It is thrown by switchTo().frame().
- NoSuchWindowException – An attempt is made to access an unavailable window. It is thrown by switchTo().window().
- StaleElementReferenceException – The reference element is stale (no longer new).
- TimeoutException – A command is not completed in the allocated time.
In this blog on handling the Stale Element Reference Exception, I will explain how to handle a StaleElementReferenceException in Selenium using Java.
TABLE OF CONTENTS
- What is a Stale Element Reference Exception?
- Example of Stale Element Reference Exception
- Re-initialize the WebElement to Handle Stale Element Reference Exception
- Use Loops & Try-Catch Block to Handle Stale Element Reference Exception
- Use Expected Conditions to Handle Stale Element Reference Exception
- Frequently Asked Questions (FAQs)
What is a Stale Element Reference Exception?
The Stale Element Reference Exception is a runtime error arising when an object’s state changes while your code is in the midst of utilizing it. This shift can result from a page update or user-triggered events altering your document’s structure. The reference to the altered object remains valid but no longer corresponds to your intended target. Attempting to use it will result in a StaleElementReferenceException.
A StaleElementReferenceException is thrown by Selenium WebDriver in 1 of 2 circumstances.
- The element has been removed from the DOM.
- The element is not attached to the page document.
In addition, there is an edge case concerning a Stale Element Reference Exception. Edge cases involve extreme situations at the minimum or maximum range of a possible condition. Selenium WebDriver will return a StaleElementReferenceException if the element changes its type.
Example of Stale Element Reference Exception
You would encounter a Stale Element Reference Exception when the Selenium test code refers to an element that is no longer available (not attached or removed) in the DOM. It’s a reference that a specific element is stale and prevents the test script from performing an action.
As a result, the console returns org.openqa.selenium.StaleElementReferenceException: stale element reference: with 1 of 2 descriptions.
The following screenshot shows an “element is not attached to the page document” description.
The other description is “element has been removed from the DOM.”
Here are steps and screenshots from the Selenium Playground by LambdaTest to return a StaleElementReferenceException:
- Go to https://www.lambdatest.com/selenium-playground/.
- Click the Table Data Search link.
- Enter Status, “i.e., in progress” via Filter by Task / Assignee / Status field.
- Click the Back button.
- Click the Table Data Search link.
- Enter Status, “i.e., completed” via Filter by Task / Assignee / Status field.
The root of this StaleElementReferenceException is navigating to the previous page (Step 4). Clicking the back button causes the Filter by Task / Assignee / Status field to be detached from the DOM. Therefore, our test script cannot enter a Status (Step 6), although the field is visible after clicking the Table Data Search link (Step 5).
Let’s walk through the code step-by-step and see how to generate the Stale Element Reference Exception in Selenium Java.
- Test Method
Starting with the BaseTest, the Selenium code sets up and tears down every test. I have used the Selenium cloud grid from LambdaTest for demonstration.
LambdaTest is a cloud-based cross browser testing platform that offers an online Selenium Grid to perform Selenium automation testing at scale. You can exponentially increase your browser coverage by running your Selenium automation scripts on a test automation cloud of 3000+ desktop and mobile environments, ensuring a seamless user experience across all browsers and OSes.
For a different approach to handling exceptions, you might also explore exception handling in cypress, which can be useful in specific scenarios.
The following is a screenshot of the setUp() method.
On line 19, the DesiredCapabilities class is declared to set some requirements for executing the test. We consider a combination of browsers, browser versions, operating systems, etc., to automate web testing. The following is a list of established capabilityNames in the setUp() method.
- Line 23: “build” serves as the build number with a maximum of 255 characters.
- Line 24: “name” serves as the test name.
- Line 25: “platform” serves as the operating system. If a platform is not supplied, then LambdaTest will map a relevant operating system.
- Line 26: “browserName” serves as the name of the browser.
- Line 27: “version” serves as the version of the selected browser.
- Line 29: “tunnel” establishes an SSH connection.
- Line 30: “network” captures a recording for the network packets.
- Line 32: “visual” takes a screenshot of each test step.
- Lines 34-39: try/catch.
- Line 35: RemoteWebDriver implements the WebDriver interface and executes the browser on a remote machine.
- Line 35: username automatically generated when logged into LambdaTest under desired Selenium Capabilities class.
- Line 36: accessKey automatically generated when logged into LambdaTest under desired Selenium Capabilities class.
- Line 36: hub is a String with the following value “https://hub.lambdatest.com/wd/hub”
- Line 40: driver.get() loads the LambdaTest Selenium Playground web application
Note: You can generate your custom desired capabilities using the LambdaTest Desired Capabilities Generator.
The Test Method name is createStaleElementReferenceException(). In the method’s body, line 12 finds the Table Data Search link and assigns it to pageLink. Afterward, on line 13, the pageLink is clicked, which transitions the application to the Table Search filter page (See Figure 3).
On the Table Search filter page, line 14 finds the Filter by Task / Assignee / Status field, and line 16 enters the first status “in progress.” Notice in the screenshot below that all Tasks with an “in progress” status appear after searching for “in progress.”
On line 17, the test script clicks the back button and navigates to the previous page, “Selenium Playground-Home Page” (See Figure 2). The automation code successfully clicks the pageLink “Table Data Search” via line 18.
However, line 19 cannot enter the “completed” Status because it returns a StaleElementReferenceException. The below screenshot provides more information regarding the Stale Element Reference Exception by displaying line 19.
We can handle the Stale Element Reference Exception in multiple ways depending on why the exception was thrown. Let’s investigate how to resolve the StaleElementReferenceException by:
- Re-Initializing The WebElement
- Using Loops & Try Catch Blocks
- Using Expected Conditions
Run your Selenium scripts across 3000+ browser environments. Try LambdaTest Now!
Re-initialize the WebElement to Handle Stale Element Reference Exception
In the above example (see Figure 5), if we re-initialize the filterByField element before entering “completed” status, then the StaleElementReferenceException will not be thrown. There was not a reference to filterByField because it was not attached to the page document. The below screenshot displays how to re-initialize filterByField to avoid the exception.
Notice how line 19 finds the element before entering the “completed” Status on line 20. As a result, the StaleElementReferenceException is not thrown, but the test script successfully searches for a “completed” Status and returns the correct results. The below screenshot shows how the “completed” Status is searched and returned on the Table Search Filter page.
Use Loops & Try-Catch Block to Handle Stale Element Reference Exception
In some instances, the element is temporarily not reachable through the DOM. Hence, we can try to access the element multiple times in a loop until it becomes available. Within our desired loop, we implement a try-catch block and attempt to make a connection with the element.
- While Loop & Try-Catch Block
- For Loop & Try-Catch Block
While Loop & Try-Catch Block
In the utility package-Helper class, a method called retryUsingWhileLoop_TryCatch() is created to handle the StaleElementReferenceException. It receives a By locator and String value as the parameters. On line 15, the boolean outcome variable is initialized to false, and the int repeat variable is set to 0 on line 16.
The while loop starts on line 17 with a condition to repeat less than or equal to 3. Next is the try block, which tries to find the element and enter a Status via line 19. If the outcome is false, the code continues up to 3 times.
Normally, the second effort finds the element and acts on the element. If the element is found, the outcome is true on line 20. The following screenshot shows how a locator and value are passed to line 19.
The test calls the retryUsingWhileLoop_TryCatch() method and sends two arguments: filterByField and a value. Lines 17 and 20 send the same filterByField locator but different values (in progress and completed). Both calls were a success and did not return a StaleElementReferenceException.
- The “in progress” Status returned 3 Tasks (see Figure 6).
- The “completed” Status returned 1 Task (see Figure 9).
For Loop & Try-Catch Block
We handle the Stale Element Reference Exception using a for loop similar to a while loop. Each loop has a try-catch block and initializes the boolean variable, “i.e., outcome,” to false. The following is a screenshot displaying a try-catch block within a for loop.
Line 32 begins the for loop by initializing the repeat variable to 0, followed by the condition to cycle less than or equal to 3. Afterward, the repeat variable increments by 1 (repeat ++). Like the while loop, this for loop tries to find the element and enter a value.
If the element is found, the outcome is true, and line 36 terminates the loop immediately with the break statement. The purpose of the catch (lines 37 and 38) is to handle the StaleElementReferenceException if it is thrown.
Since the method retryUsingForLoop_TryCatch() is a boolean method, line 41 returns the outcome, which is declared boolean via line 31. The following screenshot shows how filterByField and status are passed to line 34.
Just like the while loop, the for loop calls a method from the utility package-Helper class. Lines 29 and 32 call the retryUsingForLoop_TryCatch() method but pass different values. Line 29 pass “in progress” Status, and line 32 pass “completed” Status.
- The “in progress” Status returned 3 Tasks (see Figure 6)
- The “completed” Status returned 1 Task (see Figure 9)
Use Expected Conditions to Handle Stale Element Reference Exception
Thankfully, Selenium also allows us to manage the Stale Element Reference Exception by implementing methods from the Expected Conditions class. The following is a screenshot displaying multiple methods by way of Expected Conditions.
Starting at line 55, the automation code creates an instance of WebDriverWait with the wait as the object reference variable. The parameters are driver and Duration.ofSeconds(5):
- driver controls the Chrome browser
- Duration.ofSeconds(5) will wait to find the element for up to 5 seconds.
WebDriverWait is a class that helps to develop an explicit dynamic wait statement. If the element is not found, then a TimeoutException shows up. The key to handling a Stale Element Reference Exception is lines 56 and 57.
On line 56, wait.until provides access to the ExpectedConditions class, which has many methods. The following screenshot shows some methods including refreshed() and presenceOfElementLocated().
The solution to handling our example StaleElementReferenceException utilizes multiple methods. It dynamically waits and checks if the element is refreshed for up to 5 seconds, then wait an additional five more seconds for the element to be present (See Figure 14).
In some cases, only one method, such as stalenessOf() from the Expected Conditions class, is sufficient for overseeing a StaleElementReferenceException. The following screenshot displays how the Test Method calls the chainMultipleExpectedCondtions() method.
Note: All of the code is located on GitHub.
The chainMultipleExpectedConditions() method is in the utility package-Helper class. With this solution, the test makes a call on lines 18 and 21. It is comparable to the other methods by sending two arguments: filterByField and Status.
- Line 18 sends filterByField and is in progress, with 3 Tasks showing up in the results (see Figure 6).
- Line 21 sends filterByField and completed with 1 Task showing up in the results (see Figure 9).
Watch this video to learn how to handle Stale Element Reference Exceptions in Selenium with Java.
A Stale Element Reference Exception is challenging to handle because the element is stale. According to dictionary.com, one of the definitions of stale is not fresh. Therefore, the StaleElementReferenceException is thrown because the element has been removed from the DOM or is no longer attached to the page document.
In this Selenium Java tutorial, the element was visible on the User Interface (UI), but there was no reference to the element. It was not a reference to the element because the test script navigated to the previous page before returning to the element. As a result, the console returned a StaleElementReferenceException with a message stating, “element is not attached to the page document” (See Figure 1).
Selenium supplies various approaches to deal with a Stale Element Reference Exception. The following practices for handling a StaleElementReferenceException were explained in this article.
- Re-Initialize The WebElement
- Use Loops & Try-Catch Block
- Use Expected Conditions
The following screenshots show results from creating our Example Stale Element Reference Exception and solutions for handling the StaleElementReferenceException.
- createStaleElementReferenceException (Fail).
- test1_ReInitializeWebElementToHandle_SERE (Pass).
- test2_WhileLoopToHandle_SERE (Pass).
- test3_ForLoopToHandle_SERE (Pass).
- test4_chainExpectedConditionsToHandle_SERE (Pass).
Frequently Asked Questions (FAQs)
How do I avoid StaleElementReferenceException?
When working with Java programming language and its associated APIs, you can avoid stale references to ensure that your code is properly synchronized so that multiple threads can’t modify the same object simultaneously. This will ensure that the correct thread has a chance to free up any unused memory before another thread tries to access it, thus preventing StaleElementReferenceException.
What is the difference between stale element exception and no such element exception?
The main difference between the two exceptions is that if you use the stale element exception, you know that the element is not found in the DOM, but it might appear again if you navigate to a different page. On the other hand, if you use no such element exception, you know that the element is not found in the DOM, and this element will never appear again.
What is a stale element reference exception?
A stale element reference exception is a common error in software automation, particularly in web testing. It occurs when an element on a webpage that was previously referenced becomes detached or no longer exists in the current DOM (Document Object Model), leading to an invalid reference. This exception typically requires refreshing the page or updating the element reference to continue interacting with the webpage accurately.
How can I handle a stale element reference exception in Selenium Java?
To handle a stale element reference exception in Selenium Java, you can use techniques such as wrapping the code that interacts with the element in a try-catch block, refreshing the page before accessing the element, or using explicit waits to ensure the element is available before interacting with it.
What causes a stale element reference exception?
A stale element reference exception occurs when a previously referenced element on a web page no longer exists or has changed. This can happen due to the page being refreshed, modified, or navigated away from. As a result, the reference to the element becomes invalid, causing the exception.
How do I refresh the page to handle a stale element reference exception?
To handle a stale element reference exception and refresh the page, you can employ the following professional approach: First, catch the exception using a try-catch block. Within the catch block, issue a refresh command or navigate back to the page’s URL, allowing the page to reload and update the element references, thereby avoiding the stale element reference exception.
Can I use explicit waits to handle stale element reference exceptions?
Yes, explicit waits can be used to handle stale element reference exceptions in a professional manner. By specifying the maximum amount of time to wait for an element to become stable, explicit waits allow for a more controlled approach to handling such exceptions, ensuring smoother execution of test scripts and improved reliability in automated testing scenarios.
What are some best practices to avoid stale element reference exceptions?
To avoid stale element reference exceptions, it is advisable to employ a set of best practices. These include synchronizing page loads, using explicit waits for element visibility, minimizing the use of dynamic elements, updating element references when necessary, and leveraging stable locators. Implementing these practices ensures greater stability and reliability in automated tests, reducing the occurrence of stale element reference exceptions.
Is there a specific method in Selenium to handle stale element reference exceptions?
Yes, Selenium provides a method to handle stale element reference exceptions. By using the
ExpectedConditions class in conjunction with the
WebDriverWait class, you can wait for a certain condition (e.g., element visibility or presence) before interacting with an element, effectively mitigating stale element reference exceptions and ensuring smoother test execution.
Got Questions? Drop them on LambdaTest Community. Visit now