import { execSync } from "node:child_process"; import dedent from "ts-dedent"; import { beforeEach, describe, it } from "vitest"; import { CLOUDFLARE_ACCOUNT_ID } from "./helpers/account-id"; import { makeRoot, seed } from "./helpers/setup"; import { WRANGLER_IMPORT } from "./helpers/wrangler"; describe.skipIf(!CLOUDFLARE_ACCOUNT_ID)("switching runtimes", () => { let root: string; beforeEach(async () => { root = await makeRoot(); await seed(root, { "wrangler.toml": dedent` name = "dev-env-app" account_id = "${CLOUDFLARE_ACCOUNT_ID}" compatibility_date = "2023-01-01" `, "index.ts": dedent /*javascript*/ ` export default { async fetch(request, env) { return new Response( env.ORDER + ": I am " + (env.REMOTE ? "remote" : "local") ); }, }; `, "index.mjs": dedent /*javascript*/ ` import { setTimeout } from "timers/promises"; import { unstable_startWorker as startWorker } from "${WRANGLER_IMPORT}"; const firstRemote = process.argv[2] === "remote"; let worker; try { worker = await startWorker({ name: "worker", entrypoint: "index.ts", compatibilityFlags: ["nodejs_compat"], compatibilityDate: "2023-10-01", bindings: { REMOTE: { type: "json", value: firstRemote, }, ORDER: { type: "plain_text", value: "1", }, }, dev: { remote: firstRemote, auth: { accountId: process.env.CLOUDFLARE_ACCOUNT_ID, apiToken: { apiToken: process.env.CLOUDFLARE_API_TOKEN, } }, server: { port: 0, }, }, }); const url = await worker.url; console.log(await fetch(url).then((r) => r.text())); await worker.patchConfig({ bindings: { REMOTE: { type: "json", value: !firstRemote, }, ORDER: { type: "plain_text", value: "2", }, }, dev: { ...worker.config.dev, remote: !firstRemote, }, }); // Give the config some time to propagate await setTimeout(500); console.log(await fetch(url).then((r) => r.text())); } finally { await worker?.dispose(); process.exit(0); } `, "package.json": dedent` { "name": "dev-env-app", "version": "0.0.0", "private": true } `, }); }); it("can switch from local to remote", async ({ expect }) => { const stdout = execSync(`node index.mjs local`, { timeout: 20_000, encoding: "utf-8", cwd: root, stdio: "pipe", }); expect(stdout).toContain("1: I am local"); expect(stdout).toContain("2: I am remote"); }); it("can switch from remote to local", async ({ expect }) => { const stdout = execSync(`node index.mjs remote`, { timeout: 20_000, encoding: "utf-8", cwd: root, stdio: "pipe", }); expect(stdout).toContain("1: I am remote"); expect(stdout).toContain("2: I am local"); }); });