From 17ced680efb2589765637cd41abec0ab9d199ed3 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Mon, 2 Oct 2023 19:41:25 +0100 Subject: [PATCH] C3: e2es pages tests additions and fixes (#4015) * C3: remove comment about docusaurus and gatsby * C3: add docusaurus e2e test * C3: add gatsby e2e test * add --no-git-init test flag to remix * add log to show what C3 command gets run during e2e testing * set up git user in C3 e2e workflows * tweak npm_config_user_agent env variable for testing * increase timeout to 5 mins * increase prompt delay by a half second * Add per-framework timeouts in config. Quarantine gatsby * Prevent promptHandlers from being consumed * use blog template in astro C3 e2e test --------- Co-authored-by: James Culveyhouse --- .github/workflows/test-c3.yml | 6 +++ .../create-cloudflare/e2e-tests/helpers.ts | 24 ++++++++-- .../create-cloudflare/e2e-tests/pages.test.ts | 47 +++++++++++++++---- .../src/frameworks/astro/index.ts | 2 +- .../src/frameworks/remix/index.ts | 2 +- .../create-cloudflare/src/helpers/packages.ts | 3 ++ packages/create-cloudflare/turbo.json | 2 +- 7 files changed, 69 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test-c3.yml b/.github/workflows/test-c3.yml index 7927efe49302..c80b23d87507 100644 --- a/.github/workflows/test-c3.yml +++ b/.github/workflows/test-c3.yml @@ -79,6 +79,12 @@ jobs: with: bun-version: ${{ env.bun-version }} + # Needed because gatsby requires git + - name: Configure Git + run: | + git config --global user.email wrangler@cloudflare.com + git config --global user.name 'Wrangler automated PR updater' + - name: E2E Tests run: pnpm run --filter create-cloudflare test:e2e:${{matrix.pm}} env: diff --git a/packages/create-cloudflare/e2e-tests/helpers.ts b/packages/create-cloudflare/e2e-tests/helpers.ts index 3605b1c8364c..d3ef2d13990a 100644 --- a/packages/create-cloudflare/e2e-tests/helpers.ts +++ b/packages/create-cloudflare/e2e-tests/helpers.ts @@ -5,6 +5,7 @@ import { join } from "path"; import { spawn } from "cross-spawn"; import { sleep } from "helpers/common"; import { spinnerFrames } from "helpers/interactive"; +import { detectPackageManager } from "helpers/packages"; import type { SpinnerStyle } from "helpers/interactive"; export const C3_E2E_PREFIX = "c3-e2e-"; @@ -39,7 +40,20 @@ export const runC3 = async ({ promptHandlers = [], outputPrefix = "", }: RunnerConfig) => { - const proc = spawn("node", ["./dist/cli.js", ...argv]); + const cmd = "node"; + const args = ["./dist/cli.js", ...argv]; + const proc = spawn(cmd, args); + + promptHandlers = [...promptHandlers]; + + const { name: pm } = detectPackageManager(); + + console.log( + `\x1b[44m${outputPrefix} Running C3 with command: \`${cmd} ${args.join( + " " + )}\` (using ${pm})\x1b[0m` + ); + const stdout: string[] = []; const stderr: string[] = []; @@ -49,7 +63,6 @@ export const runC3 = async ({ const currentDialog = promptHandlers[0]; lines.forEach(async (line) => { - // Uncomment to debug test output if (filterLine(line)) { console.log(`${outputPrefix} ${line}`); } @@ -57,7 +70,7 @@ export const runC3 = async ({ if (currentDialog && currentDialog.matcher.test(line)) { // Add a small sleep to avoid input race - await sleep(500); + await sleep(1000); currentDialog.input.forEach((keystroke) => { proc.stdin.write(keystroke); @@ -116,7 +129,10 @@ export const testProjectDir = (suite: string) => { const clean = (suffix: string) => { const path = getPath(suffix); if (existsSync(path)) { - rmSync(path, { recursive: true, force: true }); + rmSync(path, { + recursive: true, + force: true, + }); } }; diff --git a/packages/create-cloudflare/e2e-tests/pages.test.ts b/packages/create-cloudflare/e2e-tests/pages.test.ts index 6a0778e56425..9ee5ff1abbf7 100644 --- a/packages/create-cloudflare/e2e-tests/pages.test.ts +++ b/packages/create-cloudflare/e2e-tests/pages.test.ts @@ -5,18 +5,18 @@ import { fetch } from "undici"; import { describe, expect, test, afterEach, beforeEach } from "vitest"; import { version } from "../package.json"; import { deleteProject } from "../scripts/e2eCleanup"; +import { frameworkCliMap } from "../src/frameworks/package.json"; import { frameworkToTest } from "./frameworkToTest"; import { isQuarantineMode, keys, runC3, testProjectDir } from "./helpers"; import type { RunnerConfig } from "./helpers"; - -/* -Areas for future improvement: -- Add support for frameworks with global installs (like docusaurus, gatsby, etc) -*/ +import type { TestContext } from "vitest"; const TEST_TIMEOUT = 1000 * 60 * 3; +const frameworks = Object.keys(frameworkCliMap); + type FrameworkTestConfig = RunnerConfig & { + timeout?: number; expectResponseToContain: string; testCommitMessage: boolean; }; @@ -24,13 +24,23 @@ type FrameworkTestConfig = RunnerConfig & { describe.concurrent(`E2E: Web frameworks`, () => { const { getPath, getName, clean } = testProjectDir("pages"); + const getFrameworkNameFromTestContext = (ctx: TestContext) => { + const framework = ctx.meta.name.replace(/^Quarantined: /, ""); + if (!frameworks.includes(framework)) { + throw new Error( + `Error: Invalid test name, could not detect current framework from it` + ); + } + return framework; + }; + beforeEach((ctx) => { - const framework = ctx.meta.name; + const framework = getFrameworkNameFromTestContext(ctx); clean(framework); }); afterEach(async (ctx) => { - const framework = ctx.meta.name; + const framework = getFrameworkNameFromTestContext(ctx); clean(framework); // Cleanup the pages project in case we need to retry it @@ -57,6 +67,7 @@ describe.concurrent(`E2E: Web frameworks`, () => { framework, "--deploy", "--no-open", + "--no-git", ]; args.push(...argv); @@ -108,7 +119,7 @@ describe.concurrent(`E2E: Web frameworks`, () => { const { output } = await runCli(framework, { overrides, promptHandlers, - argv: [...(argv ?? []), "--deploy", "--no-git"], + argv: [...(argv ?? [])], }); // Verify deployment @@ -140,9 +151,25 @@ describe.concurrent(`E2E: Web frameworks`, () => { // These are ordered based on speed and reliability for ease of debugging const frameworkTests: Record = { astro: { - expectResponseToContain: "Welcome to Astro", + expectResponseToContain: "Hello, Astronaut!", + testCommitMessage: true, + }, + docusaurus: { + expectResponseToContain: "Dinosaurs are cool", testCommitMessage: true, }, + gatsby: { + quarantine: true, + expectResponseToContain: "Gatsby!", + promptHandlers: [ + { + matcher: /Would you like to use a template\?/, + input: ["n"], + }, + ], + testCommitMessage: true, + timeout: 1000 * 60 * 6, + }, hono: { expectResponseToContain: "Hello Hono!", testCommitMessage: false, @@ -242,7 +269,7 @@ describe.concurrent(`E2E: Web frameworks`, () => { frameworkTests[framework].testCommitMessage ); }, - { retry: 3, timeout: TEST_TIMEOUT } + { retry: 3, timeout: config.timeout || TEST_TIMEOUT } ); }); diff --git a/packages/create-cloudflare/src/frameworks/astro/index.ts b/packages/create-cloudflare/src/frameworks/astro/index.ts index 2c2d0186a56b..916ac7304621 100644 --- a/packages/create-cloudflare/src/frameworks/astro/index.ts +++ b/packages/create-cloudflare/src/frameworks/astro/index.ts @@ -49,7 +49,7 @@ const config: FrameworkConfig = { "--no-install", "--no-git", "--template", - "basics", + "blog", "--typescript", "strict", ], diff --git a/packages/create-cloudflare/src/frameworks/remix/index.ts b/packages/create-cloudflare/src/frameworks/remix/index.ts index 5d48c339ce7a..926edfdd4051 100644 --- a/packages/create-cloudflare/src/frameworks/remix/index.ts +++ b/packages/create-cloudflare/src/frameworks/remix/index.ts @@ -24,6 +24,6 @@ const config: FrameworkConfig = { "pages:deploy": `${npm} run build && wrangler pages deploy ./public`, }, devCommand: "dev", - testFlags: ["--typescript", "--no-install"], + testFlags: ["--typescript", "--no-install", "--no-git-init"], }; export default config; diff --git a/packages/create-cloudflare/src/helpers/packages.ts b/packages/create-cloudflare/src/helpers/packages.ts index 768b9627b407..66c7d0077c0b 100644 --- a/packages/create-cloudflare/src/helpers/packages.ts +++ b/packages/create-cloudflare/src/helpers/packages.ts @@ -19,10 +19,12 @@ export const detectPackageManager = () => { case "pnpm": name = "pnpm"; version = devDependencies["pnpm"].replace("^", ""); + process.env.npm_config_user_agent = "pnpm"; break; case "yarn": name = "yarn"; version = devDependencies["yarn"].replace("^", ""); + process.env.npm_config_user_agent = "yarn"; break; case "bun": name = "bun"; @@ -31,6 +33,7 @@ export const detectPackageManager = () => { case "npm": name = "npm"; version = "0.0.0"; + process.env.npm_config_user_agent = "npm"; break; } } diff --git a/packages/create-cloudflare/turbo.json b/packages/create-cloudflare/turbo.json index 978dacea0540..f0b50391ed8b 100644 --- a/packages/create-cloudflare/turbo.json +++ b/packages/create-cloudflare/turbo.json @@ -4,7 +4,7 @@ "pipeline": { "build": { - "env": ["VITEST", "TEST_PM", "CI"] + "env": ["VITEST", "TEST_PM", "npm_config_user_agent", "CI"] }, "test:e2e:*": { "env": [