diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/snapshots.toml b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/snapshots.toml index b614ce1363..2ef1b1e254 100644 --- a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/snapshots.toml +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/snapshots.toml @@ -5,7 +5,7 @@ steps = [ { argv = ["vp", "install", "-g", "./long-time-install-package"], continue-on-failure = true }, { argv = ["long-time-install-package"], continue-on-failure = true }, # snapshot = false: the killed install's partial screen is timing-dependent - # (which spinner frame was live at the 100ms SIGKILL) and ConPTY renders a + # (which spinner frame was live when the kill landed) and ConPTY renders a # trailing blank line Unix does not; the meaningful outcome is asserted by # the check-stale-packages step that follows. { argv = ["node", "test-reinstall-interrupt.js"], comment = "Reinstall but interrupt", snapshot = false, continue-on-failure = true }, diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/test-reinstall-interrupt.js b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/test-reinstall-interrupt.js index 76f2c3fb31..e48ab05f42 100644 --- a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/test-reinstall-interrupt.js +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/env_install_interrupt/test-reinstall-interrupt.js @@ -1,15 +1,42 @@ const { spawn } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +const scopeDir = path.join(process.env.VP_HOME, 'packages', '@scope'); +const before = new Set(fs.readdirSync(scopeDir)); const child = spawn('vp', ['install', '-g', './long-time-install-package'], { stdio: 'inherit', }); -setTimeout(() => { +// A fixed kill delay races vp's startup: on slow runners it can fire before +// the reinstall creates its install dir, leaving nothing stale. Kill as soon +// as the new dir appears; the package's 200ms postinstall keeps the install +// running well past that point. +const poll = setInterval(() => { + let entries; + try { + entries = fs.readdirSync(scopeDir); + } catch { + return; + } + if (entries.some((name) => !before.has(name))) { + clearInterval(poll); + child.kill('SIGKILL'); + } +}, 10); + +// Bound the wait so a reinstall that dies before creating the dir cannot +// hang the case. +const fallback = setTimeout(() => { + clearInterval(poll); if (!child.killed) { child.kill('SIGKILL'); } -}, 100); +}, 10_000); child.on('close', (code) => { + clearInterval(poll); + clearTimeout(fallback); process.exit(code); });