From 1b1853f0cc0ce943c2d46c7fa02bf5a4ed2bbb53 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 10 Apr 2026 14:20:11 +0100 Subject: [PATCH] test: restore moved Vitest config discovery --- scripts/test-projects.mjs | 3 + src/docker-build-cache.test.ts | 2 +- test/vitest-scoped-config.test.ts | 94 +++++++++++++++------------- test/vitest-unit-fast-config.test.ts | 12 ++++ test/vitest/vitest.pattern-file.ts | 45 +++++++++++-- test/vitest/vitest.scoped-config.ts | 6 +- test/vitest/vitest.shared.config.ts | 4 +- 7 files changed, 114 insertions(+), 52 deletions(-) diff --git a/scripts/test-projects.mjs b/scripts/test-projects.mjs index 8dfd16082cd..3a4b0567279 100644 --- a/scripts/test-projects.mjs +++ b/scripts/test-projects.mjs @@ -218,6 +218,9 @@ async function main() { `[test] running ${parallelSpecs.length} Vitest shards with parallelism ${concurrency}`, ); const parallelExitCode = await runVitestSpecsParallel(parallelSpecs, concurrency); + console.error( + `[test] completed ${parallelSpecs.length} Vitest shards; Vitest summaries above are per-shard, not aggregate totals.`, + ); releaseLockOnce(); if (parallelExitCode !== 0) { process.exit(parallelExitCode); diff --git a/src/docker-build-cache.test.ts b/src/docker-build-cache.test.ts index 6eeea1e73c5..1fede0ae237 100644 --- a/src/docker-build-cache.test.ts +++ b/src/docker-build-cache.test.ts @@ -114,7 +114,7 @@ describe("docker build cache layout", () => { /^COPY(?:\s+--chown=\S+)?\s+scripts\/postinstall-bundled-plugins\.mjs scripts\/npm-runner\.mjs scripts\/windows-cmd-helpers\.mjs \.\/scripts\/$/m, ); expectPatternAfterInstall( - /^COPY(?:\s+--chown=\S+)?\s+tsconfig\.json tsconfig\.plugin-sdk\.dts\.json tsdown\.config\.ts vitest\.config\.ts vitest\.e2e\.config\.ts vitest\.performance-config\.ts vitest\.shared\.config\.ts vitest\.system-load\.ts vitest\.bundled-plugin-paths\.ts openclaw\.mjs \.\/$/m, + /^COPY(?:\s+--chown=\S+)?\s+tsconfig\.json tsconfig\.plugin-sdk\.dts\.json tsdown\.config\.ts vitest\.config\.ts openclaw\.mjs \.\/$/m, ); expectPatternAfterInstall(/^COPY(?:\s+--chown=\S+)?\s+src \.\/src$/m); expectPatternAfterInstall(/^COPY(?:\s+--chown=\S+)?\s+test \.\/test$/m); diff --git a/test/vitest-scoped-config.test.ts b/test/vitest-scoped-config.test.ts index 9abd65cb15d..c0b74c0d085 100644 --- a/test/vitest-scoped-config.test.ts +++ b/test/vitest-scoped-config.test.ts @@ -79,6 +79,14 @@ describe("resolveVitestIsolation", () => { expect(resolveVitestIsolation({ OPENCLAW_TEST_NO_ISOLATE: "0" })).toBe(false); expect(resolveVitestIsolation({ OPENCLAW_TEST_NO_ISOLATE: "false" })).toBe(false); }); + + it("resolves scoped discovery dirs from the repo root after config relocation", () => { + const config = createExtensionMatrixVitestConfig({}); + + expect(config.root).toBe(process.cwd()); + expect(config.test?.dir).toBe(path.join(process.cwd(), "extensions")); + expect(config.test?.include).toContain("matrix/**/*.test.ts"); + }); }); describe("createScopedVitestConfig", () => { @@ -94,7 +102,7 @@ describe("createScopedVitestConfig", () => { dir: "src", env: {}, }); - expect(config.test?.dir).toBe("src"); + expect(config.test?.dir).toBe(path.join(process.cwd(), "src")); expect(config.test?.include).toEqual(["example.test.ts"]); }); @@ -310,7 +318,7 @@ describe("scoped vitest configs", () => { }); it("normalizes extension channel include patterns relative to the scoped dir", () => { - expect(defaultExtensionChannelsConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionChannelsConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionChannelsConfig.test?.include).toEqual( expect.arrayContaining([ "discord/**/*.test.ts", @@ -323,88 +331,90 @@ describe("scoped vitest configs", () => { }); it("normalizes bluebubbles extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionBlueBubblesConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionBlueBubblesConfig.test?.dir).toBe( + path.join(process.cwd(), "extensions"), + ); expect(defaultExtensionBlueBubblesConfig.test?.include).toEqual(["bluebubbles/**/*.test.ts"]); }); it("normalizes acpx extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionAcpxConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionAcpxConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionAcpxConfig.test?.include).toEqual(["acpx/**/*.test.ts"]); }); it("normalizes diffs extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionDiffsConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionDiffsConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionDiffsConfig.test?.include).toEqual(["diffs/**/*.test.ts"]); }); it("normalizes feishu extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionFeishuConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionFeishuConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionFeishuConfig.test?.include).toEqual(["feishu/**/*.test.ts"]); }); it("normalizes irc extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionIrcConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionIrcConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionIrcConfig.test?.include).toEqual(["irc/**/*.test.ts"]); }); it("normalizes extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionsConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionsConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionsConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes extension provider include patterns relative to the scoped dir", () => { - expect(defaultExtensionProvidersConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionProvidersConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionProvidersConfig.test?.include).toEqual( expect.arrayContaining(["openai/**/*.test.ts", "xai/**/*.test.ts", "google/**/*.test.ts"]), ); }); it("normalizes extension messaging include patterns relative to the scoped dir", () => { - expect(defaultExtensionMessagingConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMessagingConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionMessagingConfig.test?.include).toEqual( expect.arrayContaining(["googlechat/**/*.test.ts"]), ); }); it("normalizes matrix extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionMatrixConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMatrixConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionMatrixConfig.test?.include).toEqual(["matrix/**/*.test.ts"]); }); it("normalizes mattermost extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionMattermostConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMattermostConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionMattermostConfig.test?.include).toEqual(["mattermost/**/*.test.ts"]); }); it("normalizes msteams extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionMsTeamsConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMsTeamsConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionMsTeamsConfig.test?.include).toEqual(["msteams/**/*.test.ts"]); }); it("normalizes telegram extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionTelegramConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionTelegramConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionTelegramConfig.test?.include).toEqual(["telegram/**/*.test.ts"]); }); it("normalizes whatsapp extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionWhatsAppConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionWhatsAppConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionWhatsAppConfig.test?.include).toEqual(["whatsapp/**/*.test.ts"]); }); it("normalizes zalo extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionZaloConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionZaloConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionZaloConfig.test?.include).toEqual( expect.arrayContaining(["zalo/**/*.test.ts", "zalouser/**/*.test.ts"]), ); }); it("normalizes voice-call extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionVoiceCallConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionVoiceCallConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionVoiceCallConfig.test?.include).toEqual(["voice-call/**/*.test.ts"]); }); it("normalizes memory extension include patterns relative to the scoped dir", () => { - expect(defaultExtensionMemoryConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMemoryConfig.test?.dir).toBe(path.join(process.cwd(), "extensions")); expect(defaultExtensionMemoryConfig.test?.include).toEqual( expect.arrayContaining(["memory-core/**/*.test.ts", "memory-lancedb/**/*.test.ts"]), ); @@ -490,12 +500,12 @@ describe("scoped vitest configs", () => { }); it("normalizes secrets include patterns relative to the scoped dir", () => { - expect(defaultSecretsConfig.test?.dir).toBe("src/secrets"); + expect(defaultSecretsConfig.test?.dir).toBe(path.join(process.cwd(), "src", "secrets")); expect(defaultSecretsConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes hooks include patterns relative to the scoped dir", () => { - expect(defaultHooksConfig.test?.dir).toBe("src/hooks"); + expect(defaultHooksConfig.test?.dir).toBe(path.join(process.cwd(), "src", "hooks")); expect(defaultHooksConfig.test?.include).toEqual(["**/*.test.ts"]); }); @@ -546,7 +556,7 @@ describe("scoped vitest configs", () => { }); it("normalizes gateway include patterns relative to the scoped dir", () => { - expect(defaultGatewayConfig.test?.dir).toBe("src/gateway"); + expect(defaultGatewayConfig.test?.dir).toBe(path.join(process.cwd(), "src", "gateway")); expect(defaultGatewayConfig.test?.include).toEqual(["**/*.test.ts"]); expect(defaultGatewayConfig.test?.exclude).toContain("gateway.test.ts"); expect(defaultGatewayConfig.test?.exclude).toContain( @@ -556,68 +566,68 @@ describe("scoped vitest configs", () => { }); it("normalizes infra include patterns relative to the scoped dir", () => { - expect(defaultInfraConfig.test?.dir).toBe("src"); + expect(defaultInfraConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultInfraConfig.test?.include).toEqual(["infra/**/*.test.ts"]); }); it("normalizes runtime config include patterns relative to the scoped dir", () => { - expect(defaultRuntimeConfig.test?.dir).toBe("src"); + expect(defaultRuntimeConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultRuntimeConfig.test?.include).toEqual(["config/**/*.test.ts"]); }); it("normalizes cron include patterns relative to the scoped dir", () => { - expect(defaultCronConfig.test?.dir).toBe("src"); + expect(defaultCronConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultCronConfig.test?.include).toEqual(["cron/**/*.test.ts"]); }); it("normalizes daemon include patterns relative to the scoped dir", () => { - expect(defaultDaemonConfig.test?.dir).toBe("src"); + expect(defaultDaemonConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultDaemonConfig.test?.include).toEqual(["daemon/**/*.test.ts"]); }); it("normalizes media include patterns relative to the scoped dir", () => { - expect(defaultMediaConfig.test?.dir).toBe("src"); + expect(defaultMediaConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultMediaConfig.test?.include).toEqual(["media/**/*.test.ts"]); }); it("normalizes logging include patterns relative to the scoped dir", () => { - expect(defaultLoggingConfig.test?.dir).toBe("src"); + expect(defaultLoggingConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultLoggingConfig.test?.include).toEqual(["logging/**/*.test.ts"]); }); it("normalizes plugin-sdk include patterns relative to the scoped dir", () => { - expect(defaultPluginSdkConfig.test?.dir).toBe("src"); + expect(defaultPluginSdkConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultPluginSdkConfig.test?.include).toEqual(["plugin-sdk/**/*.test.ts"]); }); it("normalizes shared-core include patterns relative to the scoped dir", () => { - expect(defaultSharedCoreConfig.test?.dir).toBe("src"); + expect(defaultSharedCoreConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultSharedCoreConfig.test?.include).toEqual(["shared/**/*.test.ts"]); expect(defaultSharedCoreConfig.test?.setupFiles).toEqual(["test/setup.ts"]); }); it("normalizes process include patterns relative to the scoped dir", () => { - expect(defaultProcessConfig.test?.dir).toBe("src"); + expect(defaultProcessConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultProcessConfig.test?.include).toEqual(["process/**/*.test.ts"]); }); it("normalizes tasks include patterns relative to the scoped dir", () => { - expect(defaultTasksConfig.test?.dir).toBe("src"); + expect(defaultTasksConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultTasksConfig.test?.include).toEqual(["tasks/**/*.test.ts"]); }); it("normalizes wizard include patterns relative to the scoped dir", () => { - expect(defaultWizardConfig.test?.dir).toBe("src"); + expect(defaultWizardConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultWizardConfig.test?.include).toEqual(["wizard/**/*.test.ts"]); }); it("normalizes tui include patterns relative to the scoped dir", () => { - expect(defaultTuiConfig.test?.dir).toBe("src"); + expect(defaultTuiConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultTuiConfig.test?.include).toEqual(["tui/**/*.test.ts"]); }); it("normalizes media-understanding include patterns relative to the scoped dir", () => { - expect(defaultMediaUnderstandingConfig.test?.dir).toBe("src"); + expect(defaultMediaUnderstandingConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultMediaUnderstandingConfig.test?.include).toEqual([ "media-understanding/**/*.test.ts", ]); @@ -634,43 +644,43 @@ describe("scoped vitest configs", () => { }); it("normalizes acp include patterns relative to the scoped dir", () => { - expect(defaultAcpConfig.test?.dir).toBe("src/acp"); + expect(defaultAcpConfig.test?.dir).toBe(path.join(process.cwd(), "src", "acp")); expect(defaultAcpConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes cli include patterns relative to the scoped dir", () => { - expect(defaultCliConfig.test?.dir).toBe("src/cli"); + expect(defaultCliConfig.test?.dir).toBe(path.join(process.cwd(), "src", "cli")); expect(defaultCliConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes commands include patterns relative to the scoped dir", () => { - expect(defaultCommandsConfig.test?.dir).toBe("src/commands"); + expect(defaultCommandsConfig.test?.dir).toBe(path.join(process.cwd(), "src", "commands")); expect(defaultCommandsConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes auto-reply include patterns relative to the scoped dir", () => { - expect(defaultAutoReplyConfig.test?.dir).toBe("src/auto-reply"); + expect(defaultAutoReplyConfig.test?.dir).toBe(path.join(process.cwd(), "src", "auto-reply")); expect(defaultAutoReplyConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes agents include patterns relative to the scoped dir", () => { - expect(defaultAgentsConfig.test?.dir).toBe("src/agents"); + expect(defaultAgentsConfig.test?.dir).toBe(path.join(process.cwd(), "src", "agents")); expect(defaultAgentsConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes plugins include patterns relative to the scoped dir", () => { - expect(defaultPluginsConfig.test?.dir).toBe("src/plugins"); + expect(defaultPluginsConfig.test?.dir).toBe(path.join(process.cwd(), "src", "plugins")); expect(defaultPluginsConfig.test?.include).toEqual(["**/*.test.ts"]); expect(defaultPluginsConfig.test?.exclude).toContain("contracts/**"); }); it("normalizes ui include patterns relative to the scoped dir", () => { - expect(defaultUiConfig.test?.dir).toBe("ui/src/ui"); + expect(defaultUiConfig.test?.dir).toBe(path.join(process.cwd(), "ui", "src", "ui")); expect(defaultUiConfig.test?.include).toEqual(["**/*.test.ts"]); }); it("normalizes utils include patterns relative to the scoped dir", () => { - expect(defaultUtilsConfig.test?.dir).toBe("src"); + expect(defaultUtilsConfig.test?.dir).toBe(path.join(process.cwd(), "src")); expect(defaultUtilsConfig.test?.include).toEqual(["utils/**/*.test.ts"]); expect(defaultUtilsConfig.test?.setupFiles).toEqual(["test/setup.ts"]); }); diff --git a/test/vitest-unit-fast-config.test.ts b/test/vitest-unit-fast-config.test.ts index 4a037b97204..9c852544af3 100644 --- a/test/vitest-unit-fast-config.test.ts +++ b/test/vitest-unit-fast-config.test.ts @@ -23,6 +23,18 @@ describe("unit-fast vitest lane", () => { expect(config.test?.include).toContain("src/commands/status-overview-values.test.ts"); }); + it("does not treat moved config paths as CLI include filters", () => { + const config = createUnitFastVitestConfig( + {}, + { + argv: ["node", "vitest", "run", "--config", "test/vitest/vitest.unit-fast.config.ts"], + }, + ); + + expect(config.test?.include).toContain("src/plugin-sdk/provider-entry.test.ts"); + expect(config.test?.include).toContain("src/commands/status-overview-values.test.ts"); + }); + it("keeps obvious stateful files out of the unit-fast lane", () => { expect(isUnitFastTestFile("src/plugin-sdk/temp-path.test.ts")).toBe(false); expect(resolveUnitFastTestIncludePattern("src/plugin-sdk/temp-path.ts")).toBeNull(); diff --git a/test/vitest/vitest.pattern-file.ts b/test/vitest/vitest.pattern-file.ts index 844db8a1f80..b883f221c92 100644 --- a/test/vitest/vitest.pattern-file.ts +++ b/test/vitest/vitest.pattern-file.ts @@ -46,12 +46,45 @@ export function loadPatternListFromEnv( } export function loadPatternListFromArgv(argv: string[] = process.argv): string[] | null { - const patterns = argv - .slice(2) - .filter((value) => value !== "run" && value !== "watch" && value !== "bench") - .filter((value) => !value.startsWith("-")) - .filter(looksLikeCliIncludePattern) - .map(normalizeCliPattern); + const optionValueFlags = new Set([ + "-c", + "-r", + "-t", + "--config", + "--dir", + "--environment", + "--exclude", + "--maxWorkers", + "--mode", + "--outputFile", + "--pool", + "--project", + "--reporter", + "--root", + "--shard", + "--testNamePattern", + ]); + const values: string[] = []; + let skipNext = false; + for (const value of argv.slice(2)) { + if (skipNext) { + skipNext = false; + continue; + } + if (value === "run" || value === "watch" || value === "bench") { + continue; + } + if (optionValueFlags.has(value)) { + skipNext = true; + continue; + } + if (value.startsWith("-")) { + continue; + } + values.push(value); + } + + const patterns = values.filter(looksLikeCliIncludePattern).map(normalizeCliPattern); return patterns.length > 0 ? [...new Set(patterns)] : null; } diff --git a/test/vitest/vitest.scoped-config.ts b/test/vitest/vitest.scoped-config.ts index d03da3742b3..7fcf2e683e1 100644 --- a/test/vitest/vitest.scoped-config.ts +++ b/test/vitest/vitest.scoped-config.ts @@ -1,6 +1,7 @@ +import path from "node:path"; import { defineConfig } from "vitest/config"; import { loadPatternListFromEnv, narrowIncludePatternsForCli } from "./vitest.pattern-file.ts"; -import { sharedVitestConfig } from "./vitest.shared.config.ts"; +import { repoRoot, sharedVitestConfig } from "./vitest.shared.config.ts"; import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs"; function normalizePathPattern(value: string): string { @@ -144,6 +145,7 @@ export function createScopedVitestConfig( const base = sharedVitestConfig as Record; const baseTest = sharedVitestConfig.test ?? {}; const scopedDir = options?.dir; + const resolvedScopedDir = scopedDir ? path.join(repoRoot, scopedDir) : undefined; const env = options?.env; const includeFromEnv = loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); const cliInclude = narrowIncludePatternsForCli(include, options?.argv); @@ -173,7 +175,7 @@ export function createScopedVitestConfig( isolate, ...(runner ? { runner } : { runner: undefined }), setupFiles, - ...(scopedDir ? { dir: scopedDir } : {}), + ...(resolvedScopedDir ? { dir: resolvedScopedDir } : {}), include: relativizeScopedPatterns(includeFromEnv ?? cliInclude ?? include, scopedDir), exclude, ...(options?.pool ? { pool: options.pool } : {}), diff --git a/test/vitest/vitest.shared.config.ts b/test/vitest/vitest.shared.config.ts index 1c545623750..2de77e36bca 100644 --- a/test/vitest/vitest.shared.config.ts +++ b/test/vitest/vitest.shared.config.ts @@ -159,7 +159,7 @@ export function resolveDefaultVitestPool( return "threads"; } -const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +export const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true"; const isWindows = process.platform === "win32"; const defaultPool = resolveDefaultVitestPool(); @@ -179,6 +179,7 @@ if (!isCI && localScheduling.throttledBySystem && shouldPrintVitestThrottle(proc } export const sharedVitestConfig = { + root: repoRoot, resolve: { alias: [ { @@ -200,6 +201,7 @@ export const sharedVitestConfig = { ], }, test: { + dir: repoRoot, testTimeout: 120_000, hookTimeout: isWindows ? 180_000 : 120_000, unstubEnvs: true,