GitLab流水线中基于Selenium WebDriver v4.34.0的Node.js组件测试偶发不稳定问题排查求助
GitLab流水线中基于Selenium WebDriver v4.34.0的Node.js组件测试偶发不稳定问题排查求助
大家好,最近在GitLab流水线里跑基于Selenium WebDriver的Node.js组件测试时遇到了头疼的偶发不稳定问题,折腾了好一阵没找到根因,来求助各位大佬!
一、环境基础信息
我们的技术栈是Node.js + Express + Nunjucks UI,用Mocha写组件测试,依赖Selenium WebDriver v4.34.0。测试时会启动四个Docker容器:UI服务、模拟外部调用的Fake服务、LocalStack、以及Selenium Chrome节点。
之前旧版本的Selenium Chrome镜像时测试非常稳定,升级后开始出问题,目前试过两个镜像版本:
selenium/standalone-chromium:137.0@sha256:f3bde4afe83cb361025dfab27ad6ce9aa12eacfa5204ec17b06ff5d1940777a3selenium/standalone-chromium:138.0@sha256:7e431c5aeed78f06f146076f023e02f543f0c936fb619b64617915a5c0f19f34
二、具体问题表现
- 测试在本地跑完全正常,但GitLab流水线里偶发失败,每次失败的测试用例不固定,重跑失败的Job大概率能通过
- 最常见的错误是
WebDriverError: unknown error: net::ERR_CONNECTION_REFUSED,比如某个用例的before each钩子卡在页面加载步骤:1) /referrals/assign/bulk - When no row is selected "before each" hook for "Should show the error message when no rows selected": WebDriverError: unknown error: net::ERR_CONNECTION_REFUSED (Session info: chrome=137.0.7151.68) - 日志追踪发现,问题出在
selectLot函数里的await driver.get(...)调用,执行到这里就停住,没有继续后续逻辑,直接触发afterEach钩子 - 补充Selenium日志后,看到失败测试对应端口出现
LocalNode.stopTimedOutSession的记录
三、已尝试的排查动作
- 切换过137、138两个版本的Selenium Chrome镜像,问题依旧
- 怀疑是新增的CSRF验证导致,暂时跳过了大部分测试的CSRF校验,问题未解决
- 把Selenium的超时时间(implicit、pageLoad、script)都提高到8000ms,日志显示大部分时候初始化耗时远没到阈值
- 在ChromeOptions里显式指定浏览器版本为137,无效
- 重构了测试代码,拆分了测试文件和流水线任务,避免一个失败引发连锁反应,但偶发单测失败的问题仍存在
四、关键代码片段
1. WebDriver初始化函数
function getDriver(identifier = 'default', timeouts = { implicit: 8000, pageLoad: 8000, script: 8000 }) { nextPort++; const chromeOptions = new chrome.Options(); chromeOptions.addArguments([ '--no-sandbox', '--disable-gpu', '--headless=new', `--remote-debugging-port=${nextPort}`, '--verbose', ]); const capabilities = Capabilities.chrome(); capabilities.setProxy(null); const driver = new Builder() .forBrowser('chrome') .usingServer(config.get('test.selenium_server')) .withCapabilities(capabilities) .setChromeOptions(chromeOptions) .build(); driver.manage().setTimeouts(timeouts); driver.manage().deleteAllCookies(); return driver; }
2. 测试前置钩子与页面加载函数
beforeEach(async () => { driver = getDriver('open-tasks-csrf'); await selectLot(driver); }); async function selectLot(driver, lot = 'lot_1') { const uiServer = config.get('test.ui_server'); const contextPath = config.get('app.path'); await driver.get(`${uiServer}${contextPath}`); // 后续选择Lot的业务逻辑 … }
五、求助方向
现在有点摸不着头绪了,想请教各位:
- 有没有遇到过类似的GitLab流水线中Selenium偶发连接拒绝/会话超时的问题?
- 除了调整超时时间,还有哪些Docker镜像配置、Selenium参数或者测试代码的优化方向可以尝试?
- 日志里的
LocalNode.stopTimedOutSession是不是真的意味着某个步骤偶尔超时?但为什么本地环境完全不会出现这种情况?
内容来源于stack exchange
相关产品推荐
相关产品推荐

