How to avoid “StaleElementReferenceException” in Selenium?

前端 未结 16 2275
一向
一向 2020-11-22 12:12

I\'m implementing a lot of Selenium tests using Java. Sometimes, my tests fail due to a StaleElementReferenceException. Could you suggest some approaches to mak

16条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-22 12:50

    I was having this issue intermittently. Unbeknownst to me, BackboneJS was running on the page and replacing the element I was trying to click. My code looked like this.

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

    Which is of course functionally the same as this.

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

    What would occasionally happen was the javascript would replace the checkoutLink element in between finding and clicking it, ie.

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

    Which rightfully led to a StaleElementReferenceException when trying to click the link. I couldn't find any reliable way to tell WebDriver to wait until the javascript had finished running, so here's how I eventually solved it.

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

    This code will continually try to click the link, ignoring StaleElementReferenceExceptions until either the click succeeds or the timeout is reached. I like this solution because it saves you having to write any retry logic, and uses only the built-in constructs of WebDriver.

提交回复
热议问题