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

如何在Selenium C#中不指定Chrome DevTools版本避免测试中断

问题

在项目中使用Selenium DevTools的Network日志工具简化测试分析,但目前必须在using语句中指定Chrome的具体版本(如示例中的V122)。公司IT部门会定期更新Chrome,导致DevTools版本与Chrome版本不匹配,测试执行中断。

请问是否存在无需指定特定版本的实现方式,让Chrome更新后测试不会立即崩溃?

技术栈

  • Selenium 4
  • .NET 6

当前代码

using DevToolsSessionDomains = OpenQA.Selenium.DevTools.V122.DevToolsSessionDomains;

public class ChromeBrowser : MyBrowser
{
private static readonly ILogger _log = Serilog.Log.ForContext<ChromeBrowser>();
private ChromeDriver driver;

public override void InitDriver(bool runHeadless)
{
    new DriverManager().SetUpDriver(new ChromeConfig(), VersionResolveStrategy.MatchingBrowser);
    var service = ChromeDriverService.CreateDefaultService();

    driver = new ChromeDriver(service, DriverOptions(runHeadless), TimeSpan.FromMinutes(3));
    pid = service.ProcessId;
    _log.Information($"ChromeDriver PID = {pid}");
    _log.Information($"Chrome capabilities: {driver.Capabilities}");

    EnableLogging();
}
public void EnableLogging()
{
    if (!Properties.NetworkLogger)
    {
        //No logger is enabled
        _log.Information("No logging of network activity will be done during this test run.");
        return;
    }

    driver.ExecuteCdpCommand("Network.enable", new Dictionary<string, object>());

    var session = driver.GetDevToolsSession();
    var domains = session.GetVersionSpecificDomains<DevToolsSessionDomains>();

    domains.Network.Enable(new EnableCommandSettings());
    _log.Information("Logging of network activity has started.");
    domains.Network.RequestWillBeSent += RequestSentHandler;
    domains.Network.ResponseReceived += ResponseReceivedHandler;
}

public static void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
{
    //logging responses given
    if (MimeTypes.ExcludedFromLogs.Exists(m => e.Response.MimeType.Contains(m)))
    {
        return;
    }
    
    string logLine = $"Status: {e.Response.Status}\tType: {e.Response.MimeType}\tUrl: {e.Response.Url}";

    if (!MimeTypes.ExcludedFromBodyLogs.Exists(m => e.Response.MimeType.Contains(m)))
    {
        LogMessageBody(e.RequestId);
    }

    if (e.Response.Status != 200)
    {
        _log.Warning(logLine);
    }
    else
    {
        _log.Information(logLine);
    }
}

private static void LogMessageBody(string requestId)
{        
    var chromeDriver = TestBrowser.Browser as ChromeDriver;
    var session = chromeDriver.GetDevToolsSession();
    var domains = session.GetVersionSpecificDomains<DevToolsSessionDomains>();

    var settings = new GetResponseBodyCommandSettings
    {
        RequestId = requestId
    };

    var command = domains.Network.GetResponseBody(settings);
    if (command.IsCompletedSuccessfully) {
        var body = command.Result;
        if (body != null && !string.IsNullOrEmpty(body.Body))
        {
            _log.Information($"Body for requestId {requestId}");
            _log.Information(body.Body);
        }
    }
}


public static void RequestSentHandler(object sender, RequestWillBeSentEventArgs e)
{
    if (!(e.Request.HasPostData ?? false))
    {
        return;
    }
    //logging requests made
    string logLine = $"Method: {e.Request.Method}\tRequest sent:{e.Request.PostData}";
    _log.Information(logLine);
}
}
解决方案

核心思路:使用Selenium DevTools的通用抽象层

Selenium 4提供了不绑定特定Chrome版本的DevTools API,只需移除版本特定的引用,改用通用域对象即可自动匹配当前浏览器版本。

具体步骤

  1. 移除版本特定的依赖与引用

    • 删除项目中针对特定版本的NuGet包(如OpenQA.Selenium.DevTools.V122),只保留OpenQA.Selenium.DevTools包
    • 删除版本特定的using语句:using DevToolsSessionDomains = OpenQA.Selenium.DevTools.V122.DevToolsSessionDomains;
  2. 修改代码使用通用DevTools域
    替换所有版本特定的GetVersionSpecificDomains调用,改用GetDomain<T>获取通用的Network域对象,示例修改如下:

修改后的EnableLogging方法

using OpenQA.Selenium.DevTools.Network;

public async void EnableLogging()
{
    if (!Properties.NetworkLogger)
    {
        _log.Information("本次测试不会记录网络活动日志。");
        return;
    }

    var session = driver.GetDevToolsSession();
    // 获取通用的Network域,自动匹配浏览器版本
    var networkDomain = session.GetDomain<Network>();
    
    await networkDomain.Enable(new EnableCommandSettings());
    
    _log.Information("网络活动日志已开始记录。");
    networkDomain.RequestWillBeSent += RequestSentHandler;
    networkDomain.ResponseReceived += ResponseReceivedHandler;
}

修改后的LogMessageBody方法

private static async void LogMessageBody(string requestId)
{        
    var chromeDriver = TestBrowser.Browser as ChromeDriver;
    var session = chromeDriver.GetDevToolsSession();
    var networkDomain = session.GetDomain<Network>();

    var settings = new GetResponseBodyCommandSettings
    {
        RequestId = requestId
    };

    var commandResult = await networkDomain.GetResponseBody(settings);
    if (commandResult != null && !string.IsNullOrEmpty(commandResult.Body))
    {
        _log.Information($"请求ID {requestId} 的响应体:");
        _log.Information(commandResult.Body);
    }
}

修改事件处理器的参数类型

确保事件处理器的参数使用通用命名空间下的类型:

public static void ResponseReceivedHandler(object sender, OpenQA.Selenium.DevTools.Network.ResponseReceivedEventArgs e)
{
    // 原有逻辑不变
}

public static void RequestSentHandler(object sender, OpenQA.Selenium.DevTools.Network.RequestWillBeSentEventArgs e)
{
    // 原有逻辑不变
}
  1. 保留DriverManager的版本匹配策略
    你已经在使用VersionResolveStrategy.MatchingBrowser确保ChromeDriver版本与浏览器一致,继续保留这部分逻辑即可。

效果

修改后,Selenium会自动检测当前Chrome的版本,并匹配对应的DevTools协议实现,无需手动指定版本,Chrome更新后测试不会因版本不匹配而崩溃。


内容的提问来源于stack exchange,提问作者Jurn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:42:25