@@ -460,6 +460,9 @@ function runTestFile(path, filesWatcher, opts) { |
460 | 460 | finished(child.stdout, { __proto__: null, signal: t.signal }), |
461 | 461 | ]); |
462 | 462 |
|
| 463 | + // Close readline interface to prevent memory leak |
| 464 | + rl.close(); |
| 465 | + |
463 | 466 | if (watchMode) { |
464 | 467 | filesWatcher.runningProcesses.delete(path); |
465 | 468 | filesWatcher.runningSubtests.delete(path); |
@@ -522,7 +525,7 @@ function watchFiles(testFiles, opts) { |
522 | 525 | } |
523 | 526 |
|
524 | 527 | // Watch for changes in current filtered files |
525 | | - watcher.on('changed', ({ owners, eventType }) => { |
| 528 | + const onChanged = ({ owners, eventType }) => { |
526 | 529 | if (!opts.hasFiles && (eventType === 'rename' || eventType === 'change')) { |
527 | 530 | const updatedTestFiles = createTestFileList(opts.globPatterns, opts.cwd); |
528 | 531 | const newFileName = ArrayPrototypeFind(updatedTestFiles, (x) => !ArrayPrototypeIncludes(testFiles, x)); |
@@ -563,19 +566,29 @@ function watchFiles(testFiles, opts) { |
563 | 566 | triggerUncaughtException(error, true /* fromPromise */); |
564 | 567 | })); |
565 | 568 | } |
566 | | - }); |
| 569 | + }; |
| 570 | + |
| 571 | + watcher.on('changed', onChanged); |
| 572 | + |
| 573 | + // Cleanup function to remove event listener and prevent memory leak |
| 574 | + const cleanup = () => { |
| 575 | + watcher.removeListener('changed', onChanged); |
| 576 | + opts.root.harness.watching = false; |
| 577 | + opts.root.postRun(); |
| 578 | + }; |
| 579 | + |
567 | 580 | if (opts.signal) { |
568 | 581 | kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation; |
569 | 582 | opts.signal.addEventListener( |
570 | 583 | 'abort', |
571 | | - () => { |
572 | | - opts.root.harness.watching = false; |
573 | | - opts.root.postRun(); |
574 | | - }, |
| 584 | + cleanup, |
575 | 585 | { __proto__: null, once: true, [kResistStopPropagation]: true }, |
576 | 586 | ); |
577 | 587 | } |
578 | 588 |
|
| 589 | + // Expose cleanup method for proper resource management |
| 590 | + filesWatcher.cleanup = cleanup; |
| 591 | + |
579 | 592 | return filesWatcher; |
580 | 593 | } |
581 | 594 |
|
|