我在Ubunto上运行web E2E测试(使用cucumber,junit,selenium webDriver)。
我的测试在使用remoteWebDriver时失败零星(从未使用local-webDriver失败)
Then banner image in preview html should be "p_1047_o_9075_banner_1423040308.png"
Failure
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
当我将代码重构为此时,我以为我绕过了这个异常:
public String getSrcAfterWait(final By by) {
WebElement webElement = getElementAfterWaitForDisplay2(by);
String currentSrc = null;
if (webElement != null) {
currentSrc = webElement.getAttribute("src");
}
return currentSrc;
}
public WebElement getElementAfterWaitForDisplay2(final By by) {
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class, StaleElementReferenceException.class);
return wait.until(ExpectedConditions.presenceOfElementLocated(by));
}
我怎样才能进一步稳定这个测试?
更新
我正在尝试mentallurg
解决方案。但这个结构合理吗?
public String getButtonTextAfterWait(final By by) {
String currentText;
try {
currentText = tryToGetText(by);
} catch (StaleElementReferenceException ex)
{
currentText = tryToGetText(by);
}
return currentText;
}
答案 0 :(得分:1)
如果您的页面是动态的,可能会发生以下情况。
情景1。 在方法“getSrcAfterWait”中,您找到了带有“getElementAfterWaitForDisplay2”的元素。但在调用webElement.getAttribute(“src”)之前,元素会在页面上发生更改。当你调用webElement.getAttribute(“src”)时,“webElement”指向一个已经过时(不再存在)的元素。这导致StaleElementReferenceException。
情景2。 可能你有某种动画。因此,定期创建一个新的元素实例多次。 “getElementAfterWaitForDisplay2”总是找到“By”条件的元素,但不时地它是页面上的新对象。在找到元素之后,在调用webElement.getAttribute(“src”)之前,在页面上创建了一个新实例(在DOM中)。这样您所定位的变量就会引用已经过时的实例。
两种情况下的简单解决方案:捕获异常并再次找到对象。
更复杂的解决方案,但更通用:使用代理对象并实现异常处理和定位。
答案 1 :(得分:0)
@EladBenda:不是。你应该在循环中做到这一点。但是你不需要编写循环代码。请改用FluentWait。你只需要转换你的方法&#34; getButtonTextAfterWait&#34;进入ExpectedCondition或谓词或函数并将其传递给FluentWait。您不需要明确捕获异常。您可以通过...忽略(... Exception.class),就像您在其他地方已经做的那样。它可以如下所示:
Wait wait = new FluentWait(driver)
.withTimeout(60, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class, StaleElementReferenceException.class);
String text = wait.until(new Function() {
public String apply(WebDriver driver) {
WebElement element = driver.findElement(By.id("..."));
return element.getText(); // or webElement.getAttribute("src") etc.
}
});
答案 2 :(得分:0)
public void waitForElementBeDisplay(WebElement element) {
Wait wait = new FluentWait(driver).withTimeout(Duration.ofSeconds(30)).ignoring(StaleElementReferenceException.class).pollingEvery(Duration.ofSeconds(2));
wait.until(ExpectedConditions.refreshed(ExpectedConditions.visibilityOf(element)));
}