16

我在课堂开始时初始化一个变量:

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

为什么?

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

4

3 回答 3

31

如果在您最初找到该参考资料后页面有任何更改,现在elementwebdriver参考资料将包含一个stale参考资料。随着页面的变化,element将不再是webdriver预期的位置。

要解决您的问题,请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");

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

于 2013-07-31T14:19:41.873 回答
0

浏览器重建了动态页面的 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();
于 2016-07-06T14:06:05.837 回答
-7

这是因为您没有给适当的时间来加载页面。所以您必须为给Thread.sleep();定页面提供代码。
我的项目也遇到了同样的问题,但是在使用Thread.sleep();它对我来说工作正常后,尽可能多地为网页提供 30 到 50 秒。

于 2014-03-06T10:48:51.633 回答