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