"org.openqa.selenium.StaleElementReferenceException: Element is no longer attached to the DOM"
错误,测试失败。代码如下:
@Test
public void rowSelection() throws Exception
{
SeleniumHelper helper = new SeleniumHelper();
action = new SeleniumActionHelper(driver);
helper.login();
String testUrl = navigateToUrl("option/listOptions.xhtml");
driver.get(testUrl);
WebElement table = findElementById("tableSection:dataTableWrapped_data");
List<WebElement> allRows = table.findElements(By.tagName("tr"));
for (WebElement row : allRows)
{
List<WebElement> cells = row.findElements(By.tagName("td"));
for (WebElement cell : cells)
{
WebElement listName = cell.findElement(By.xpath("./* [text()='body_build']"));
listName.click();
}
}
}
我在
Thread.sleep(2000)
动作的前面和后面都放置了listName.click()
,但都没有帮助。任何帮助将不胜感激。#1 楼
我认为您在执行listName.click()
之后重新加载了您的页面(或页面的一部分)。 重新加载后,还有一个表似乎与重新加载前的表相同,但不相同。
您可以计算表中的行/列,并在循环中使用迭代器。您需要在
之后重复
WebElement table = findElementById("tableSection:dataTableWrapped_data");
List<WebElement> allRows = table.findElements(By.tagName("tr"));
listName.click();
评论
显示的最后一个答案是完全正确的。。。
– Bipin Tiwari
2012年12月24日在7:33
#2 楼
发生陈旧元素的两个原因在WebDriver中被引用为WebElement的网页上找到一个元素,然后DOM更改(可能归因于JavaScript函数),WebElement变得陈旧。
元素已被完全删除。
当您尝试与陈旧的WebElement交互时(以上任何一种情况),都会引发StaleElementException。
要解决的解决方案它们:
将定位符存储到元素中而不是引用中
不要
driver = webdriver.Firefox();
driver.get("http://www.github.com");
search_input = driver.find_element_by_name('q');
search_input.send_keys('hello world\n'); // Page contents refresh after typing in search results.
time.sleep(5);
search_input.send_keys('hello frank\n'); // StaleElementReferenceException
做
driver = webdriver.Firefox();
driver.get("http://www.github.com");
search_input = lambda: driver.find_element_by_name('q');
search_input().send_keys('hello world\n');
time.sleep(5);
search_input().send_keys('hello frank\n') // no stale element exception
使用的JS库中的钩子
# Using Jquery queue to get animation queue length.
animationQueueIs = """
return $.queue( $("#%s")[0], "fx").length;
""" % element_id
wait_until(lambda: self.driver.execute_script(animationQueueIs)==0)
将动作转移到JavaScript注入中
self.driver.execute_script("$(\"li:contains('Narendra')\").click()");
主动等待元素过时
# Wait till the element goes stale, this means the list has updated
wait_until(lambda: is_element_stale(old_link_reference))
/>
此解决方案对我有用,如果您还有其他情况,我在这里已经提到过,对您有用,请在下面评论或与我联系这样我们就可以添加到解决方案列表中
评论
在您的Do代码块中,lambda:关键字是什么?它从何而来 ?这有什么用途 ?
– Stephane
19年8月19日在9:06
永远不要使用固定的等待时间.sleep()使用var el = driver.wait(until.elementLocated(
– MortenB
19年9月12日在11:39
#3 楼
我们有机会看到您要自动化的页面吗?我可以想到一个原因,那就是表的开发方式是存在一种javascript,当与该元素进行交互而不是修改该元素时,它会用一个新元素替换它,在这种情况下,该元素将不再存在...如果您在firefox或IE开发人员工具中使用firebug之类的内容来查看dom,将相关元素悬停在该元素上是否会发生变化?如果开发人员实际上是在替换元素而不是修改元素的类,那将是一个非常奇怪的实现,我认为您应该提交一个错误并让他们更改实现方式。
评论
不幸的是,由于各种原因,我无法显示我们正在处理的页面。该类正在被修改并且没有替换元素...这就是为什么我坐在这里挠头,对我来说这没有意义,因为我可以看到在给出DOM错误之前该行已被选中
–挤压
12年7月13日在21:10
javascript会怎样改变类? Selenium确实会尝试像用户一样操作,并在执行点击之前触发onmouseover之类的事件。如果将鼠标悬停在元素上会使它看起来“已选中”,则可能在触发该事件之后但单击之前发生了陈旧元素异常。
–山姆·伍兹(Sam Woods)
2012年7月13日在21:33
评论
这可能有助于处理此类元素-stackoverflow.com/questions/4846454/…