testPollsExample
the polls example builds, passes its tests, and runs in a browser
import { CHROME, pageText } from "#codebase/tcmts/cli/test/browser"; import { env, exampleDir, hashOf } from "#codebase/tcmts/cli/test/e2e/examples"; import { tcmBin, tempDir, withChildren } from "#codebase/tcmts/cli/test/e2e/harness"; import { POLLS } from "#codebase/tcmts/fixtures"; import assert from "node:assert/strict"; import { spawn, spawnSync } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; import { stripVTControlCharacters } from "node:util"; export const testPollsExample = async () => { if (!CHROME) return console.log("skipped: no Chrome"); const dir = path.join(tempDir("examples"), "polls"); const setup = spawnSync(path.join(exampleDir(POLLS), "setup.sh"), [dir], { env: env(), encoding: "utf8", }); const out = stripVTControlCharacters(setup.stdout + setup.stderr); assert.equal(setup.status, 0, out); assert.match(out, /9 passed, 0 failed/); assert.ok( fs.existsSync(path.join(dir, "scratch.ts")) && !fs.existsSync(path.join(dir, "server.ts")), "only the playground is left as a file", ); await withChildren(async (keep) => { const child = keep( spawn(process.execPath, [tcmBin(), "start", "polls.main", "--port", "0"], { cwd: dir, env: env(), }), ); let log = ""; child.stdout.setEncoding("utf8").on("data", (d: string) => (log += d)); child.stderr.setEncoding("utf8").on("data", (d: string) => (log += d)); for (const end = Date.now() + 60000; !/url\s+http/.test(log) && Date.now() < end;) await new Promise((r) => setTimeout(r, 100)); const url = /url\s+(http:\/\/\S+)/.exec(log)?.[1]; assert.ok(url, log); const call = async (name: string, args: unknown[]) => { const r = await fetch(new URL(`/__tcm/rpc/${hashOf(name, dir)}`, url), { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(args), }); assert.equal(r.status, 200, await r.clone().text()); return r.json(); }; const id = await call("polls.createPoll", ["Tabs or spaces?", ["tabs", "spaces"], 5]); await call("polls.vote", [id, 0]); // the page lists the poll and streams its tally from the server const text = await pageText(url!, "main", (t) => /tabs is ahead/.test(t)); assert.match(text, /Tabs or spaces\?/); assert.match(text, /tabs\s+█+\s+100% \(1\)/); }); }