fuzzyworld

when-am-i / files / scripts / generate-screenshots.mts

generate-screenshots.mts

Blame: the commit that last changed each line · file · history

48a625b7 2026-06-19 Pavel Safronov1// Generate documentation screenshots of key app states.
2//
3// Forces deterministic state via URL params (the same hook the app reads), so
4// shots are reproducible. Output: screenshots/app/. Run from the repo root:
5// npm run screenshot
6
7import { chromium } from 'playwright';
8import { mkdir, rm } from 'node:fs/promises';
9import path from 'node:path';
10import { startDevServer, BASE_URL, REPO_ROOT } from './lib/server.mts';
11
12const OUT_DIR = path.join(REPO_ROOT, 'screenshots', 'app');
13
14const STATES = [
76ecf55e 2026-06-21 Pavel Safronov15 { name: '01-landing', query: '', desc: "Landing (today's date, no pin)" },
48a625b7 2026-06-19 Pavel Safronov16 {
143b640c 2026-06-19 Pavel Safronov17 name: '02-boston-1650',
18 query: '?lat=42.32&lng=-71.06&zoom=10&year=1650&month=6&day=15',
19 desc: 'Boston, 1650 — coexistence (Massachusett + colonial Julian)',
48a625b7 2026-06-19 Pavel Safronov20 },
21 {
68dcf3ed 2026-06-25 Pavel Safronov22 name: '03-boston-1752',
23 query: '?lat=42.32&lng=-71.06&zoom=10&year=1752&month=9&day=20',
24 desc: 'Boston, 1752 — the British Julian→Gregorian switch mid-September (day-of-year track splits)',
25 },
26 {
27 name: '04-boston-1800',
143b640c 2026-06-19 Pavel Safronov28 query: '?lat=42.32&lng=-71.06&zoom=10&year=1800&month=6&day=15',
48a625b7 2026-06-19 Pavel Safronov29 desc: 'Boston, 1800 — Gregorian',
30 },
31];
32
33async function run() {
34 console.log('\n📸 Generating app screenshots…\n');
35 const server = await startDevServer();
36 try {
37 await rm(OUT_DIR, { recursive: true, force: true });
38 await mkdir(OUT_DIR, { recursive: true });
39
40 const browser = await chromium.launch();
41 const page = await browser.newPage({ viewport: { width: 1100, height: 920 }, deviceScaleFactor: 2 });
42
43 for (const state of STATES) {
44 await page.goto(`${BASE_URL}${state.query}`, { waitUntil: 'networkidle' });
45 await page.waitForTimeout(800); // let map tiles settle
46 const file = path.join(OUT_DIR, `${state.name}.png`);
d1eb8ad5 2026-06-19 Pavel Safronov47 await page.screenshot({ path: file, fullPage: true });
48a625b7 2026-06-19 Pavel Safronov48 console.log(` ✅ ${state.name} — ${state.desc}`);
49 }
50
51 await browser.close();
52 console.log('\n✨ Done — screenshots/app/\n');
53 } finally {
54 server.stop();
55 }
56}
57
58run().catch((err) => {
59 console.error(err);
60 process.exit(1);
61});