Selenium Webdriver with Java:在缓存中找不到元素 - 也许页面在被查找后已经发生了变化

2022-09-03 05:56:17

我正在类的开头初始化一个变量:

public WebElement logout;

稍后在代码中,在某个方法中,当我第一次遇到注销按钮时,我会为该变量分配一个值(在if/else语句的括号中):

logout = driver.findElement(By.linkText("Logout"));
logout.click();

然后,我在测试的另一个阶段再次成功使用“注销”:

logout.click();

在测试结束时,在元素相同的地方(By.linkText(“Logout”)),我得到这个错误:

Element not found in the cache - perhaps the page has changed since it was looked up

为什么?

编辑:实际上,我没有成功使用注销.click();在我测试的另一个阶段。看起来我不能再使用它了。我必须创建一个logout1 webelement并使用它...


答案 1

如果在最初找到页面后对页面进行了任何更改,则引用现在将包含引用。随着页面的更改,将不再位于预期的位置。elementwebdriverstaleelementwebdriver

要解决您的问题,请在每次需要使用它时尝试使用该元素 - 编写一个小方法,您可以在何时调用它是一个好主意。find

import org.openqa.selenium.support.ui.WebDriverWait

public void clickAnElementByLinkText(String linkText) {
    wait.until(ExpectedConditions.presenceOfElementLocated(By.linkText(linkText)));
    driver.findElement(By.linkText(linkText)).click();
}

然后,在您的代码中,您只需要:

clickAnElementByLinkText("Logout");

因此,每次它找到该元素并单击它时,即使页面在“刷新”对该元素的引用时发生变化,它也会成功单击它。


答案 2

浏览器重建了动态页面的DOM结构,因此元素不需要保留,您必须在使用之前找到它们。

例如,使用 XPath。此方法不正确(将来可能会导致异常):org.openqa.selenium.StaleElementReferenceException

WebElement element = driver.findElement(By.xpath("//ul[@class=\"pagination\"]/li[3]/a"));
...// Some Ajax interaction here
element.click(); //<-- Element might not be exists

这种方法是正确的:

driver.findElement(By.xpath("//ul[@class=\"pagination\"]/li[3]/a")).click();

推荐