Ways to avoid "StaleElementReferenceException" errors in Selenium
P粉920835423
P粉920835423 2023-08-21 17:47:18
0
2
660
<p>I'm implementing a lot of Selenium tests in Java - sometimes, my tests fail due to <code>StaleElementReferenceException</code>. </p> <p>Can you suggest some ways to make the tests more stable? </p>
P粉920835423
P粉920835423

reply all(2)
P粉899950720

I once had this problem, but unbeknownst to me, BackboneJS was running on the page and it replaced the element I was trying to click on. My code is as follows.

driver.findElement(By.id("checkoutLink")).click();

This is of course functionally the same as the code below.

WebElement checkoutLink = driver.findElement(By.id("checkoutLink"));
checkoutLink.click();

What occasionally happens is that between the find and the click, javascript replaces the checkoutLink element, ie.

WebElement checkoutLink = driver.findElement(By.id("checkoutLink"));
// javascript替换了checkoutLink
checkoutLink.click();

This results in a StaleElementReferenceException exception when trying to click on the link. I couldn't find any reliable way to tell WebDriver to wait for the javascript to finish running, so this is how I ended up solving it.

new WebDriverWait(driver, timeout)
    .ignoring(StaleElementReferenceException.class)
    .until(new Predicate<WebDriver>() {
        @Override
        public boolean apply(@Nullable WebDriver driver) {
            driver.findElement(By.id("checkoutLink")).click();
            return true;
        }
    });

This code will continue to try to click the link, ignoring the StaleElementReferenceException exception, until the click is successful or the timeout is reached. I like this solution because it takes away the hassle of writing retry logic and only uses WebDriver's built-in constructs.

P粉343141633

This can occur if DOM operations taking place on the page temporarily render the element inaccessible. To deal with these situations, you can try to access the element multiple times in a loop until finally an exception is thrown.

Try using this excellent solution from darrelgrainger.blogspot.com:

public boolean retryingFindClick(By by) {
    boolean result = false;
    int attempts = 0;
    while(attempts < 2) {
        try {
            driver.findElement(by).click();
            result = true;
            break;
        } catch(StaleElementException e) {
        }
        attempts++;
    }
    return result;
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template