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

Azure DevOps流水线Selenium C#测试套件WebDriver异常求助

Selenium C# 在Azure DevOps流水线中执行PDF打印命令超时问题

问题描述

近15天,基于Selenium C#的测试套件执行PDF打印命令时出现异常:本地及测试VM上手动通过Visual Studio运行正常,但在Azure DevOps流水线中执行失败。TearDown阶段触发OpenQA.Selenium.WebDriverException,提示向远程WebDriver服务器发送的HTTP请求超时60秒,嵌套异常包含System.Threading.Tasks.TaskCanceledException、System.IO.IOException及System.Net.Sockets.SocketException。已尝试升级/降级ChromeDriver版本、添加--no-sandbox和--no-gpu参数、延长超时时间、更新Selenium.Support及Selenium.WebDriver版本等方案,均未解决。

异常详情

TearDown : OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:54995/session/36a5bcb819c93c78746cf5eb6ca81796/goog/cdp/execute timed out after 60 seconds.
----> System.Threading.Tasks.TaskCanceledException : The operation was canceled.
----> System.IO.IOException : Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
----> System.Net.Sockets.SocketException : The I/O operation has been aborted because of either a thread exit or an application request.

堆栈跟踪:

--TearDown
at OpenQA.Selenium.Remote.HttpCommandExecutor.ExecuteAsync(Command commandToExecute)
at OpenQA.Selenium.Remote.DriverServiceCommandExecutor.ExecuteAsync(Command commandToExecute)
at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters) at OpenQA.Selenium.WebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Chromium.ChromiumDriver.ExecuteCdpCommand(String commandName, Dictionary`2 commandParameters)

相关代码

public static byte[] ConvertHtmlToPdf(string html)
{
    int t = 0;
    int timeout = 180;
    byte[] pdf = new byte[] { };

    DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
    string baseDir = di.Parent.Parent.Parent.FullName;
    string reportDir = Path.Combine(baseDir, "Report", BaseFixture.timestamp);
    var filePath = Path.Combine(reportDir, $"{Guid.NewGuid()}.html");
    File.WriteAllTextAsync(filePath, html);

    var driverOptions = new ChromeOptions();
    //In headless mode, PDF writing is enabled by default, hence switching to headless mode
    driverOptions.AddArgument("headless");
    using var driver = new ChromeDriver(driverOptions);
    driver.Navigate().GoToUrl(filePath);

    // Output a PDF of the first page in A4 size at 90% scale
    var printOptions = new Dictionary<string, object>
    {
        { "paperWidth", 210 / 5 },
        { "paperHeight", 150 / 5 },
        { "scale", 0.9 },
        { "pageRanges", "1-2" },
        { "preferCSSPageSize", true }
    };
    //while (t < timeout)
    //{
      //  Thread.Sleep(60000);
      //  t = t + 60;
        var printOutput = driver.ExecuteCdpCommand("Page.printToPDF", printOptions) as Dictionary<string, object>;
        pdf = Convert.FromBase64String(printOutput["data"] as string);
    //}
    File.Delete(filePath);
    return pdf;
}

解决方案建议

  1. 修复异步文件写入的同步等待问题
    代码中使用File.WriteAllTextAsync(filePath, html)但未等待完成,直接启动ChromeDriver读取文件,可能导致文件未完全写入就被访问,引发后续加载或打印超时。可改为同步方法:

    File.WriteAllText(filePath, html);
    

    或修改方法为异步并添加等待:

    // 方法签名改为async Task<byte[]>
    await File.WriteAllTextAsync(filePath, html);
    
  2. 优化ChromeDriver初始化及超时配置

    • 为ChromeDriver设置更长的命令超时时间,默认60秒可能不足以在流水线环境完成PDF渲染:
      var driverService = ChromeDriverService.CreateDefaultService();
      driverService.Start();
      var driver = new ChromeDriver(driverService, driverOptions, TimeSpan.FromMinutes(5));
      
    • 添加适配流水线环境的Chrome参数:
      driverOptions.AddArgument("--no-sandbox");
      driverOptions.AddArgument("--no-gpu");
      driverOptions.AddArgument("--disable-dev-shm-usage"); // 解决共享内存不足问题
      driverOptions.AddArgument("--disable-extensions");
      driverOptions.AddArgument("--disable-plugins");
      
  3. 确保HTML页面完全加载后再执行打印
    在调用ExecuteCdpCommand前,等待页面加载完成:

    new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(d => 
        ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
    
  4. 检查Azure DevOps流水线环境资源

    • 确保流水线代理有足够的CPU和内存资源,PDF渲染对资源要求较高,资源不足会导致超时。
    • 确认流水线中Chrome浏览器版本与ChromeDriver版本严格匹配,版本不一致可能引发兼容性问题。
  5. 简化PDF打印参数
    先使用基础配置排查问题,排除复杂参数导致的渲染耗时:

    var printOptions = new Dictionary<string, object>
    {
        { "scale", 0.9 },
        { "pageRanges", "1" },
        { "preferCSSPageSize", false }
    };
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:40:23