···44444545const process_ = process
46464747+// Polling interval of the file watcher in spawned watch-mode instances. The
4848+// watcher-ready probe derives its timing from it: each probe state must
4949+// outlive a full poll cycle, or the poller can keep sampling the state that
5050+// matches its baseline and never observe a difference.
5151+const WATCH_POLL_INTERVAL = 100
5252+4753export function createConsole({ tty, std }: { tty?: boolean; std?: 'inherit' } = {}) {
4854 const stdout = new Writable({
4955 write(chunk, __, callback) {
···239245 // misses change events, so enforce polling for consistency
240246 // https://github.com/vitejs/vite/blob/b723a753ced0667470e72b4853ecda27b17f546a/playground/vitestSetup.ts#L211
241247 usePolling: true,
242242- interval: 100,
248248+ interval: WATCH_POLL_INTERVAL,
243249 ...viteConfig.server?.watch,
244250 },
245251 ...viteConfig?.server,
···336342// verify end-to-end: keep cycling a probe file in the root until the watcher
337343// reports it. The probe is recreated rather than rewritten because a creation
338344// folded into the initial scan of the file AND its directory leaves nothing to
339339-// rescan; deleting and recreating it bumps the directory mtime every cycle, so
340340-// a live directory poller always sees a difference, and any probe event
341341-// (`add`, `change` or `unlink`) proves delivery.
345345+// rescan; alternating present/absent guarantees the current state differs from
346346+// whichever state the poller's baseline captured, and any probe event (`add`,
347347+// `change` or `unlink`) proves delivery. Each state is held for multiple poll
348348+// intervals: on a loaded runner, a cycle as fast as the poll interval aliases
349349+// with it — every rescan can land when the probe is back in the state matching
350350+// the poller's baseline, and no event ever fires.
342351//
343352// The scan can also surface writes made by the PREVIOUS test (an `afterEach`
344353// restoring a fixture right before this instance started) as fresh change
···392401 }
393402 watcher.on('all', onWatcherEvent)
394403 try {
404404+ const holdProbeState = async () => {
405405+ const stateEnd = Date.now() + WATCH_POLL_INTERVAL * 2.5
406406+ while (Date.now() < stateEnd) {
407407+ if (probeSeen) {
408408+ return
409409+ }
410410+ await new Promise(resolve => setTimeout(resolve, 25))
411411+ }
412412+ }
395413 while (true) {
396414 if (probeSeen) {
397415 break
···403421 )
404422 }
405423 fs.writeFileSync(probe, `${Date.now()}`, 'utf-8')
406406- await new Promise(resolve => setTimeout(resolve, 50))
424424+ await holdProbeState()
407425 if (probeSeen) {
408426 break
409427 }
410428 fs.rmSync(probe, { force: true })
411411- await new Promise(resolve => setTimeout(resolve, 50))
429429+ await holdProbeState()
412430 }
413431414432 while (Date.now() - lastEventAt < 200 && Date.now() < deadline) {