测试抛出 StaleElementReferenceException:元素不再附加到 DOM 或页面已刷新

Test throws StaleElementReferenceException: either the element is no longer attached to the DOM or the page has been refreshed

我查看了在线论坛和本网站上的讨论并添加了等待功能。但是,它继续显示此错误 问题代码如下:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import com.google.common.base.Function;

public class WebDriverNavigate {
    public static void main(String[] args) throws InterruptedException {
    System.setProperty("webdriver.gecko.driver",System.getProperty("user.dir")+"/GeckoDriver/geckodriver.exe");
        WebDriver driver = new FirefoxDriver();
        driver.navigate().to("http://www.google.com");
        WebElement textbox = driver.findElement(By.id("lst-ib"));
        textbox.sendKeys("Search on Google");       
        WebDriverWait wait = new WebDriverWait(driver,10);
        wait.until(visibilityOfElementLocated(By.id("lst-ib")));
        driver.findElement(By.name("btnK")).click();;
        textbox.clear();                
        textbox.sendKeys("This is the second search");
        WebElement searchbutton2 = driver.findElement(By.id("fZl"));
        searchbutton2.click();
        driver.navigate().back();
        driver.navigate().forward();
        driver.navigate().refresh();

    }

    private static Function<WebDriver,WebElement> visibilityOfElementLocated(final By locator) {
        return new Function<WebDriver, WebElement>() {
            @Override
            public WebElement apply(WebDriver driver) {
                return driver.findElement(locator);
            }
        };
    }
}

这是 HTML 片段:

<input class="gsfi" id="lst-ib" maxlength="2048" name="q" autocomplete="off" title="Search" value="Search on Google" aria-label="Search" aria-haspopup="false" role="combobox" aria-autocomplete="list" style="border: medium none; padding: 0px; margin: 0px; height: auto; width: 100%; background: transparent url(&quot;data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D&quot;) repeat scroll 0% 0%; position: absolute; z-index: 6; left: 0px; outline: medium none;" dir="ltr" spellcheck="false" type="text">

控制台上的错误消息:

线程中出现异常 "main" org.openqa.selenium.StaleElementReferenceException:过时的元素引用:元素不再附加到 DOM 或页面已刷新

这个问题我遇到过很多次,有时解决不了。

首先,您应该找到带有 Wait 或 WaitFluent selenium 类 的元素。因为也许您尝试在元素尚未加载之前找到该元素。类似的东西:

new FluentWait<WebDriver>(driver)
            .withTimeout(IMPLICIT_TIMEOUT, TimeUnit.SECONDS)
            .pollingEvery(RETRY_TIME, TimeUnit.SECONDS)
            .ignoring(StaleElementReferenceException.class,
                      NoSuchElementException.class)
            .until(ExpectedConditions
            .visibilityOfElementLocated(By.xpath(xpath)));

其他方法是在一个里面有 driver.sleep() 的 for 中尝试多次。

大多数情况下,这是因为 DOM 正在更新并且您试图访问 updated/new 元素。所以this Question&Answers应该覆盖你。

您还可以查看 Selenium Documentation

在大多数情况下 explicit wait 有效。

或者您可以忽略该错误,直到元素可以点击为止

new WebDriverWait(driver, timeout).ignoring(StaleElementReferenceException.class).until(ExpectedConditions.elementToBeClickable(By.name("btnK")));
driver.findElement(By.name("btnK")).click();

我可以通过按以下顺序重新排列代码来解决问题:

        WebElement searchbutton = driver.findElement(By.name("btnK"));
        driver.findElement(By.name("btnK")).click();
        WebDriverWait wait = new WebDriverWait(driver,10);
        WebElement text2 = wait.until(visibilityOfElementLocated(By.id("lst-ib")));
        text2.clear();  

看起来我试图在 click() 之前等待,但应该在 click() 之后但在 clear() 之前等待元素加载 现在它不会抛出那个错误

感谢大家的建议和解决方案。我相信它们在将来解决更复杂的代码问题时会有用。