dequelabs/axe-core

Memory leak in ACT test runner: `process` `exit` listeners accumulate across test suites

Open

#5018 opened on Feb 27, 2026

View on GitHub
 (2 comments) (0 reactions) (1 assignee)JavaScript (5,457 stars) (783 forks)batch import
good first issue

Description

Summary

Running the ACT rules test suite triggers Node's MaxListenersExceededWarning because each spec file leaves a dangling exit listener on process that is never cleaned up.

Call chain

Each of the ~35 spec files calls act-runner.js, which in its before() hook calls getWebdriver() (act-runner.js#L32):

driver = getWebdriver();

getWebdriver() calls Builder.build(), which spawns a ChromeDriver subprocess via selenium-webdriver's internal exec() function. On every spawn, exec() registers a cleanup listener (selenium-webdriver/io/exec.js#L134):

process.once('exit', onProcessExit)

This listener is designed to self-clean when the child process exits (exec.js#L139):

process.removeListener('exit', onProcessExit)

Root cause

The after() hook tears down the driver with driver.close() (act-runner.js#L50):

after(async () => {
  await driver.close();
  await new Promise(r => server.close(r));
});

driver.close() closes the browser window but does not stop the ChromeDriver service process. Because the subprocess never exits during the test run, the onProcessExit listener on process is never removed. With ~35 spec files each creating their own driver, 35 dangling exit listeners accumulate on process.

Fix

Change driver.close() to driver.quit() at act-runner.js#L50:

- await driver.close();
+ await driver.quit();

driver.quit() sends DELETE /session, which terminates the ChromeDriver process. That causes proc.once('exit', ...) in exec.js to fire, which calls process.removeListener('exit', onProcessExit) and properly cleans up the listener. This aligns with the best practice from Selenium itself for managing sessions.

Extra Notes

Any PRs submitting to fix this, need to orchestrate a setup (probably a quick matrix) that runs this test suite 10 times. To prove it is not flaky anymore from this leak.

Contributor guide