diff --git a/scripts/prepush-ci.sh b/scripts/prepush-ci.sh index 2f3b7b24a7..8fba0b46d4 100644 --- a/scripts/prepush-ci.sh +++ b/scripts/prepush-ci.sh @@ -56,7 +56,7 @@ run_linux_ci_mirror() { run_step pnpm lint:ui:no-raw-window-open run_protocol_ci_mirror run_step pnpm canvas:a2ui:bundle - run_step pnpm vitest run --config vitest.extensions.config.ts --maxWorkers=1 + run_step pnpm exec vitest run --config vitest.extensions.config.ts --maxWorkers=1 run_step env CI=true pnpm exec vitest run --config vitest.unit.config.ts --maxWorkers=1 log_step "OPENCLAW_VITEST_MAX_WORKERS=${OPENCLAW_VITEST_MAX_WORKERS:-1} NODE_OPTIONS=${NODE_OPTIONS:---max-old-space-size=6144} pnpm test" diff --git a/scripts/test-force.ts b/scripts/test-force.ts index 9b907263d7..0c55342313 100755 --- a/scripts/test-force.ts +++ b/scripts/test-force.ts @@ -28,7 +28,7 @@ function runTests() { const isolatedLock = process.env.OPENCLAW_GATEWAY_LOCK ?? path.join(os.tmpdir(), `openclaw-gateway.lock.test.${Date.now()}`); - const result = spawnSync("pnpm", ["vitest", "run"], { + const result = spawnSync("pnpm", ["exec", "vitest", "run"], { stdio: "inherit", env: { ...process.env, diff --git a/scripts/test-report-utils.mjs b/scripts/test-report-utils.mjs index af4c5d6dbd..e97c4fa38a 100644 --- a/scripts/test-report-utils.mjs +++ b/scripts/test-report-utils.mjs @@ -43,7 +43,16 @@ export function runVitestJsonReport({ if (!(reportPath && fs.existsSync(resolvedReportPath))) { const run = spawnSync( "pnpm", - ["vitest", "run", "--config", config, "--reporter=json", "--outputFile", resolvedReportPath], + [ + "exec", + "vitest", + "run", + "--config", + config, + "--reporter=json", + "--outputFile", + resolvedReportPath, + ], { stdio: "inherit", env: process.env, diff --git a/test/scripts/test-report-utils.test.ts b/test/scripts/test-report-utils.test.ts index 55537a6920..a42817750d 100644 --- a/test/scripts/test-report-utils.test.ts +++ b/test/scripts/test-report-utils.test.ts @@ -1,13 +1,21 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { collectVitestFileDurations, normalizeTrackedRepoPath, tryReadJsonFile, } from "../../scripts/test-report-utils.mjs"; +const { spawnSyncMock } = vi.hoisted(() => ({ + spawnSyncMock: vi.fn(), +})); + +vi.mock("node:child_process", () => ({ + spawnSync: spawnSyncMock, +})); + describe("scripts/test-report-utils normalizeTrackedRepoPath", () => { it("normalizes repo-local absolute paths to repo-relative slash paths", () => { const absoluteFile = path.join(process.cwd(), "src", "tools", "example.test.ts"); @@ -69,3 +77,41 @@ describe("scripts/test-report-utils tryReadJsonFile", () => { } }); }); + +describe("scripts/test-report-utils runVitestJsonReport", () => { + beforeEach(() => { + vi.resetModules(); + spawnSyncMock.mockReset(); + }); + + it("launches Vitest through pnpm exec", async () => { + spawnSyncMock.mockReturnValue({ status: 0 }); + const reportPath = path.join(os.tmpdir(), `openclaw-vitest-json-${Date.now()}.json`); + const { runVitestJsonReport } = await import("../../scripts/test-report-utils.mjs"); + + expect( + runVitestJsonReport({ + config: "vitest.unit.config.ts", + reportPath, + }), + ).toBe(reportPath); + + expect(spawnSyncMock).toHaveBeenCalledWith( + "pnpm", + [ + "exec", + "vitest", + "run", + "--config", + "vitest.unit.config.ts", + "--reporter=json", + "--outputFile", + reportPath, + ], + expect.objectContaining({ + stdio: "inherit", + env: process.env, + }), + ); + }); +});