From 34bba50b3a80208e73f4390925e1b60116169a04 Mon Sep 17 00:00:00 2001 From: Greg Brimble Date: Thu, 5 Dec 2024 21:15:34 -0500 Subject: [PATCH] Add e2e test for WfP & Assets --- packages/wrangler/e2e/deployments.test.ts | 173 +++++++++++++----- .../wrangler/e2e/helpers/e2e-wrangler-test.ts | 14 ++ 2 files changed, 146 insertions(+), 41 deletions(-) diff --git a/packages/wrangler/e2e/deployments.test.ts b/packages/wrangler/e2e/deployments.test.ts index 6c1e8bbecd74f..25902cb273c64 100644 --- a/packages/wrangler/e2e/deployments.test.ts +++ b/packages/wrangler/e2e/deployments.test.ts @@ -1,7 +1,7 @@ import assert from "node:assert"; import dedent from "ts-dedent"; import { fetch } from "undici"; -import { afterAll, describe, expect, it, vi } from "vitest"; +import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; import { CLOUDFLARE_ACCOUNT_ID } from "./helpers/account-id"; import { WranglerE2ETestHelper } from "./helpers/e2e-wrangler-test"; import { generateResourceName } from "./helpers/generate-resource-name"; @@ -14,6 +14,8 @@ const normalize = (str: string) => [CLOUDFLARE_ACCOUNT_ID]: "CLOUDFLARE_ACCOUNT_ID", }).replaceAll(/^Author:(\s+).+@.+$/gm, "Author:$1person@example.com"); const workerName = generateResourceName(); +const dispatchNamespaceName = generateResourceName("dispatch"); +const dispatchWorkerName = generateResourceName(); describe("deployments", { timeout: TIMEOUT }, () => { let deployedUrl: string; @@ -250,11 +252,115 @@ const checkAssets = async (testCases: AssetTestCase[], deployedUrl: string) => { } }; -describe("Workers + Assets deployment", { timeout: TIMEOUT }, () => { +describe.each([ + { + name: "regular Worker", + flags: "", + async beforeAll() {}, + async afterAll() {}, + expectInitialStdout: (output: string) => { + expect(output).toEqual(`🌀 Building list of assets... +🌀 Starting asset upload... +🌀 Found 3 new or modified static assets to upload. Proceeding with upload... ++ /404.html ++ /index.html ++ /[boop].html +Uploaded 1 of 3 assets +Uploaded 2 of 3 assets +Uploaded 3 of 3 assets +✨ Success! Uploaded 3 files (TIMINGS) +Total Upload: xx KiB / gzip: xx KiB +Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS) +Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS) + https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev +Current Version ID: 00000000-0000-0000-0000-000000000000`); + }, + expectSubsequentStdout: (output: string) => { + expect(output).toEqual(`🌀 Building list of assets... +🌀 Starting asset upload... +No files to upload. Proceeding with deployment... +Total Upload: xx KiB / gzip: xx KiB +Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS) +Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS) + https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev +Current Version ID: 00000000-0000-0000-0000-000000000000`); + }, + }, + { + name: "Workers for Platforms", + flags: `--dispatch-namespace ${dispatchNamespaceName}`, + url: "", + async beforeAll(helper: WranglerE2ETestHelper) { + await helper.seed({ + "dispatch-worker/wrangler.toml": dedent` + name = "${dispatchWorkerName}" + main = "./src/index.js" + compatibility_date = "2023-01-01" + + [[dispatch_namespaces]] + binding = "DISPATCH" + namespace = "${dispatchNamespaceName}" + `, + "dispatch-worker/src/index.js": dedent` + export default { + async fetch(request, env, ctx) { + const stub = env.DISPATCH.get("${workerName}"); + return stub.fetch(request); + } + } + `, + }); + await helper.run( + `wrangler dispatch-namespace create ${dispatchNamespaceName}` + ); + const { stdout } = await helper.run( + `wrangler deploy -c dispatch-worker/wrangler.toml` + ); + const match = stdout.match(/https:\/\/tmp-e2e-.+?\..+?\.workers\.dev/); + assert(match?.groups); + this.url = match.groups.url; + }, + async afterAll(helper: WranglerE2ETestHelper) { + await helper.run(`wrangler delete -c dispatch-worker/wrangler.toml`); + await helper.run( + `wrangler dispatch-namespace delete ${dispatchNamespaceName}` + ); + }, + expectInitialStdout: (output: string) => { + expect(output).toEqual(`🌀 Building list of assets... +🌀 Starting asset upload... +🌀 Found 3 new or modified static assets to upload. Proceeding with upload... ++ /404.html ++ /index.html ++ /[boop].html +Uploaded 1 of 3 assets +Uploaded 2 of 3 assets +Uploaded 3 of 3 assets +✨ Success! Uploaded 3 files (TIMINGS) +Total Upload: xx KiB / gzip: xx KiB +Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS) + Dispatch Namespace: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000 +Current Version ID: 00000000-0000-0000-0000-000000000000`); + }, + expectSubsequentStdout: (output: string) => { + expect(output).toEqual(`🌀 Building list of assets... +🌀 Starting asset upload... +No files to upload. Proceeding with deployment... +Total Upload: xx KiB / gzip: xx KiB +Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS) + Dispatch Namespace: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000 +Current Version ID: 00000000-0000-0000-0000-000000000000`); + }, + }, +])("Workers + Assets deployment: $name", { timeout: TIMEOUT }, (testcase) => { let deployedUrl: string; const helper = new WranglerE2ETestHelper(); + beforeAll(async () => { + await testcase.beforeAll(helper); + }); afterAll(async () => { - await helper.run(`wrangler delete`); + await helper.run(`wrangler delete ${testcase.flags}`); + await testcase.afterAll(helper); }); it("deploys a Workers + Assets project with assets only", async () => { await helper.seed({ @@ -268,28 +374,18 @@ describe("Workers + Assets deployment", { timeout: TIMEOUT }, () => { }); const output = await helper.run(`wrangler deploy`); - expect(normalize(output.stdout)).toMatchInlineSnapshot(` - "🌀 Building list of assets... - 🌀 Starting asset upload... - 🌀 Found 3 new or modified static assets to upload. Proceeding with upload... - + /404.html - + /index.html - + /[boop].html - Uploaded 1 of 3 assets - Uploaded 2 of 3 assets - Uploaded 3 of 3 assets - ✨ Success! Uploaded 3 files (TIMINGS) - Total Upload: xx KiB / gzip: xx KiB - Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS) - Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS) - https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev - Current Version ID: 00000000-0000-0000-0000-000000000000" - `); - const match = output.stdout.match( - /(?https:\/\/tmp-e2e-.+?\..+?\.workers\.dev)/ - ); - assert(match?.groups); - deployedUrl = match.groups.url; + testcase.expectInitialStdout(normalize(output.stdout)); + if (testcase.url) { + deployedUrl = testcase.url; + } else { + const match = output.stdout.match( + /(?https:\/\/tmp-e2e-.+?\..+?\.workers\.dev)/ + ); + assert(match?.groups); + deployedUrl = match.groups.url; + } + + console.log({ workerName, dispatchWorkerName, deployedUrl }); const testCases: AssetTestCase[] = [ // Tests html_handling = "auto_trailing_slash" (default): @@ -349,23 +445,18 @@ describe("Workers + Assets deployment", { timeout: TIMEOUT }, () => { }`, ...initialAssets, }); - const output = await helper.run(`wrangler deploy`); + const output = await helper.run(`wrangler deploy ${testcase.flags}`); // expect only no asset files to be uploaded as no new asset files have been added - expect(normalize(output.stdout)).toMatchInlineSnapshot(` - "🌀 Building list of assets... - 🌀 Starting asset upload... - No files to upload. Proceeding with deployment... - Total Upload: xx KiB / gzip: xx KiB - Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS) - Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS) - https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev - Current Version ID: 00000000-0000-0000-0000-000000000000" - `); - const match = output.stdout.match( - /(?https:\/\/tmp-e2e-.+?\..+?\.workers\.dev)/ - ); - assert(match?.groups); - deployedUrl = match.groups.url; + testcase.expectSubsequentStdout(normalize(output.stdout)); + if (testcase.url) { + deployedUrl = testcase.url; + } else { + const match = output.stdout.match( + /(?https:\/\/tmp-e2e-.+?\..+?\.workers\.dev)/ + ); + assert(match?.groups); + deployedUrl = match.groups.url; + } const testCases: AssetTestCase[] = [ // because html handling has now been set to "none", only exact matches will be served diff --git a/packages/wrangler/e2e/helpers/e2e-wrangler-test.ts b/packages/wrangler/e2e/helpers/e2e-wrangler-test.ts index f1b39b8e53879..293ff896b7969 100644 --- a/packages/wrangler/e2e/helpers/e2e-wrangler-test.ts +++ b/packages/wrangler/e2e/helpers/e2e-wrangler-test.ts @@ -68,6 +68,20 @@ export class WranglerE2ETestHelper { return id; } + async dispatchNamespace(isLocal: boolean) { + const name = generateResourceName("dispatch"); + if (isLocal) { + throw new Error( + "Dispatch namespaces are not supported in local mode (yet)" + ); + } + await this.run(`wrangler dispatch-namespace create ${name}`); + onTestFinished(async () => { + await this.run(`wrangler dispatch-namespace delete ${name}`); + }); + return name; + } + async r2(isLocal: boolean) { const name = generateResourceName("r2"); if (isLocal) {