← Files aictrl.devARCHIVED FILE

templates/blocks.example.cjs

1.73 KB · Sep 30, 2026 · 22:54 UTC

↓ Download file

/* Example demo/blocks.cjs — the per-repo journey, one block per narration
 * segment. The framework (record-demo.cjs) provides the api; this file owns
 * WHAT is shown. Copy into the host repo's demo/ dir and rewrite the blocks
 * against the app's REAL on-screen strings (scrape-text.cjs dumps them).
 *
 * Rules that keep the take time-locked:
 * - Call setT0() exactly when narration should start (after the first page is
 *   visually settled). Everything before it is trimmed by assemble.cjs.
 * - EVERY block ends with `await until(B[i])` — the narration boundary.
 * - Wrap optional flourishes in glideTo(...) — it logs a WARN and moves on if
 *   the element is missing, costing ~2s, not a blown take.
 * - A take that logs "WARN: block overran" is garbage; tighten the block.
 */
module.exports = async function run(api) {
  const { page, config, B, until, sleep, glideTo, slowWheel, setT0 } = api;
  const BASE = config.app.baseUrl;

  // ---- Block 1: opening scene [t0 - B1] ----
  await page.goto(`${BASE}/`, { waitUntil: 'domcontentloaded', timeout: 45000 });
  await page.getByText(new RegExp(config.app.readyText, 'i')).first()
    .waitFor({ timeout: 15000 }).catch(() => console.log('[blocks] WARN: ready text not found'));
  await sleep(800);
  setT0(); // narration starts here
  await sleep(2000);
  await slowWheel(300, 4000);
  await until(B[1]);

  // ---- Block 2: a feature page [B1 - B2] ----
  await page.goto(`${BASE}/features`, { waitUntil: 'domcontentloaded', timeout: 45000 });
  await sleep(800);
  await glideTo(page.getByRole('heading').first(), 1000);
  await sleep(1500);
  await slowWheel(400, 3000);
  await until(B[2]);

  // ---- closing hold: past narration end, for the fade ----
  await until(B[B.length - 1] + 1.2);
};

SHA-256: a7963492265938cea37ee3d459a9a3e0225990b62f42f1ac12b65f126ac208dd