我已经通过此页面http://www.efinancialcareers.co.uk/search自动化了一些用户流程。 当我使用左侧精炼轨道缩小搜索范围时,会出现一个叠加层,用户必须等到返回搜索结果。该方法等待叠加层出现,然后等待它消失。
public void waitForSRPOverlayToComplete() {
Wait<WebDriver> wait = new FluentWait<WebDriver>(getDriver())
.withTimeout(5, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.NANOSECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(TimeoutException.class);
**// Error occurs here**
WebElement blockedOverlay = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.className("blockOverlay"));
}
});
Wait<WebDriver> wait2 = new FluentWait<WebDriver>(getDriver())
.withTimeout(5, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.NANOSECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(TimeoutException.class);
wait2.until(ExpectedConditions.stalenessOf(blockedOverlay));
}
有时我会收到Timeout异常,因为找不到元素(blockOverlay)。当发生这种情况并且叠加确实出现时我观察了页面,但我认为有时当搜索速度非常快时,上面的方法会错过它。 我不明白为什么我会遇到技术错误,因为我告诉流利的等待忽略它们。
这是显示叠加层的代码:
$('body').block({
message: $('#loaderEl'),
css: {
backgroundColor: 'transparent',
border: "none",
color: '#333333',
fontWeight: 'bolder',
top: ($(window).height() - $('#loaderEl').height()) / 2 + $(window).scrollTop() + "px"
},
overlayCSS: {
backgroundColor: '#f8f8f8'
},
centerY: false
});
并将其删除
$('body').unblock();
这是我收到的错误:
Caused by: org.openqa.selenium.TimeoutException: Timed out after 5 seconds waiting for com.efinancialcareers.myefc.desktop.BasePage$6@548238e0
Build info: version: '2.35.0', revision: '8df0c6bedf70ff9f22c647788f9fe9c8d22210e2', time: '2013-08-17 12:46:41'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.6.0_26'
Driver info: driver.version: unknown
... 33 more
Caused by: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"class name","selector":"blockOverlay"}
任何帮助或建议都将不胜感激。
答案 0 :(得分:8)
当TimeoutException
实际超时时,您无法取消FluentWait
。这只是API的本质。如果这是您真正想要忽略的异常,则需要捕获TimeoutException
。
此外,作为旁注,尝试每纳秒轮询一次这种情况可能会适得其反。您应该将轮询间隔延长到每200或250毫秒。
答案 1 :(得分:1)
非常感谢Jim Evans给我的关键线索,我需要知道为什么会出现这个问题。
我决定进一步深入研究FluentWait代码(Java 1.8或更高版本),看看为什么抛出TimeoutException,即使你请求它不被抛出。
FluentWait的典型示例:
WebDriver driver = new ChromeDriver();
FluentWait wait = new FluentWait(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = (WebElement) wait.until(new Function() {
@Override
public WebElement apply(Object input) {
return null;
}
});
我们查看FluentWait的until
方法,因为这是实际启动等待过程的方法。很可能所有异常处理/抛出逻辑都存在。 FluentWait的所有其他方法调用,例如withTimeout
,ignoring
等实际上为FluentWait对象创建“设置”。它们不执行任何操作,如等待或运行某些代码等。
让我们看一下documentation for "until"。最后一行告诉我们该方法抛出TimeoutException。因此,即使您请求了,也不应该忽略TimeoutException。
Throws:
TimeoutException - If the timeout expires.
我们现在快速查看FluentWait的代码,以了解为什么“until”不会忽略TimeoutException。
public <V> V until(Function<? super T, V> isTrue) {
long end = clock.laterBy(timeout.in(MILLISECONDS));
Throwable lastException = null;
while (true) {
try {
V value = isTrue.apply(input);
if (value != null && Boolean.class.equals(value.getClass())) {
if (Boolean.TRUE.equals(value)) {
return value;
}
} else if (value != null) {
return value;
}
} catch (Throwable e) {
lastException = propagateIfNotIgnored(e);
}
// Check the timeout after evaluating the function to ensure conditions
// with a zero timeout can succeed.
if (!clock.isNowBefore(end)) {
String message = messageSupplier != null ?
messageSupplier.get() : null;
String toAppend = message == null ?
" waiting for " + isTrue.toString() : ": " + message;
String timeoutMessage = String.format("Timed out after %d seconds%s",
timeout.in(SECONDS), toAppend);
throw timeoutException(timeoutMessage, lastException);
}
try {
sleeper.sleep(interval);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new WebDriverException(e);
}
}
}
while块将:
if块将在未传播异常时运行。如果发生超时,它将抛出TimeoutException。所以,这是负责超时异常的代码。