Skip to content

Commit c2d24c1

Browse files
authored
chore: Bump vitest and avoid synchronous node apis in e2e tests (#1683)
I figured the test output rendering was weird but I think that's just vitest 4 🤷‍♂️
1 parent 8b45b9e commit c2d24c1

File tree

25 files changed

+342
-307
lines changed

25 files changed

+342
-307
lines changed

e2e/helpers/provider-runtime.mjs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { initLogger, startSpan, withCurrent } from "braintrust";
2-
import { existsSync, readFileSync } from "node:fs";
2+
import { promises as fs } from "node:fs";
33
import { createRequire } from "node:module";
44
import path from "node:path";
55
import { fileURLToPath } from "node:url";
@@ -83,11 +83,13 @@ export async function getInstalledPackageVersion(importMetaUrl, packageName) {
8383

8484
while (true) {
8585
const manifestPath = path.join(currentDir, "package.json");
86-
if (existsSync(manifestPath)) {
87-
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
86+
try {
87+
const manifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
8888
if (manifest && typeof manifest.version === "string") {
8989
return manifest.version;
9090
}
91+
} catch {
92+
// Keep walking upward until we find the package root.
9193
}
9294

9395
const parentDir = path.dirname(currentDir);

e2e/helpers/scenario-installer.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { promises as fs, rmSync } from "node:fs";
1+
import { promises as fs } from "node:fs";
22
import { spawn } from "node:child_process";
33
import * as path from "node:path";
44
import { fileURLToPath } from "node:url";
@@ -103,24 +103,29 @@ function registerCleanupHandlers() {
103103

104104
cleanupRegistered = true;
105105

106-
const cleanupAll = () => {
106+
const cleanupAll = async () => {
107107
for (const dir of cleanupDirs) {
108108
try {
109-
rmSync(dir, { force: true, recursive: true });
109+
await fs.rm(dir, { force: true, recursive: true });
110110
} catch {
111111
// Best-effort cleanup for ephemeral test directories.
112112
}
113113
}
114+
cleanupDirs.clear();
114115
};
115116

116-
process.on("exit", cleanupAll);
117+
process.on("beforeExit", () => {
118+
void cleanupAll();
119+
});
117120
process.on("SIGINT", () => {
118-
cleanupAll();
119-
process.exit(130);
121+
void cleanupAll().finally(() => {
122+
process.exit(130);
123+
});
120124
});
121125
process.on("SIGTERM", () => {
122-
cleanupAll();
123-
process.exit(143);
126+
void cleanupAll().finally(() => {
127+
process.exit(143);
128+
});
124129
});
125130
}
126131

e2e/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"braintrust": "workspace:^",
2020
"tsx": "^4.21.0",
2121
"typescript": "5.4.4",
22-
"vitest": "^4.1.0",
22+
"vitest": "^4.1.2",
2323
"zod": "4.3.6"
2424
}
2525
}

e2e/scenarios/nextjs-instrumentation/scenario.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { spawn, spawnSync } from "node:child_process";
1+
import { spawn } from "node:child_process";
22
import net from "node:net";
33
import path from "node:path";
44
import { fileURLToPath } from "node:url";
5-
import { runMain } from "../../helpers/scenario-runtime";
5+
import { runMain, runNodeSubprocess } from "../../helpers/scenario-runtime";
66

77
const scenarioDir = path.dirname(fileURLToPath(import.meta.url));
88
const nextBin = new URL("./node_modules/next/dist/bin/next", import.meta.url)
@@ -97,19 +97,13 @@ async function main() {
9797
const baseUrl = `http://127.0.0.1:${port}`;
9898
const env = withScenarioEnv(process.env);
9999

100-
const buildResult = spawnSync(process.execPath, [nextBin, "build"], {
100+
await runNodeSubprocess({
101+
args: [nextBin, "build"],
101102
cwd: scenarioDir,
102-
stdio: "pipe",
103103
env,
104-
encoding: "utf8",
104+
timeoutMs: 180_000,
105105
});
106106

107-
if (buildResult.status !== 0) {
108-
throw new Error(
109-
`next build failed with exit code ${buildResult.status}\nSTDOUT:\n${buildResult.stdout}\nSTDERR:\n${buildResult.stderr}`,
110-
);
111-
}
112-
113107
const server = spawn(
114108
process.execPath,
115109
[nextBin, "start", "--hostname", "127.0.0.1", "--port", String(port)],

e2e/scenarios/test-framework-evals-vitest/scenario.vitest-v3.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createRequire } from "node:module";
2-
import { existsSync } from "node:fs";
2+
import { promises as fs } from "node:fs";
33
import * as path from "node:path";
44
import { resolveScenarioDir } from "../../helpers/scenario-harness";
55
import {
@@ -12,22 +12,24 @@ const require = createRequire(import.meta.url);
1212
const scenarioDir = resolveScenarioDir(import.meta.url);
1313

1414
// Resolve the vitest.mjs bin by finding the package root via the main entry.
15-
function findVitestBin(packageName: string): string {
15+
async function findVitestBin(packageName: string): Promise<string> {
1616
const entryPath = require.resolve(packageName);
1717
let dir = path.dirname(entryPath);
1818
while (dir !== path.dirname(dir)) {
1919
const candidate = path.join(dir, "vitest.mjs");
20-
if (existsSync(candidate)) {
20+
try {
21+
await fs.access(candidate);
2122
return candidate;
23+
} catch {
24+
// Keep walking upward.
2225
}
2326
dir = path.dirname(dir);
2427
}
2528
throw new Error(`Could not find vitest.mjs for ${packageName}`);
2629
}
2730

28-
const vitestCliPath = findVitestBin("vitest-v3");
29-
3031
async function main() {
32+
const vitestCliPath = await findVitestBin("vitest-v3");
3133
const testRunId = getTestRunId();
3234

3335
await runNodeSubprocess({

e2e/scenarios/test-framework-evals-vitest/scenario.vitest-v4.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createRequire } from "node:module";
2-
import { existsSync } from "node:fs";
2+
import { promises as fs } from "node:fs";
33
import * as path from "node:path";
44
import { resolveScenarioDir } from "../../helpers/scenario-harness";
55
import {
@@ -12,22 +12,24 @@ const require = createRequire(import.meta.url);
1212
const scenarioDir = resolveScenarioDir(import.meta.url);
1313

1414
// Resolve the vitest.mjs bin by finding the package root via the main entry.
15-
function findVitestBin(packageName: string): string {
15+
async function findVitestBin(packageName: string): Promise<string> {
1616
const entryPath = require.resolve(packageName);
1717
let dir = path.dirname(entryPath);
1818
while (dir !== path.dirname(dir)) {
1919
const candidate = path.join(dir, "vitest.mjs");
20-
if (existsSync(candidate)) {
20+
try {
21+
await fs.access(candidate);
2122
return candidate;
23+
} catch {
24+
// Keep walking upward.
2225
}
2326
dir = path.dirname(dir);
2427
}
2528
throw new Error(`Could not find vitest.mjs for ${packageName}`);
2629
}
2730

28-
const vitestCliPath = findVitestBin("vitest-v4");
29-
3031
async function main() {
32+
const vitestCliPath = await findVitestBin("vitest-v4");
3133
const testRunId = getTestRunId();
3234

3335
await runNodeSubprocess({

e2e/scenarios/turbopack-auto-instrumentation/scenario.ts

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { spawn, spawnSync } from "node:child_process";
1+
import { spawn } from "node:child_process";
22
import http from "node:http";
33
import path from "node:path";
44
import { fileURLToPath } from "node:url";
5+
import { runMain, runNodeSubprocess } from "../../helpers/scenario-runtime";
56

67
const scenarioDir = path.dirname(fileURLToPath(import.meta.url));
78
const PORT = 3999;
@@ -11,28 +12,15 @@ const PORT = 3999;
1112
const nextBin = new URL("./node_modules/next/dist/bin/next", import.meta.url)
1213
.pathname;
1314

14-
// Run Next.js build (Turbopack is the default bundler in Next.js 16)
15-
const buildResult = spawnSync(process.execPath, [nextBin, "build"], {
16-
cwd: scenarioDir,
17-
stdio: "inherit",
18-
env: { ...process.env, NEXT_TELEMETRY_DISABLED: "1" },
19-
});
20-
21-
if (buildResult.status !== 0) {
22-
throw new Error(`next build failed with exit code ${buildResult.status}`);
15+
function withScenarioEnv(
16+
env: NodeJS.ProcessEnv = process.env,
17+
): NodeJS.ProcessEnv {
18+
return {
19+
...env,
20+
NEXT_TELEMETRY_DISABLED: "1",
21+
};
2322
}
2423

25-
// Start the Next.js server
26-
const server = spawn(
27-
process.execPath,
28-
[nextBin, "start", "--port", String(PORT)],
29-
{
30-
cwd: scenarioDir,
31-
stdio: "inherit",
32-
env: { ...process.env, NEXT_TELEMETRY_DISABLED: "1" },
33-
},
34-
);
35-
3624
function httpGet(url: string): Promise<{ status: number; body: string }> {
3725
return new Promise((resolve, reject) => {
3826
http
@@ -60,8 +48,27 @@ async function waitForServer(timeoutMs = 30_000): Promise<void> {
6048
}
6149

6250
// Top-level await is not supported in CJS output, so use an explicit async
63-
// function and propagate failures via process.exit.
51+
// function and run it through the shared scenario wrapper.
6452
async function main() {
53+
const env = withScenarioEnv(process.env);
54+
await runNodeSubprocess({
55+
args: [nextBin, "build"],
56+
cwd: scenarioDir,
57+
env,
58+
timeoutMs: 180_000,
59+
});
60+
61+
// Start the Next.js server
62+
const server = spawn(
63+
process.execPath,
64+
[nextBin, "start", "--port", String(PORT)],
65+
{
66+
cwd: scenarioDir,
67+
stdio: "inherit",
68+
env,
69+
},
70+
);
71+
6572
try {
6673
await waitForServer();
6774

@@ -82,7 +89,4 @@ async function main() {
8289
}
8390
}
8491

85-
main().catch((err) => {
86-
console.error(err);
87-
process.exit(1);
88-
});
92+
runMain(main);

integrations/browser-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"braintrust": "workspace:*",
3232
"tsup": "^8.3.5",
3333
"typescript": "^5.3.3",
34-
"vitest": "^4.1.0"
34+
"vitest": "^4.1.2"
3535
},
3636
"peerDependencies": {
3737
"zod": "^3.25.34 || ^4.0"

integrations/langchain-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"tsup": "^8.3.5",
3535
"typedoc": "^0.25.13",
3636
"typescript": "^5.3.3",
37-
"vitest": "^4.1.0",
37+
"vitest": "^4.1.2",
3838
"zod": "^3.25.34",
3939
"zod-to-json-schema": "^3.22.5"
4040
},

integrations/openai-agents-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"tsx": "^4.21.0",
3232
"typedoc": "^0.25.13",
3333
"typescript": "^5.3.3",
34-
"vitest": "^4.1.0",
34+
"vitest": "^4.1.2",
3535
"zod": "^3.25.34"
3636
},
3737
"peerDependencies": {

0 commit comments

Comments
 (0)