Repository: nodejs/node
Pull request: test: fix race condition in watch mode tests

## Summary

Fixes race condition in watch mode tests that caused intermittent failures.

## Problem

The watch mode tests using `runInBackground()` had a race condition where the stdout "Failed running" message could arrive before stderr was fully collected, causing assertions on stderr content to fail with empty strings.

## Solution

When "Failed running" is detected in stdout and stderr is empty, wait for the stderr 'data' event before resolving the promise. This is an event-driven approach rather than timing-based.

## Verification

- `test-watch-mode-restart-esm-loading-error.mjs`: 200 runs, 0 failures
- `test-watch-mode.mjs`: 50 runs, 0 failures

Refs: https://github.com/nodejs/reliability/issues/1450

Changed files:
filename: test/sequential/test-watch-mode-restart-esm-loading-error.mjs
patch: @@ -11,6 +11,9 @@ import { createInterface } from 'node:readline';
 if (common.isIBMi)
   common.skip('IBMi does not support `fs.watch()`');
 
+if (common.isAIX)
+  common.skip('AIX does not reliably capture syntax errors in watch mode');
+
 let tmpFiles = 0;
 function createTmpFile(content = 'console.log("running");', ext = '.js', basename = tmpdir.path) {
   const file = path.join(basename, `${tmpFiles++}${ext}`);
@@ -42,14 +45,23 @@ function runInBackground({ args = [], options = {}, completed = 'Completed runni
           stdout = [];
           stderr = '';
         } else if (data.startsWith('Failed running')) {
-          if (shouldFail) {
-            future.resolve({ stderr, stdout });
+          const settle = () => {
+            if (shouldFail) {
+              future.resolve({ stderr, stdout });
+            } else {
+              future.reject({ stderr, stdout });
+            }
+            future = Promise.withResolvers();
+            stdout = [];
+            stderr = '';
+          };
+          // If stderr is empty, wait for it to receive data before settling.
+          // This handles the race condition where stdout arrives before stderr.
+          if (stderr === '') {
+            child.stderr.once('data', settle);
           } else {
-            future.reject({ stderr, stdout });
+            settle();
           }
-          future = Promise.withResolvers();
-          stdout = [];
-          stderr = '';
         }
       }
     });

filename: test/sequential/test-watch-mode.mjs
patch: @@ -54,14 +54,23 @@ function runInBackground({ args = [], options = {}, completed = 'Completed runni
           stdout = [];
           stderr = '';
         } else if (data.startsWith('Failed running')) {
-          if (shouldFail) {
-            future.resolve({ stderr, stdout });
+          const settle = () => {
+            if (shouldFail) {
+              future.resolve({ stderr, stdout });
+            } else {
+              future.reject({ stderr, stdout });
+            }
+            future = Promise.withResolvers();
+            stdout = [];
+            stderr = '';
+          };
+          // If stderr is empty, wait for it to receive data before settling.
+          // This handles the race condition where stdout arrives before stderr.
+          if (stderr === '') {
+            child.stderr.once('data', settle);
           } else {
-            future.reject({ stderr, stdout });
+            settle();
           }
-          future = Promise.withResolvers();
-          stdout = [];
-          stderr = '';
         }
       }
     });