From 7364f71a8c5e468f98a4b97581a88948f111caa8 Mon Sep 17 00:00:00 2001 From: Marcus Schiesser <mail@marcusschiesser.de> Date: Wed, 6 Dec 2023 13:46:37 +0700 Subject: [PATCH] refactor: cleaned e2e test code --- e2e/basic.spec.ts | 123 ++-------------------------------------------- e2e/utils.ts | 118 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 119 deletions(-) create mode 100644 e2e/utils.ts diff --git a/e2e/basic.spec.ts b/e2e/basic.spec.ts index dbaeb4b9..9e726330 100644 --- a/e2e/basic.spec.ts +++ b/e2e/basic.spec.ts @@ -1,33 +1,17 @@ /* eslint-disable turbo/no-undeclared-env-vars */ import { expect, test } from "@playwright/test"; -import { ChildProcess, exec } from "child_process"; -import { execSync } from "node:child_process"; -import crypto from "node:crypto"; -import { mkdir } from "node:fs/promises"; -import { fileURLToPath } from "node:url"; -import waitPort from "wait-port"; import type { TemplateEngine, TemplateFramework, TemplateType, TemplateUI, } from "../templates"; - -let cwd: string; -test.beforeEach(async () => { - cwd = fileURLToPath( - new URL(`.cache/${crypto.randomUUID()}`, import.meta.url), - ); - await mkdir(cwd, { recursive: true }); -}); - -type AppType = "--frontend" | "--no-frontend" | ""; +import { createTestDir, runApp, runCreateLlama, type AppType } from "./utils"; const templateTypes: TemplateType[] = ["streaming"]; const templateFrameworks: TemplateFramework[] = ["express"]; const templateEngines: TemplateEngine[] = ["simple"]; const templateUIs: TemplateUI[] = ["html"]; -const MODEL = "gpt-3.5-turbo"; for (const templateType of templateTypes) { for (const templateFramework of templateFrameworks) { @@ -44,7 +28,9 @@ for (const templateType of templateTypes) { test(`try create-llama ${templateType} ${templateFramework} ${templateEngine} ${templateUI} ${appType}`, async ({ page, }) => { + const cwd = await createTestDir(); const name = runCreateLlama( + cwd, templateType, templateFramework, templateEngine, @@ -53,7 +39,7 @@ for (const templateType of templateTypes) { ); const port = Math.floor(Math.random() * 10000) + 10000; - const cps = await runApp(name, appType, port); + const cps = await runApp(cwd, name, appType, port); // test frontend await page.goto(`http://localhost:${port}`); @@ -66,104 +52,3 @@ for (const templateType of templateTypes) { } } } - -async function runApp( - name: string, - appType: AppType, - port: number, -): Promise<ChildProcess[]> { - const cps = []; - - try { - switch (appType) { - case "--no-frontend": - cps.push( - await createProcess("npm run dev", `${cwd}/${name}/backend`, port), - ); - break; - case "--frontend": - cps.push( - await createProcess( - "npm run dev", - `${cwd}/${name}/backend`, - port + 1, - ), - ); - cps.push( - await createProcess("npm run dev", `${cwd}/${name}/frontend`, port), - ); - break; - default: - cps.push(await createProcess("npm run dev", `${cwd}/${name}`, port)); - break; - } - } catch (e) { - cps.forEach((cp) => cp.kill()); - throw e; - } - return cps; -} - -async function createProcess(command: string, cwd: string, port: number) { - const cp = exec(command, { - cwd, - env: { - ...process.env, - PORT: `${port}`, - }, - }); - if (!cp) throw new Error(`Can't start process ${command} in ${cwd}`); - - await waitPort({ - host: "localhost", - port, - timeout: 1000 * 60, - }); - return cp; -} - -function runCreateLlama( - templateType: string, - templateFramework: string, - templateEngine: string, - templateUI: string, - appType: AppType, -) { - const createLlama = fileURLToPath( - new URL("../dist/index.js", import.meta.url), - ); - - const name = [ - templateType, - templateFramework, - templateEngine, - templateUI, - appType, - ].join("-"); - const command = [ - "node", - createLlama, - name, - "--template", - templateType, - "--framework", - templateFramework, - "--engine", - templateEngine, - "--ui", - templateUI, - "--model", - MODEL, - "--open-ai-key", - "testKey", // TODO: pass in OPEN_AI_KEY from CI env if needed for tests - appType, - "--eslint", - "--use-npm", - ].join(" "); - console.log(`running command '${command}' in ${cwd}`); - execSync(command, { - stdio: "inherit", - cwd, - }); - return name; -} diff --git a/e2e/utils.ts b/e2e/utils.ts new file mode 100644 index 00000000..75e2a619 --- /dev/null +++ b/e2e/utils.ts @@ -0,0 +1,118 @@ +import { ChildProcess, exec, execSync } from "child_process"; +import crypto from "node:crypto"; +import { mkdir } from "node:fs/promises"; +import { fileURLToPath } from "node:url"; +import waitPort from "wait-port"; + +export type AppType = "--frontend" | "--no-frontend" | ""; +const MODEL = "gpt-3.5-turbo"; + +export async function runApp( + cwd: string, + name: string, + appType: AppType, + port: number, +): Promise<ChildProcess[]> { + const cps = []; + + try { + switch (appType) { + case "--no-frontend": + cps.push( + await createProcess("npm run dev", `${cwd}/${name}/backend`, port), + ); + break; + case "--frontend": + cps.push( + await createProcess( + "npm run dev", + `${cwd}/${name}/backend`, + port + 1, + ), + ); + cps.push( + await createProcess("npm run dev", `${cwd}/${name}/frontend`, port), + ); + break; + default: + cps.push(await createProcess("npm run dev", `${cwd}/${name}`, port)); + break; + } + } catch (e) { + cps.forEach((cp) => cp.kill()); + throw e; + } + return cps; +} + +async function createProcess(command: string, cwd: string, port: number) { + const cp = exec(command, { + cwd, + env: { + ...process.env, + PORT: `${port}`, + }, + }); + if (!cp) throw new Error(`Can't start process ${command} in ${cwd}`); + + await waitPort({ + host: "localhost", + port, + timeout: 1000 * 60, + }); + return cp; +} + +export function runCreateLlama( + cwd: string, + templateType: string, + templateFramework: string, + templateEngine: string, + templateUI: string, + appType: AppType, +) { + const createLlama = fileURLToPath( + new URL("../dist/index.js", import.meta.url), + ); + + const name = [ + templateType, + templateFramework, + templateEngine, + templateUI, + appType, + ].join("-"); + const command = [ + "node", + createLlama, + name, + "--template", + templateType, + "--framework", + templateFramework, + "--engine", + templateEngine, + "--ui", + templateUI, + "--model", + MODEL, + "--open-ai-key", + "testKey", + appType, + "--eslint", + "--use-npm", + ].join(" "); + console.log(`running command '${command}' in ${cwd}`); + execSync(command, { + stdio: "inherit", + cwd, + }); + return name; +} +export async function createTestDir() { + const cwd = fileURLToPath( + new URL(`.cache/${crypto.randomUUID()}`, import.meta.url), + ); + await mkdir(cwd, { recursive: true }); + return cwd; +} -- GitLab