Glossario · Automazione della UI
StaleElementReferenceException
Detto anche: stale element, stale element reference, elemento stale, stale element exception
Definizione
Errore di Selenium lanciato quando un test usa un WebElement il cui nodo DOM è stato rimosso o sostituito dopo essere stato trovato, di solito dopo un re-render.
StaleElementReferenceException significa che l’elemento a cui il tuo codice fa riferimento non esiste più nella pagina. In Selenium un WebElement è un riferimento a uno specifico nodo del DOM. Se l’applicazione rimuove quel nodo, ad esempio perché un framework ha ri-renderizzato la lista, la pagina ha navigato o un aggiornamento AJAX ha sostituito una sezione, il riferimento non punta più a nulla e qualsiasi chiamata su di esso lancia questa eccezione.
Esempio
WebElement firstRow = driver.findElement(By.cssSelector("table tbody tr"));
driver.findElement(By.id("sort-by-date")).click(); // table body is re-rendered
firstRow.getText(); // StaleElementReferenceException
Sullo schermo l’elemento sembra identico, ma è un nodo nuovo. Il vecchio riferimento è morto.
Come risolverla
Trova di nuovo l’elemento nel momento in cui ti serve e attendi il nuovo stato invece di catturare l’eccezione.
By firstRow = By.cssSelector("table tbody tr");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement before = driver.findElement(firstRow);
driver.findElement(By.id("sort-by-date")).click();
// Wait until the old node is gone, then look up the new one
wait.until(ExpectedConditions.stalenessOf(before));
String text = driver.findElement(firstRow).getText();
Altri pattern utili:
- Memorizza locator
By, non campiWebElement, nei page object. Cerca l’elemento dentro ciascun metodo. - Attendi che l’aggiornamento sia concluso (uno spinner che scompare, un numero di righe che cambia) prima di leggere i valori.
- Evita le liste di lunga durata. Iterare su una
List<WebElement>cliccando elementi che provocano re-render è una fonte classica di questo errore. Ripeti la query per indice o per un attributo univoco a ogni passaggio.
Perché Playwright ha raramente questo problema
Un Locator di Playwright è una query, non un riferimento a un nodo. Risolve di nuovo l’elemento per ogni azione e asserzione, quindi un re-render tra un passo e l’altro non lo rompe. L’ElementHandle di livello più basso di Playwright può comunque puntare a un nodo staccato dal DOM, ed è uno dei motivi per cui la documentazione ti indirizza verso i locator.
Avvolgere ogni chiamata in un ciclo di retry sugli elementi stale fa sparire l’errore ma nasconde il vero problema: il test non sta aspettando che la pagina si stabilizzi.