已设置120秒commandTimeout,为何远程WebDriver请求仍60秒超时?
问题描述
在.NET平台使用Selenium WebDriver,通过BrowserStack测试Android端Chrome浏览器的Web应用时,明明已给驱动传入2分钟的commandTimeout,但偶尔仍会触发以下错误:
OneTimeSetUp: OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://hub-cloud.browserstack.com/wd/hub/session timed out after 60 seconds
代码示例:
new AndroidDriver( myUrl, myDriverOptions, commandTimeout: TimeSpan.FromMinutes(2) )
已知未手动设置的其他超时项默认值:
- AsynchronousJavaScript - 默认值: 0:30
- ImplicitWait - 默认值: 0:00
- PageLoad - 默认值: 3:20
堆栈跟踪片段:
OneTimeSetUp: OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://hub-cloud.browserstack.com/wd/hub/session timed out after 60 seconds.
----> System.Threading.Tasks.TaskCanceledException : The request was canceled due to the configured HttpClient.Timeout of 60 seconds elapsing.
----> System.TimeoutException : The operation was canceled.
----> 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.
一、超时来源:底层HttpClient的默认60秒限制
你设置的commandTimeout是Selenium层面的命令执行超时,但Selenium和BrowserStack Hub通信的底层HttpClient有自己的默认60秒超时——这是两个完全独立的层级:
commandTimeout:控制Selenium等待WebDriver命令执行完成的最长时间HttpClient.Timeout:控制整个HTTP请求(建立连接、发送请求、接收响应)的总时长
当BrowserStack创建Android会话较慢时(比如设备队列排队、环境初始化耗时),哪怕Selenium允许等待2分钟,底层HttpClient会先触发60秒超时,直接抛出错误。
二、解决办法
1. 手动配置HttpClient超时
在初始化AndroidDriver前,自定义HttpClient并将超时设置为与commandTimeout一致的时长(比如2分钟),再传给驱动(Selenium 4+支持此方式):
var httpClient = new HttpClient(new HttpClientHandler()) { Timeout = TimeSpan.FromMinutes(2) }; var driver = new AndroidDriver( new Uri(myUrl), myDriverOptions, httpClient, TimeSpan.FromMinutes(2) );
2. 优化BrowserStack设备配置
- 在
myDriverOptions中指定具体的Android设备型号、Chrome版本,减少BrowserStack匹配设备的耗时(例如添加deviceName、browserVersion参数) - 确认你的BrowserStack套餐是否存在会话创建的超时限制,基础套餐可能队列等待时长更严格
3. 添加重试逻辑
针对偶发的超时问题,给会话创建逻辑添加重试机制,比如使用Polly库实现指数退避重试:
var retryPolicy = Policy .Handle<WebDriverException>(ex => ex.Message.Contains("timed out after 60 seconds")) .WaitAndRetry(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); var driver = retryPolicy.Execute(() => new AndroidDriver( new Uri(myUrl), myDriverOptions, TimeSpan.FromMinutes(2) ));
内容的提问来源于stack exchange,提问作者Marco Eckstein

