Skip to content

Commit 729788a

Browse files
authored
Revert "test: add e2e tests of the build+preview use case (un-revert of #8384) (#8436)" (#8609)
This reverts commit c018844.
1 parent 5889c4c commit 729788a

File tree

5 files changed

+44
-115
lines changed

5 files changed

+44
-115
lines changed
Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# vite-plugin e2e tests
22

3-
This directory contains e2e tests that give more confidence that the plugin will work in real world scenarios outside the comfort of this monorepo.
3+
This directory contains e2e test that give more confidence that the plugin will work in real world scenarios outside the comfort of this monorepo.
44

55
In general, these tests create test projects by copying a fixture from the `fixtures` directory into a temporary directory and then installing the local builds of the plugin along with its dependencies.
66

@@ -9,10 +9,8 @@ In general, these tests create test projects by copying a fixture from the `fixt
99
Simply use turbo to run the tests from the root of the monorepo.
1010
This will also ensure that the required dependencies have all been built before running the tests.
1111

12-
You will need to provide CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN for the Workers AI tests to pass.
13-
1412
```sh
15-
CLOUDFLARE_ACCOUNT_ID=xxxx CLOUDFLARE_API_TOKEN=yyyy pnpm test:e2e -F @cloudflare/vite-plugin
13+
pnpm test:e2e -F @cloudflare/vite-plugin
1614
```
1715

1816
## Developing e2e tests
@@ -21,7 +19,7 @@ These tests use a mock npm registry where the built plugin has been published.
2119

2220
The registry is booted up and loaded with the local build of the plugin and its local dependencies in the global-setup.ts file that runs once at the start of the e2e test run, and the server is killed and its caches removed at the end of the test run.
2321

24-
The Vitest `test` function is extended with additional helpers to setup clean copies of fixtures outside of the monorepo so that they can be isolated from any other dependencies in the project.
22+
The Vite `test` function is an extended with additional helpers to setup clean copies of fixtures outside of the monorepo so that they can be isolated from any other dependencies in the project.
2523

2624
The simplest test looks like:
2725

@@ -30,23 +28,14 @@ test("can serve a Worker request", async ({ expect, seed, viteDev }) => {
3028
const projectPath = await seed("basic");
3129
runCommand(`pnpm install`, projectPath);
3230

33-
const proc = await viteDev("pnpm", "dev", projectPath);
31+
const proc = await viteDev(projectPath);
3432
const url = await waitForReady(proc);
3533
expect(await fetchJson(url + "/api/")).toEqual({ name: "Cloudflare" });
3634
});
3735
```
3836

3937
- The `seed()` helper makes a copy of the named fixture into a temporary directory. It returns the path to the directory containing the copy (`projectPath` above). This directory will be deleted at the end of the test.
4038
- The `runCommand()` helper simply executes a one-shot command and resolves when it has exited. You can use this to install the dependencies of the fixture from the mock npm registry, as in the example above.
41-
- The `viteCommand()` helper boots up the given long-lived command and returns an object that can be used to monitor its output. The process will be killed at the end of the test.
42-
- The `waitForReady()` helper will resolve when the `proc` process has output its ready message, from which it will parse the url that can be fetched in the test.
39+
- The `viteDev()` helper boots up the `vite dev` command and returns an object that can be used to monitor its output. The process will be killed at the end of the test.
40+
- The `waitForReady()` helper will resolve when the `vite dev` process has output its ready message, from which it will parse the url that can be fetched in the test.
4341
- The `fetchJson()` helper makes an Undici fetch to the url parsing the response into JSON. It will retry every 250ms for up to 10 secs to minimize flakes.
44-
45-
## Debugging e2e tests
46-
47-
You can control the logging and cleanup via environment variables:
48-
49-
- Keep the temporary directory after the tests have completed: `CLOUDFLARE_VITE_E2E_KEEP_TEMP_DIRS=true`
50-
- See debug logs for the tests: `NODE_DEBUG=vite-plugin:test`
51-
- See debug logs for the mock npm registry: `NODE_DEBUG=mock-npm-registry`
52-
- See debug logs for Vite: `DEBUG="vite:*"`
Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,30 @@
11
import { describe } from "vitest";
22
import { fetchJson, runCommand, test, waitForReady } from "./helpers.js";
33

4-
const isWindows = process.platform === "win32";
4+
describe("node compatibility", () => {
5+
describe.each(["pnpm --no-store", "npm", "yarn"])("using %s", (pm) => {
6+
test("can serve a Worker request", async ({ expect, seed, viteDev }) => {
7+
const projectPath = await seed("basic");
8+
runCommand(`${pm} install`, projectPath);
59

6-
const packageManagers = ["pnpm", "npm", "yarn"] as const;
7-
const commands = ["dev", "preview"] as const;
8-
9-
describe("basic e2e tests", () => {
10-
describe.each(commands)('with "%s" command', (command) => {
11-
// TODO: re-enable `vite preview` tests on Windows (DEVX-1748)
12-
describe.skipIf(command === "preview" && isWindows).each(packageManagers)(
13-
'with "%s" package manager',
14-
(pm) => {
15-
describe("node compatibility", () => {
16-
test("can serve a Worker request", async ({
17-
expect,
18-
seed,
19-
viteCommand,
20-
}) => {
21-
const projectPath = await seed("basic");
22-
runCommand(`${pm} install`, projectPath);
23-
24-
const proc = await viteCommand(pm, command, projectPath);
25-
const url = await waitForReady(proc);
26-
expect(await fetchJson(url + "/api/")).toEqual({
27-
name: "Cloudflare",
28-
});
29-
});
30-
});
10+
const proc = await viteDev(projectPath);
11+
const url = await waitForReady(proc);
12+
expect(await fetchJson(url + "/api/")).toEqual({ name: "Cloudflare" });
13+
});
14+
});
15+
});
3116

32-
// This test checks that wrapped bindings which rely on additional workers with an authed connection to the CF API work
33-
describe("Workers AI", () => {
34-
test("can serve a Worker request", async ({
35-
expect,
36-
seed,
37-
viteCommand,
38-
}) => {
39-
const projectPath = await seed("basic");
40-
runCommand(`${pm} install`, projectPath);
17+
// This test checks that wrapped bindings which rely on additional workers with an authed connection to the CF API work
18+
describe("Workers AI", () => {
19+
test("can serve a Worker request", async ({ expect, seed, viteDev }) => {
20+
const projectPath = await seed("basic");
21+
runCommand(`npm install`, projectPath);
4122

42-
const proc = await viteCommand(pm, command, projectPath);
43-
const url = await waitForReady(proc);
23+
const proc = await viteDev(projectPath);
24+
const url = await waitForReady(proc);
4425

45-
expect(await fetchJson(url + "/ai/")).toEqual({
46-
response: expect.stringContaining("Workers AI"),
47-
});
48-
});
49-
});
50-
}
51-
);
26+
expect(await fetchJson(url + "/ai/")).toEqual({
27+
response: expect.stringContaining("Workers AI"),
28+
});
5229
});
5330
});

packages/vite-plugin-cloudflare/e2e/fixtures/basic/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"type": "module",
66
"scripts": {
7-
"build": "vite build",
7+
"build": "tsc -b && vite build",
88
"dev": "vite",
99
"lint": "eslint .",
1010
"preview": "vite preview"

packages/vite-plugin-cloudflare/e2e/global-setup.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import os from "node:os";
33
import path from "node:path";
44
import util from "node:util";
55
import { startMockNpmRegistry } from "@cloudflare/mock-npm-registry";
6-
import type { TestProject } from "vitest/node";
7-
8-
const debuglog = util.debuglog("vite-plugin:test");
6+
import type { GlobalSetupContext } from "vitest/node";
97

108
declare module "vitest" {
119
export interface ProvidedContext {
@@ -15,27 +13,22 @@ declare module "vitest" {
1513

1614
// Using a global setup means we can modify tests without having to re-install
1715
// packages into our temporary directory
18-
export default async function ({ provide }: TestProject) {
16+
// Typings for the GlobalSetupContext are augmented in `global-setup.d.ts`.
17+
export default async function ({ provide }: GlobalSetupContext) {
1918
const stopMockNpmRegistry = await startMockNpmRegistry(
2019
"@cloudflare/vite-plugin"
2120
);
2221

2322
// Create temporary directory to host projects used for testing
2423
const root = await fs.mkdtemp(path.join(os.tmpdir(), "vite-plugin-"));
25-
debuglog("Created temporary directory at " + root);
2624

27-
// The type of the provided `root` is defined in the `ProvidedContent` type above.
2825
provide("root", root);
2926

3027
// Cleanup temporary directory on teardown
3128
return async () => {
3229
await stopMockNpmRegistry();
3330

34-
if (process.env.CLOUDFLARE_VITE_E2E_KEEP_TEMP_DIRS) {
35-
debuglog("Temporary directory left in-place at " + root);
36-
} else {
37-
debuglog("Cleaning up temporary directory...");
38-
await fs.rm(root, { recursive: true, maxRetries: 10 });
39-
}
31+
console.log("Cleaning up temporary directory...");
32+
await fs.rm(root, { recursive: true, maxRetries: 10 });
4033
};
4134
}

packages/vite-plugin-cloudflare/e2e/helpers.ts

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,20 @@ import path from "node:path";
55
import util from "node:util";
66
import { stripAnsi } from "miniflare";
77
import kill from "tree-kill";
8-
import { test as baseTest, inject, onTestFailed, vi } from "vitest";
8+
import { test as baseTest, inject, vi } from "vitest";
99

1010
const debuglog = util.debuglog("vite-plugin:test");
1111

12-
const testEnv = {
13-
...process.env,
14-
// The following env vars are set to ensure that package managers
15-
// do not use the same global cache and accidentally hit race conditions.
16-
YARN_CACHE_FOLDER: "./.yarn/cache",
17-
YARN_ENABLE_GLOBAL_CACHE: "false",
18-
PNPM_HOME: "./.pnpm",
19-
npm_config_cache: "./.npm/cache",
20-
};
21-
2212
/**
2313
* Extends the Vitest `test()` function to support running vite in
2414
* well defined environments that represent real-world usage.
2515
*/
2616
export const test = baseTest.extend<{
2717
seed: (fixture: string) => Promise<string>;
28-
viteCommand: (
29-
pm: "pnpm" | "npm" | "yarn",
30-
command: "dev" | "preview",
18+
viteDev: (
3119
projectPath: string,
3220
options?: { flags?: string[]; maxBuffer?: number }
33-
) => Promise<Process>;
21+
) => Process;
3422
}>({
3523
/** Seed a test project from a fixture. */
3624
async seed({}, use) {
@@ -57,24 +45,18 @@ export const test = baseTest.extend<{
5745
}
5846
}
5947
},
60-
/** Starts a command and wraps its outputs. */
61-
async viteCommand({}, use) {
48+
/** Start a `vite dev` command and wraps its outputs. */
49+
async viteDev({}, use) {
6250
const processes: ChildProcess[] = [];
63-
await use(async (pm, command, projectPath) => {
64-
if (command === "preview") {
65-
// We must first run the build command to generate the Worker that is to be previewed.
66-
await runCommand(`${pm} run build`, projectPath);
67-
}
68-
69-
debuglog(`starting "${command}" with ${pm} in ${projectPath}`);
70-
const proc = childProcess.exec(`${pm} run ${command}`, {
51+
await use((projectPath) => {
52+
debuglog("starting vite for " + projectPath);
53+
const proc = childProcess.exec(`pnpm exec vite dev`, {
7154
cwd: projectPath,
72-
env: testEnv,
7355
});
7456
processes.push(proc);
7557
return wrap(proc);
7658
});
77-
debuglog("Closing down command processes", processes.length);
59+
debuglog("Closing down vite dev processes", processes.length);
7860
processes.forEach((proc) => proc.pid && kill(proc.pid));
7961
},
8062
});
@@ -86,7 +68,7 @@ export interface Process {
8668
}
8769

8870
/**
89-
* Wraps a long running child process to capture its stdio and make it available programmatically.
71+
* Wrap a long running child process to capture its stdio and make it available programmatically.
9072
*/
9173
function wrap(proc: childProcess.ChildProcess): Process {
9274
let stdout = "";
@@ -106,7 +88,7 @@ function wrap(proc: childProcess.ChildProcess): Process {
10688
stderr += chunk;
10789
});
10890
const closePromise = events.once(proc, "close");
109-
const wrappedProc = {
91+
return {
11092
get stdout() {
11193
return stripAnsi(stdout);
11294
},
@@ -117,24 +99,12 @@ function wrap(proc: childProcess.ChildProcess): Process {
11799
return closePromise.then(([exitCode]) => exitCode ?? -1);
118100
},
119101
};
120-
121-
onTestFailed(() => {
122-
console.log(
123-
`Wrapped process logs (${proc.spawnfile} ${proc.spawnargs.join(" ")}):`
124-
);
125-
console.log(wrappedProc.stdout);
126-
console.error(wrappedProc.stderr);
127-
});
128-
129-
return wrappedProc;
130102
}
131103

132104
export function runCommand(command: string, cwd: string) {
133-
debuglog(`Running "${command}"`);
134105
childProcess.execSync(command, {
135106
cwd,
136107
stdio: debuglog.enabled ? "inherit" : "ignore",
137-
env: testEnv,
138108
});
139109
}
140110

0 commit comments

Comments
 (0)