Selenium 4和WebDriver隐含地等待



在Selenium项目中,我们使用隐式等待和流畅等待。基本上,我们使用隐式等待,直到我们需要显式的东西。例如,对于正常的findElements((调用,我们依赖于隐式等待,但当单击某个按钮后等待元素消失时,我们使用流畅的等待。(请参阅下面的代码(。

问题是,最近我在调用implicityWait(n(时看到了一些超时。这个似乎是新的。甚至可能在硒4.3中。不能肯定地说,但它确实变得令人烦恼。为了清楚起见;偶尔";意味着在几百次测试中进行几次(每次调用implicitlyWait数十次(。

public void waitUntilElementDisappear(By locator, int waitTime) throws Exception, TimeoutException {
Logger.log(String.format("Waiting [%ds] for [%s] to disappear", waitTime, locator));
try {
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(0));
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(waitTime));
wait.until(ExpectedConditions.invisibilityOfElementLocated(locator));
} catch (TimeoutException e) {
Logger.log("Caught timeout exception");
throw e;
} catch (Exception e) {
Logger.log(String.format("Caught exception message:[%s]", e.getMessage()));
throw e;
} finally {
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(DEFAULT_WAIT));
}
}

该问题仅发生在finally块中。(DEFAULT_WAIT通常为180(。

有什么建议吗?

例外:

org.openqa.selenium.TimeoutException: java.util.concurrent.TimeoutException
Build info: version: '4.3.0', revision: 'a4995e2c09*'
System info: host: 'DESKTOP-8Q1PEBT', ip: '172.32.6.43', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.15'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Command: [e8d45a02973053acad1a896d2ed471e6, setTimeout {implicit=0}]
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 103.0.5060.134, chrome: {chromedriverVersion: 103.0.5060.134 (8ec6fce403b..., userDataDir: C:UsersjenkinsAppDataLo...}, goog:chromeOptions: {debuggerAddress: localhost:59791}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: WINDOWS, proxy: Proxy(), se:cdp: ws://172.32.6.43:4444/sessi..., se:cdpVersion: 103.0.5060.134, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
Session ID: e8d45a02973053acad1a896d2ed471e6
at org.openqa.selenium.remote.http.netty.NettyHttpHandler.makeCall(NettyHttpHandler.java:65)

我仍然在Chrome 104 中看到以下内容

10:48:48 Build info: version: '4.3.0', revision: 'a4995e2c09*'
10:48:48 System info: host: 'DESKTOP-8Q1PEBT', ip: '172.32.6.43', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.15'
10:48:48 Driver info: org.openqa.selenium.remote.RemoteWebDriver
10:48:48 Command: [f97c4a4cd7a0d468391badd20e23fe8f, setTimeout {implicit=240000}]
10:48:48 Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 104.0.5112.81, chrome: {chromedriverVersion: 104.0.5112.79 (3cf3e8c8a07d..., userDataDir: C:UsersjenkinsAppDataLo...}, goog:chromeOptions: {debuggerAddress: localhost:56549}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: WINDOWS, proxy: Proxy(), se:cdp: ws://172.32.6.43:4444/sessi..., se:cdpVersion: 104.0.5112.81, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
10:48:48 Session ID: f97c4a4cd7a0d468391badd20e23fe8f]
10:48:48 org.openqa.selenium.TimeoutException: java.util.concurrent.TimeoutException

在ChromeDriver中仍未修复。:(

我决定唯一的解决方案是捕获异常并重试@pcalkins建议。

public void setImplicitWait(int maxWaitTime) {
try {
this.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(maxWaitTime));
} catch (TimeoutException e) {
this.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(maxWaitTime));
}
}

当然,可能有一个计数器和一个最大重试次数,但到目前为止,我只发现了一次重试,而且从未失败。

我最终以同样的方式包装了一大堆基本方法(例如findElement(。

我知道这很粗糙,但到目前为止似乎是我的解决方案。

根据硒文档:敲钟

警告:不要混合隐式和显式等待。这样做可能会导致不可预测的等待时间。例如,设置10秒的隐式等待和15秒的显式等待可能会导致20秒后发生超时。


解决方案

要模拟检查元素是否不可见的预期,可以使用以下方法之一:

  • 使用invisibilityOf(WebElement element)

    new WebDriverWait(driver, Duration.ofSeconds(waitTime)).until(ExpectedConditions.invisibilityOf(driver.findElement(By.cssSelector("ElementCss"))));
    
  • 使用invisibilityOfElementLocated(By locator)

    new WebDriverWait(driver, Duration.ofSeconds(waitTime)).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("ElementCss")));
    

最新更新