| 
 | 1 | +import { cp } from "fs/promises";  | 
 | 2 | +import promiseSpawn from "@npmcli/promise-spawn";  | 
 | 3 | +import { dirname, join, relative } from "path";  | 
 | 4 | +import { fileURLToPath } from "url";  | 
 | 5 | +import { parse as parseYaml } from "yaml";  | 
 | 6 | +import { spawn } from "child_process";  | 
 | 7 | +import fsExtra from "fs-extra";  | 
 | 8 | +import { scenarios } from "./scenarios.ts";  | 
 | 9 | + | 
 | 10 | +const { readFileSync, mkdirp, rmdir } = fsExtra;  | 
 | 11 | + | 
 | 12 | +const __dirname = dirname(fileURLToPath(import.meta.url));  | 
 | 13 | + | 
 | 14 | +const errors: any[] = [];  | 
 | 15 | + | 
 | 16 | +await rmdir(join(__dirname, "runs"), { recursive: true }).catch(() => undefined);  | 
 | 17 | + | 
 | 18 | +// Run each scenario  | 
 | 19 | +for (const [scenarioName, scenario] of scenarios) {  | 
 | 20 | +  console.log(  | 
 | 21 | +    `\n\n${"=".repeat(80)}\n${" ".repeat(  | 
 | 22 | +      5,  | 
 | 23 | +    )}RUNNING SCENARIO: ${scenarioName.toUpperCase()}${" ".repeat(5)}\n${"=".repeat(80)}`,  | 
 | 24 | +  );  | 
 | 25 | + | 
 | 26 | +  const runId = `${scenarioName}-${Math.random().toString().split(".")[1]}`;  | 
 | 27 | +  const cwd = join(__dirname, "runs", runId);  | 
 | 28 | +  await mkdirp(cwd);  | 
 | 29 | + | 
 | 30 | +  const starterTemplateDir = scenarioName.includes("nextjs")  | 
 | 31 | +    ? "../../../starters/nextjs/basic"  | 
 | 32 | +    : "../../../starters/angular/basic";  | 
 | 33 | +  console.log(`[${runId}] Copying ${starterTemplateDir} to working directory`);  | 
 | 34 | +  await cp(starterTemplateDir, cwd, { recursive: true });  | 
 | 35 | + | 
 | 36 | +  // Run scenario-specific setup if provided  | 
 | 37 | +  if (scenario.setup) {  | 
 | 38 | +    console.log(`[${runId}] Running setup for ${scenarioName}`);  | 
 | 39 | +    await scenario.setup(cwd);  | 
 | 40 | +  }  | 
 | 41 | + | 
 | 42 | +  console.log(`[${runId}] > npm ci --silent --no-progress`);  | 
 | 43 | +  await promiseSpawn("npm", ["ci", "--silent", "--no-progress"], {  | 
 | 44 | +    cwd,  | 
 | 45 | +    stdio: "inherit",  | 
 | 46 | +    shell: true,  | 
 | 47 | +  });  | 
 | 48 | + | 
 | 49 | +  const buildScript = relative(cwd, join(__dirname, "../dist/bin/localbuild.js"));  | 
 | 50 | +  const buildLogPath = join(cwd, "build.log");  | 
 | 51 | +  console.log(`[${runId}] > node ${buildScript} (output written to ${buildLogPath})`);  | 
 | 52 | + | 
 | 53 | +  const packageJson = JSON.parse(readFileSync(join(cwd, "package.json"), "utf-8"));  | 
 | 54 | +  const frameworkVersion = scenarioName.includes("nextjs")  | 
 | 55 | +    ? packageJson.dependencies.next.replace("^", "")  | 
 | 56 | +    : JSON.parse(  | 
 | 57 | +        readFileSync(join(cwd, "node_modules", "@angular", "core", "package.json"), "utf-8"),  | 
 | 58 | +      ).version;  | 
 | 59 | + | 
 | 60 | +  try {  | 
 | 61 | +    await promiseSpawn("node", [buildScript, ...scenario.inputs], {  | 
 | 62 | +      cwd,  | 
 | 63 | +      stdioString: true,  | 
 | 64 | +      stdio: "pipe",  | 
 | 65 | +      shell: true,  | 
 | 66 | +      env: {  | 
 | 67 | +        ...process.env,  | 
 | 68 | +        FRAMEWORK_VERSION: frameworkVersion,  | 
 | 69 | +      },  | 
 | 70 | +    }).then((result) => {  | 
 | 71 | +      // Write stdout and stderr to the log file  | 
 | 72 | +      fsExtra.writeFileSync(buildLogPath, result.stdout + result.stderr);  | 
 | 73 | +    });  | 
 | 74 | + | 
 | 75 | +    try {  | 
 | 76 | +      // Determine which test files to run  | 
 | 77 | +      const testPattern = scenario.tests  | 
 | 78 | +        ? scenario.tests.map((test) => `e2e/${test}`).join(" ")  | 
 | 79 | +        : "e2e/*.spec.ts";  | 
 | 80 | + | 
 | 81 | +      console.log(`> SCENARIO=${scenarioName} ts-mocha -p tsconfig.json ${testPattern}`);  | 
 | 82 | + | 
 | 83 | +      await promiseSpawn("ts-mocha", ["-p", "tsconfig.json", ...testPattern.split(" ")], {  | 
 | 84 | +        shell: true,  | 
 | 85 | +        stdio: "inherit",  | 
 | 86 | +        env: {  | 
 | 87 | +          ...process.env,  | 
 | 88 | +          SCENARIO: scenarioName,  | 
 | 89 | +          RUN_ID: runId,  | 
 | 90 | +        },  | 
 | 91 | +      });  | 
 | 92 | +    } catch (e) {  | 
 | 93 | +      errors.push(e);  | 
 | 94 | +    }  | 
 | 95 | +  } catch (e) {  | 
 | 96 | +    console.error(`Error in scenario ${scenarioName}:`, e);  | 
 | 97 | +    errors.push(e);  | 
 | 98 | +  }  | 
 | 99 | + | 
 | 100 | +  if (errors.length) {  | 
 | 101 | +    console.error(errors);  | 
 | 102 | +    process.exit(1);  | 
 | 103 | +  }  | 
 | 104 | +}  | 
0 commit comments