I am getting an error while running my selenium tests
Exception in thread "main"
org.openqa.selenium.StaleElementReferenceException: stale element
reference: element is not attached to the page document
(Session info: chrome=63.0.3239.84)
(Driver info: chromedriver=2.34.522932 (
4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.12.6
x86_64) (WARNING: The server did not provide any stacktrace
information)
Command duration or timeout: 0 milliseconds
For documentation on this error, please visit:
http://seleniumhq.org/exceptions/stale_element_reference.html
01T19:05:14.666Z'.
Here is the code
List<WebElement> category =
driver.findElements(By.className("a2s-skill-block"));
for(int i = 0;i<category.size();i++) {
category.get(i).click();
Thread.sleep(7000);
driver.navigate().back();
// WebElement skills1 = driver.findElement(By.id("iApps"));
//skills1.click();
Thread.sleep(15000);
}
I went through similar thread posts on this question and tried a lot of solutions mentioned by fellow members but somehow the wait and Expected COnditions don't seem to work.Any other direction of thought is really appreciated.
These are the options I tried
Introduced wait and Expected Conditions
WebDriverWait wait = new WebDriverWait(driver, 150);
wait.until(ExpectedConditions. presenceOfAllElementsLocatedBy(By.className("text-heading")));
答案 0 :(得分:1)
您应该花一些时间阅读并了解StaleElementReferenceException
是什么。重要的是要了解导致它的原因以及如何避免它。
在这种情况下,您正在抓取页面并使用第1页的元素加载category
。然后单击一些链接,将您带到第2页。此时,{{1}中的所有引用陈旧但是尚未引发异常,因为您尚未访问任何变量。然后使用category
返回第1页并尝试使用.back()
执行某些操作并获取异常。
为避免这种情况,您需要在从其他页面使用category
后将元素重新调整到第1页的category
。一种方式是我在下面写的。页面在每个循环的底部被抓取。
.back()
答案 1 :(得分:0)
您可以在循环之前找到页面上的所有类别。当您点击循环内的某些内容进入另一个页面时,实际上是“过时元素参考”#39;已经被触发了,最后你终于回到了最后一页。
以下条件会触发“陈旧元素参考”
条件1
上次进入页面时使用找到的元素,并且您至少离开页面一次(即使您再次返回)。
您可以认为,当您进入页面时,Selenium将为Selenium内部的页面分配一个引用,即使您输入了相同的页面,但Selenium也不知道它们是相同的,因此它将分配一个新的引用。
您只能使用找到的元素,哪个页面引用与您当前页面相同。
条件2
留在页面上(不要离开),但是你的脚本触发了找到的元素的HTML DOM节点更改/重新附加/删除。例如,DOM节点的某些属性已更改,或者DOM节点被删除并再次添加回去,所有这些都不会改变。
因此,找到的元素的DOM节点上的任何更改/移动都将触发“陈旧元素参考”。您可以认为条件1只是改变/移动DOM节点的另一种方式。
要解决您的问题,您应该读出所有类别的属性,这些属性可用于在循环中稍后识别该类别。
下面的代码假设每个类别都有唯一的文字:
List<WebElement> category =
driver.findElements(By.className("a2s-skill-block"));
List<String> categoryTexts = new ArrayList<String>();
for(WebElement it: category) {
categoryTexts.add(it.getText());
}
for(int i = 0;i<category.size();i++) {
driver.findElement(By.xpath("//*[text()='"+categoryTexts.get(i)+"']")).click();
Thread.sleep(7000);
driver.navigate().back();
Thread.sleep(15000);