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

Node.js下如何阻止Selenium WebDriver打开多个Firefox实例?

解决Cucumber+Selenium WebDriver打开多个Firefox实例的问题

问题详情

在Node.js环境中使用Selenium WebDriver结合Cucumber编写自动化测试时,测试功能正常,但运行单个测试会打开4个Firefox实例,仅其中一个窗口执行并完成测试,其余实例会残留,需要限制测试时打开的Firefox实例数量。

现有代码

const { Then, Given, When, After } = require('@cucumber/cucumber');
const assert = require('assert');
const { Builder, By, until, Key } = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');

let options = new firefox.Options();

const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();


Given('I am on a page that needs to be tested', async function () {
    driver.wait(until.elementLocated(By.tagName('h1')));
    await driver.get('https://www.awebsite.com');
});

When('I do the thing', async function() {
   //.....tests, etc

控制台输出

Selenium Manager binary found at /me/automated-testing/node_modules/selenium-webdriver/bin/macos/selenium-manager
Driver path: /me/.cache/selenium/geckodriver/mac-arm64/0.34.0/geckodriver
Browser path: /Applications/Firefox.app/Contents/MacOS/firefox
Driver path: /me/.cache/selenium/geckodriver/mac-arm64/0.34.0/geckodriver
Browser path: /Applications/Firefox.app/Contents/MacOS/firefox
Driver path: /me/.cache/selenium/geckodriver/mac-arm64/0.34.0/geckodriver
Browser path: /Applications/Firefox.app/Contents/MacOS/firefox
Driver path: /me/.cache/selenium/geckodriver/mac-arm64/0.34.0/geckodriver
Browser path: /Applications/Firefox.app/Contents/MacOS/firefox
.....

1 scenario (1 passed)
3 steps (3 passed)
0m04.525s (executing steps: 0m04.517s)

问题原因

当前代码在模块顶层直接创建driver实例,而Cucumber会在加载每个步骤定义时执行模块顶层代码。由于你有3个步骤(Given/When/Then)加上Cucumber内部的加载逻辑,导致模块被执行了4次,每次都创建一个新的Firefox实例,最终出现4个浏览器窗口。同时,代码未在测试结束后调用driver.quit(),导致未使用的实例残留。

解决方案

通过Cucumber的Before和After钩子管理driver的生命周期,确保每个测试场景只创建一个driver实例,并且测试结束后销毁实例:

修改后的代码

const { Then, Given, When, Before, After } = require('@cucumber/cucumber');
const assert = require('assert');
const { Builder, By, until, Key } = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');

// 定义Firefox选项(可根据需求配置)
const options = new firefox.Options();

// 在每个场景开始前创建driver实例,并绑定到上下文
Before(async function () {
    this.driver = await new Builder()
        .forBrowser('firefox')
        .setFirefoxOptions(options)
        .build();
});

// 在每个场景结束后关闭driver,避免残留实例
After(async function () {
    await this.driver.quit();
});

Given('I am on a page that needs to be tested', async function () {
    // 使用上下文里的driver,并且wait需要加await保证异步执行完成
    await this.driver.wait(until.elementLocated(By.tagName('h1')), 10000);
    await this.driver.get('https://www.awebsite.com');
});

When('I do the thing', async function() {
   // 使用this.driver执行测试操作,例如:
   // await this.driver.findElement(By.id('some-id')).click();
});

// 补充Then步骤示例
Then('I should see the expected result', async function() {
    const title = await this.driver.getTitle();
    assert.strictEqual(title, 'Expected Title');
});

关键修改点

  1. 移除全局driver初始化:不再在模块顶层创建driver,而是通过Before钩子在每个场景开始前创建实例,确保每个场景只有一个driver。
  2. 绑定driver到Cucumber上下文:将driver存储在this对象中,让所有步骤都能访问同一个实例。
  3. 添加After钩子销毁实例:测试结束后调用driver.quit(),强制关闭浏览器和驱动进程,避免残留。
  4. 修复异步等待问题:原代码中driver.wait没有加await,会导致后续代码提前执行,现在补上await确保等待完成后再执行下一步。

额外优化(可选)

如果希望所有场景共享同一个浏览器实例(而不是每个场景都重新打开),可以修改钩子作用域为BeforeAll和AfterAll:

const { BeforeAll, AfterAll } = require('@cucumber/cucumber');

let driver;

BeforeAll(async function () {
    driver = await new Builder()
        .forBrowser('firefox')
        .setFirefoxOptions(options)
        .build();
});

AfterAll(async function () {
    await driver.quit();
});

// 步骤中直接使用全局的driver变量
Given('I am on a page that needs to be tested', async function () {
    await driver.wait(until.elementLocated(By.tagName('h1')), 10000);
    await driver.get('https://www.awebsite.com');
});

注意:共享实例可能导致场景间的状态污染(比如Cookie、缓存),如果你的场景需要独立环境,建议还是使用每个场景创建一个实例的方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:27:12