diff --git a/code/addons/test/package.json b/code/addons/test/package.json index 8985ab45459c..35a4077926e1 100644 --- a/code/addons/test/package.json +++ b/code/addons/test/package.json @@ -112,6 +112,7 @@ "slash": "^5.0.0", "strip-ansi": "^7.1.0", "tinyglobby": "^0.2.10", + "tree-kill": "^1.2.2", "ts-dedent": "^2.2.0", "typescript": "^5.3.2", "vitest": "^2.1.3" diff --git a/code/addons/test/src/vitest-plugin/global-setup.ts b/code/addons/test/src/vitest-plugin/global-setup.ts index bff48208229a..ca287c105e2b 100644 --- a/code/addons/test/src/vitest-plugin/global-setup.ts +++ b/code/addons/test/src/vitest-plugin/global-setup.ts @@ -5,6 +5,8 @@ import type { GlobalSetupContext } from 'vitest/node'; import { logger } from 'storybook/internal/node-logger'; +import treeKill from 'tree-kill'; + let storybookProcess: ChildProcess | null = null; const getIsVitestStandaloneRun = () => { @@ -59,14 +61,6 @@ const startStorybookIfNotRunning = async () => { } }; -const killProcess = (process: ChildProcess) => { - return new Promise((resolve, reject) => { - process.on('close', resolve); - process.on('error', reject); - process.kill(); - }); -}; - export const setup = async ({ config }: GlobalSetupContext) => { if (config.watch && isVitestStandaloneRun) { await startStorybookIfNotRunning(); @@ -74,8 +68,19 @@ export const setup = async ({ config }: GlobalSetupContext) => { }; export const teardown = async () => { - if (storybookProcess) { - logger.verbose('Stopping Storybook process'); - await killProcess(storybookProcess); + if (!storybookProcess) { + return; } + logger.verbose('Stopping Storybook process'); + await new Promise((resolve, reject) => { + // Storybook starts multiple child processes, so we need to kill the whole tree + treeKill(storybookProcess.pid, 'SIGTERM', (error) => { + if (error) { + logger.error('Failed to stop Storybook process:'); + reject(error); + return; + } + resolve(); + }); + }); }; diff --git a/code/yarn.lock b/code/yarn.lock index e6f690cb347c..32615bb80a66 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6426,6 +6426,7 @@ __metadata: slash: "npm:^5.0.0" strip-ansi: "npm:^7.1.0" tinyglobby: "npm:^0.2.10" + tree-kill: "npm:^1.2.2" ts-dedent: "npm:^2.2.0" typescript: "npm:^5.3.2" vitest: "npm:^2.1.3" @@ -27745,7 +27746,7 @@ __metadata: languageName: node linkType: hard -"tree-kill@npm:1.2.2": +"tree-kill@npm:1.2.2, tree-kill@npm:^1.2.2": version: 1.2.2 resolution: "tree-kill@npm:1.2.2" bin: