Dynamics of StaleElement Reference Exception {Origin}

Stale Element
5 min readJan 29, 2021

Abstract:

The StaleElementReference Exception is one of the most fascinating exceptions which you would have tackled while running your selenium tests. I have seen people mixing its concepts with NoSuchElementException.

Per Selenium Webdriver documentation, the reference to an element is now “stale” — the element no longer appears on the DOM of the page. In layman words, the element that is located using the findElement or findElements method becomes inaccessible when you attempt to perform any actions on it.

Communication Protocol:

As a step to comply W3C standards, WebDriver leverages JSON as a medium of communication between client libraries (Java, C#, Python and so on) and drivers (Gecko Driver, Safari and Chrome Driver). The request is in the form of an HTTP request which accepts input in the form of JSON. Driver then performs the operation and the response of that is reverted to the client in the form of JSON response. Similarly, the RemoteWebDriver client and the RemoteWebDriver server use the JSON wire protocol to communicate among themselves. Find the W3C contract here.

The state (or instance) of the webdriver is converted into JSON through serialization and the response is de-serialized to obtain a webdriver object.

To sum up, lets see how it works −

Architecture of Selenium communication protocol

In the image above, Browser driver is a simple REST service that communicates over HTTP protocol. It is a service that runs over the machine where the browser is supposed to be installed. Please note the connection between Browser driver and browser is always local. So you have to have the browser driver installed at the node (if using Selenium Grid). You might have seen this message while invoking driver service:

Sample console of Selenium Webdriver

Object to Service:

Method of Action:

In general, we create our tests in any of the following programming languages:

Find Element usage through different bindings

Each time we create a webdriver instance a unique sessionId is generated and every following action is attached to that same session. So the responsibility of the Language client is to transform the code above to a legitimate API call. In the below request, localhost has chromedriver service running on port 9515.

Response:

If you observe the response, we have a unique sessionId, status and unique ElementId, this elementId is unique with each and is bound to the state of the page. You have to note that every node inside the DOM has this id and is reassigned when the state of the page is changed either by AJAX, RELOAD or NAVIGATE.

In case of StaleElement reference Exception, the browser driver service responds with following JSON:

StaleElementReference Exception thrown by ChromeDriver

With this information, it is evident that when you are trying to interact with the element that is found a few milliseconds before could have disappeared because the page gets refreshed/reloaded when you interacted with click or type or something. Even if the page is exactly the same after refresh/AJAX call, browser drivers won’t allow you to interact with the webelement even if the element information changes/doesn’t change at the DOM between calls (locate and action). The exception is thrown from the Browser driver (Chrome driver in this case) and the client just deserialize and cast it to WebElement Object as below:

De-Serialization of JSON response into WebElement Object

Point to note — StaleElementReference Exception arises when we attempt to perform any action on the webelement rather than finding the element and this is how it distinguishes from NoSuchElement Exception.

Now let’s broaden the perspective a little bit…

In our explanation above we have talked about WebElement. We should understand that from a DOM perspective, WebElement could be div/span/body/iframe or even a shadow dom, the behaviour and contract of the browser driver remains the same for all kinds of nodes.

How do we handle this exception?

This exception has multiple solutions. You need to find the simplest and optimized option based on your problem occurrence and experience.

Page factory or invoke when reference technique: This is the most optimized solution for handling this exception. The method of instantiating webelement at the time of reference is done through Java Reflection and Invoke function.

Retry to locate again on Stale exception: This is a primitive method for Javascript and Php based selenium automation. Idea is to simply catch or resolve the promise and retry element instantiation using the same locator.

Waits: This is a vague solution which may or may not work because once any element is marked as stale, irrespective of how much wait you put in, you would never be able to interact with it.

In our next chapter, we will talk more about the above mentioned solution and their implementation in different languages. In that chapter, we will also dig down deeper to handle the fragility of your test cases which is the most often challenge of test automation.

Till then — Happy Testing :)

--

--