Handle Stale Elements

A stale element reference error occurs when a referenced web element is no longer attached to the DOM. For a WebDriver-based UI test, an error message can look like: The element reference is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed.

This error message points to the reason why an error occurred. In a test, we found and saved an instance of an element, but then the content was refreshed (partially or completely) and the element became "stale". Basically, the element is now an orphan because it's no longer part of the DOM tree.

To avoid this type of test, a test should create a new element reference by finding the element again after it's attached to the DOM.

Let's look at a few use cases.

Page is refreshed completely

If a page is completely refreshed, we must:

Example of a Java test:

HomePage homePage = utam.load(HomePage.class);
assert homePage.isPresent();
// now something happened to refresh the page, for example you hit Save

// wait for refresh before you proceed!
homePage.waitForAbsence();

// create new instance of the root page object
homePage = utam.load(HomePage.class);
assert homePage.isPresent();

Example of a JavaScript test:

let homePage = await utam.load(HomePage);
expect(await homePage.isPresent()).toBeTrue();
// now something happened to refresh the page, for example you hit Save

// wait for refresh before you proceed!
await homePage.waitForAbsence();
expect(await pageContent.isPresent()).toBeFalse();

// create new instance of the root page object
homePage = await utam.load(HomePage);
expect(await homePage.isPresent()).toBeTrue();

Part of the page is refreshed

With AJAX-based applications, often only part of the content is refreshed. In this scenario, we don't need to recreate an instance of the root page object, but we need to call an element method for the element that's refreshed.

Example of a Java test:

HomePage homePage = utam.load(HomePage.class);
Content content = homePage.getDynamicContent();
// now something happened to refresh part of the content

// wait for refresh before you proceed!
content.waitForAbsence();

// call getter to invoke Element.findElement and assign a new variable
content = homePage.getDynamicContent();
assert content.isPresent();

Example of a JavaScript test:

let homePage = await utam.load(HomePage);
let content = await homePage.getDynamicContent();
// now something happened to refresh part of the content

// wait for refresh before you proceed!
await content.waitForAbsence();

// call getter to invoke Element.findElement and assign new variable
content = await homePage.getDynamicContent();
expect(await content.isPresent()).toBeTrue();