diff --git a/scripts/run-vitest.mjs b/scripts/run-vitest.mjs index 193b47ef906..36914beb03a 100644 --- a/scripts/run-vitest.mjs +++ b/scripts/run-vitest.mjs @@ -7,6 +7,7 @@ import { } from "./vitest-process-group.mjs"; const TRUTHY_ENV_VALUES = new Set(["1", "true", "yes", "on"]); +const SUPPRESSED_VITEST_STDERR_PATTERNS = ["[PLUGIN_TIMINGS] Warning:"]; const require = createRequire(import.meta.url); function isTruthyEnvValue(value) { @@ -30,9 +31,42 @@ export function resolveVitestSpawnParams(env = process.env, platform = process.p return { env, detached: shouldUseDetachedVitestProcessGroup(platform), + stdio: ["inherit", "pipe", "pipe"], }; } +export function shouldSuppressVitestStderrLine(line) { + return SUPPRESSED_VITEST_STDERR_PATTERNS.some((pattern) => line.includes(pattern)); +} + +function forwardVitestOutput(stream, target, shouldSuppressLine = () => false) { + if (!stream) { + return; + } + + let buffered = ""; + stream.setEncoding("utf8"); + stream.on("data", (chunk) => { + buffered += chunk; + while (true) { + const newlineIndex = buffered.indexOf("\n"); + if (newlineIndex === -1) { + break; + } + const line = buffered.slice(0, newlineIndex + 1); + buffered = buffered.slice(newlineIndex + 1); + if (!shouldSuppressLine(line)) { + target.write(line); + } + } + }); + stream.on("end", () => { + if (buffered.length > 0 && !shouldSuppressLine(buffered)) { + target.write(buffered); + } + }); +} + function main(argv = process.argv.slice(2), env = process.env) { if (argv.length === 0) { console.error("usage: node scripts/run-vitest.mjs "); @@ -45,6 +79,8 @@ function main(argv = process.argv.slice(2), env = process.env) { ...spawnParams, }); const teardownChildCleanup = installVitestProcessGroupCleanup({ child }); + forwardVitestOutput(child.stdout, process.stdout); + forwardVitestOutput(child.stderr, process.stderr, shouldSuppressVitestStderrLine); child.on("exit", (code, signal) => { teardownChildCleanup(); diff --git a/test/scripts/run-vitest.test.ts b/test/scripts/run-vitest.test.ts index 44736d56b05..85dbed06a1e 100644 --- a/test/scripts/run-vitest.test.ts +++ b/test/scripts/run-vitest.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from "vitest"; -import { resolveVitestNodeArgs, resolveVitestSpawnParams } from "../../scripts/run-vitest.mjs"; +import { + resolveVitestNodeArgs, + resolveVitestSpawnParams, + shouldSuppressVitestStderrLine, +} from "../../scripts/run-vitest.mjs"; describe("scripts/run-vitest", () => { it("adds --no-maglev to vitest child processes by default", () => { @@ -19,10 +23,21 @@ describe("scripts/run-vitest", () => { expect(resolveVitestSpawnParams({ PATH: "/usr/bin" }, "darwin")).toEqual({ env: { PATH: "/usr/bin" }, detached: true, + stdio: ["inherit", "pipe", "pipe"], }); expect(resolveVitestSpawnParams({ PATH: "/usr/bin" }, "win32")).toEqual({ env: { PATH: "/usr/bin" }, detached: false, + stdio: ["inherit", "pipe", "pipe"], }); }); + + it("suppresses rolldown plugin timing noise while keeping other stderr intact", () => { + expect( + shouldSuppressVitestStderrLine( + "\u001b[33m[PLUGIN_TIMINGS] Warning:\u001b[0m plugin `foo` was slow\n", + ), + ).toBe(true); + expect(shouldSuppressVitestStderrLine("real failure output\n")).toBe(false); + }); });