diff --git a/apps/cli/src/__tests__/helpers/fake-npm.ts b/apps/cli/src/__tests__/helpers/fake-npm.ts index 0a622d173..b7c94bebc 100644 --- a/apps/cli/src/__tests__/helpers/fake-npm.ts +++ b/apps/cli/src/__tests__/helpers/fake-npm.ts @@ -53,6 +53,14 @@ if (process.env.BB_TEST_NPM_INSTALL === "fail") { process.exit(1); } +if (process.env.BB_TEST_NPM_INSTALL === "fail-noisy-stdout") { + process.stderr.write("npm error code EPERM\\nnpm error syscall open\\n"); + for (let line = 1; line <= 9; line += 1) { + process.stdout.write("progress line " + line + "\\n"); + } + process.exit(1); +} + // npm treats NODE_ENV=production as omit=dev; a command-line --include=dev // outranks it. BB_TEST_NPM_ALWAYS_OMIT_DEV forces the omission to stand in for // an install that silently drops packages. diff --git a/apps/cli/src/__tests__/plugin-new.test.ts b/apps/cli/src/__tests__/plugin-new.test.ts index e2bfc7281..abb8fb883 100644 --- a/apps/cli/src/__tests__/plugin-new.test.ts +++ b/apps/cli/src/__tests__/plugin-new.test.ts @@ -214,6 +214,14 @@ describe.sequential("bb plugin new dependency install", () => { expect(warnings).toContain("Your cache folder contains root-owned files"); }); + it("keeps stderr details when a failed install also writes stdout", async () => { + vi.stubEnv("BB_TEST_NPM_INSTALL", "fail-noisy-stdout"); + + await runPluginNew(["npm-noisy"]); + + expect(warned.join("\n")).toContain("npm error code EPERM"); + }); + it("falls back to the manual step when npm is not on PATH", async () => { vi.stubEnv("PATH", join(workDir, "empty-bin"));