我一直遇到Selenium中的陈旧元素错误。根据我的研究,当您离开页面或元素已更改时,会发生此错误。当我浏览web元素列表以尝试通过值识别其中一个时,我不断遇到此错误。当我尝试比较名称时,它总是在下面的if语句中失败。有谁知道我的问题是什么? 在一个更大的问题上,是否有一个很好的修复陈旧元素错误?我在网上看到的只是捕获错误并再次循环。有比这更好的方法吗?
int attempts = 0;
while(attempts < 2){
try{
java.util.List<WebElement> elements = driver.findElements(By.tagName("span"));
for(WebElement element: elements){
if(element.getText().equals(elementName)){
return element;
}
}
}catch (org.openqa.selenium.StaleElementReferenceException e){
e.printStackTrace();
}
attempts++;
}
return null;
答案 0 :(得分:2)
首先,你应该写出更好的定位器。你正在做的是你正在查询所有<span>
元素到webelements列表然后在你的foreach循环中再次触发每个元素的findElement
方法,直到你从循环中断开在循环内部,您将触发getText
方法。这绝对是一种矫枉过正。最好编写一个定位器来查询特定元素,例如//span[text() == 'valueOfelementNameVariable']
,然后使用WebDriverWait类并等待元素可用于交互。
例如,您可以使用visibilityOfElementLocated
预期的条件,如:
WebElement yourSpanElement = (new WebDriverWait(driver, 60))
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[text() == \"valueOfelementNameVariable\"]")));
WebDriverWait的until函数将轮询DOM,直到ExpectedCondition返回true或发生超时。更确切地说:
public V until(com.google.common.base.Function IsTrue运算)
将此实例的输入值重复应用于给定的函数 直到出现以下情况之一:
the function returns neither null nor false, the function throws an unignored exception, the timeout expires, the current thread is interrupted
如果你看一下visibilityOfElementLocated
的实现 /**
* An expectation for checking that an element is present on the DOM of a page
* and visible. Visibility means that the element is not only displayed but
* also has a height and width that is greater than 0.
*
* @param locator used to find the element
* @return the WebElement once it is located and visible
*/
public static ExpectedCondition<WebElement> visibilityOfElementLocated(
final By locator) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
try {
return elementIfVisible(findElement(locator, driver));
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return "visibility of element located by " + locator;
}
};
}
它已经忽略了元素的陈旧性(意味着如果元素过时并且轮询继续,它将返回null)并且相同的函数将在找到元素后返回该元素,或者如果上面描述的内容则抛出异常发生。
在一个更大的问题上,是否有一个很好的修复陈旧元素错误?
您应该使用Page Object设计模型。如果你使用PageFactory启动所有元素,并带来许多其他好处(主要是维护方面),你也会失去大部分陈旧性问题,因为在这种情况下,WebElements会被懒惰地评估,这意味着每次调用该元素时都会执行元素查找。