lecture 2 of 160 completed

Why elements go stale

StaleElementReferenceException is the most common Selenium error. Once you know the cause, the fix is easy.

You will meet this error more than any other in Selenium:

StaleElementReferenceException: element is not attached to the page document

It confuses everyone the first time, because the element is clearly on the screen.

Here is what is really happening. When you call findElement, Selenium gives you a reference: a pointer to one specific element object in the browser. It is a bit like a house number. If the house is knocked down and rebuilt, your number no longer points to anything, even though a house is standing there.

Modern web apps rebuild parts of the page all the time. Any time React or Vue re-renders a list, the old elements are thrown away and new ones are created. Your reference now points at something that no longer exists.

Look at this code:

const row = await driver.findElement(By.css('[data-testid="contact-row"]'));
await driver.findElement(By.css('[data-testid="refresh"]')).click();
await row.getText(); // StaleElementReferenceException

The refresh rebuilt the table. row points to the old table's row.

The fix is to find the element again after anything that changes the page.

await driver.findElement(By.css('[data-testid="refresh"]')).click();
const row = await driver.findElement(By.css('[data-testid="contact-row"]'));
await row.getText();

This gives you a practical habit: find elements as late as possible, and use them immediately. Do not collect a list of elements at the top of your test and use them ten lines later.

There is one pattern that catches people out, and it is worth showing:

const rows = await driver.findElements(By.css('[data-testid="contact-row"]'));
for (const row of rows) {
  await row.click();      // this click may re-render the table
  await driver.navigate().back(); // now every remaining row is stale
}

If the loop changes the page, find the rows again inside each turn of the loop, or work by index and re-find each time.

Remember this: an element reference is only valid until the page changes. Find it again after every action that rebuilds part of the page.

Reference: Common errors.