You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 01:50:01