RemoteWebDriver调用Selenium BiDi组件失败,寻求社区协助
WebDriver BiDi在Selenium Grid/RemoteWebDriver环境下报错排查求助
我的代码在本地ChromeDriver实例上运行正常,WebDriver BiDi协议功能完全可用。但切换为连接Selenium Grid/Server的RemoteWebDriver实例时,抛出错误:
java.lang.IllegalArgumentException: WebDriver instance must support BiDi protocol
我已编写基础测试,通过设置webSocketUrl capability构造ChromeDriver,可成功实例化JSFatalCatch工具类并初始化LogInspector,本地测试全部通过。
排查情况
- 本地ChromeDriver场景:Driver实例包含
biDiUri和BiDi实例,说明WebDriver BiDi连接已成功建立,LogInspector等BiDi API可正常使用。 - RemoteWebDriver连接Grid场景:Driver的Capabilities中存在
se:bidi字段,但仍抛出不支持BiDi的错误,排除代码本身问题,怀疑是Selenium Server(Grid)的配置问题。
以下是测试代码及Driver Capabilities信息,恳请社区协助解决:
测试类代码
import com.qa.test.ui.jsFatalCatch.JSFatalCatch; import org.openqa.selenium.By; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.testng.Assert; public class BiDiLoggingTest { public static void main(String[] args) throws Exception { //Setup ChromeOptions options = new ChromeOptions(); options.setCapability("webSocketUrl", true); ChromeDriver driver = new ChromeDriver(options); JSFatalCatch jsFatalCatch = new JSFatalCatch(driver); driver.get("http://ccui-beta.integ.amazon.com/jsErrorOnElementAction"); driver.findElement(By.id("jsException")).click(); jsFatalCatch.addJSLogsAndExceptions(); String displayText = jsFatalCatch.getJSExceptionDisplayText(); Assert.assertTrue(displayText.contains("Error"), "JS exception found must contain expected logEntry text"); Assert.assertTrue(displayText.contains("javascript"), "JS exception found must contain expected logEntry type"); System.out.println(displayText); System.out.println(" I HAVE PASSED!!"); driver.quit(); } }
JSFatalCatch工具类代码
import com.qa.test.ui.element.Element; import com.qa.test.ui.session.Session; import lombok.Getter; import org.openqa.selenium.WebDriver; import org.openqa.selenium.bidi.LogInspector; import org.openqa.selenium.bidi.log.JavascriptLogEntry; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; // Utility Class for JSFatalCatch feature. public class JSFatalCatch { @Getter private final WebDriver driver; private final LogInspector logInspector; // 用于通过WebDriver BiDi API捕获浏览器日志(包括JavaScript日志) private CompletableFuture<JavascriptLogEntry> future; // 处理捕获JavaScript日志的异步逻辑 private JavascriptLogEntry logEntry; public JSFatalCatch(WebDriver driver) { this.driver = driver; this.logInspector = new LogInspector(driver); this.future = new CompletableFuture<>(); // 配置异步回调,捕获到JavaScript日志时完成Future logInspector.onJavaScriptLog(future::complete); } /** * 验证Session和Element级别是否都开启了JSFatalCatch配置 * 只有两者都开启时,才会在UI测试中检查浏览器事件的JS错误 */ public boolean isJSFatalCatchEnabled(Element element) { boolean jsFatalCatchEnabled = Session.getSession().getSessionConfig().isJsFatalCatchEnabledForSession(); if(jsFatalCatchEnabled) { if(!element.isJsFatalCatchEnabledForElement()) { jsFatalCatchEnabled = element.isJsFatalCatchEnabledForElement(); } } return jsFatalCatchEnabled; } // 添加浏览器会话中产生的JavaScript日志和异常 public void addJSLogsAndExceptions() throws Exception { // 等待最多5秒,直到Future捕获到JavaScript日志 logEntry = future.get(5, TimeUnit.SECONDS); } // 验证浏览器事件中是否存在JS异常 public boolean isJSExceptionPresent() throws Exception { addJSLogsAndExceptions(); return logEntry.getLevel() != null; } // 返回用于日志记录的JS异常自定义信息 public String getJSExceptionDisplayText() throws Exception { if(isJSExceptionPresent()) { StringBuilder displayText = new StringBuilder(); displayText.append("JSException text- ").append(logEntry.getText()); displayText.append(", JSException Level- ").append(logEntry.getLevel()); displayText.append(" and JSException Type- ").append(logEntry.getType()); return displayText.toString(); } return "No JS Exceptions were logged!"; } }
本地Driver Capabilities
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 122.0.6261.112, chrome: {chromedriverVersion: 122.0.6261.94 (880dbf29479c..., userDataDir: /var/folders/lw/n7ymtq912_n...}, fedcm:accounts: true, goog:chromeOptions: {debuggerAddress: localhost:60015}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: mac, proxy: Proxy(), se:cdp: ws://localhost:60015/devtoo..., se:cdpVersion: 122.0.6261.112, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webSocketUrl: ws://localhost:9111/session..., webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true} biDiUri : Optional[ws://localhost:9111/session/7cf7dac1edd6bd93565cd79d5bca75b9] biDi : Optional[org.openqa.selenium.bidi.BiDi@1cd201a8]
远程Driver Capabilities
Capabilities {acceptInsecureCerts: true, browserName: chrome, browserVersion: 122.0.6261.112, chrome: {chromedriverVersion: 122.0.6261.94 (880dbf29479c..., userDataDir: /var/folders/lw/n7ymtq912_n...}, fedcm:accounts: true, goog:chromeOptions: {debuggerAddress: localhost:61474}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: mac, proxy: Proxy(), se:bidi: ws://10.0.0.79:4444/session..., se:cdp: ws://10.0.0.79:4444/session..., se:cdpVersion: 122.0.6261.112, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webSocketUrl: ws://localhost:28501/sessio..., webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true}
内容的提问来源于stack exchange,提问作者supriti mohanty
相关产品推荐
相关产品推荐

