testKeptBuildWithoutItsCode
a kept build whose code the codebase no longer has (the web UI's, its codebase copied in again when tcm changes): its tabs are told to reload (410), and the server keeps answering
import { plainEnv, tcmBin, withChildren } from "#codebase/tcmts/cli/test/e2e/harness"; import { call, setUp, waitFor } from "#codebase/tcmts/cli/test/e2e/prod"; import { hashOf } from "#codebase/tcmts/cli/test/e2e/web"; import assert from "node:assert/strict"; import { spawn } from "node:child_process"; import type { ChildProcess } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; export const testKeptBuildWithoutItsCode = () => withChildren(async (keep) => { const app = (greeting: string) => `// tcm: namespace app import { hostname } from "node:os"; export async function greeting(name: string): Promise<string> { return "${greeting} " + name + " from " + hostname(); } export async function main() { document.querySelector("#app")!.textContent = await greeting("ada"); } `; // the old codebase's build, kept beside a new codebase that never had its code const old = setUp(); old.scratch(app("hello")); old.tcm("add"); old.tcm("build", "app.main"); const stale = hashOf(old.dir, "app.greeting"); const { dir, tcm, scratch } = setUp(); scratch(app("hi")); tcm("add"); tcm("build", "app.main"); const apps = (d: string) => path.join(d, ".tcm", "apps"); for (const b of fs.readdirSync(apps(old.dir))) if (fs.existsSync(path.join(apps(old.dir), b, "tcm-app.json"))) fs.cpSync(path.join(apps(old.dir), b), path.join(apps(dir), b), { recursive: true }); const child: ChildProcess = keep( spawn(process.execPath, [tcmBin(), "start", "app.main", "--port", "0"], { cwd: dir, env: plainEnv(), }), ); let out = ""; child.stdout!.setEncoding("utf8").on("data", (d: string) => (out += d)); child.stderr!.setEncoding("utf8").on("data", (d: string) => (out += d)); await waitFor(() => /url\s+http:\/\/\S+/.test(out)); const url = /url\s+(http:\/\/\S+)/.exec(out)![1]!; assert.equal((await call(url, stale, ["ada"])).status, 410, "the old build's tab reloads"); assert.equal(child.exitCode, null, "the server is still running"); assert.match((await call(url, hashOf(dir, "app.greeting"), ["ada"])).body, /^"hi ada from /); })