/** * Regression guard — a guest-authored caption cannot brick the offline keepsake. * * The viewer's data is inlined as `` (it must be: * guests open index.html over file://, where a cross-origin fetch of a sibling data.json is * blocked). Captions and comments are guest text and land in that payload. * * The escape used to be `` * round-trips inert. It does NOT stop the caption steering the HTML TOKENIZER: `` drives the parser into script-data-double-escaped state, where the template's own * `` steps back to script-data-escaped instead of closing the element. Everything after — * including the viewer bundle — is swallowed as script data. Nothing executes and nothing leaks; * `__EXPORT_DATA__` is never assigned and the keepsake renders blank. * * What makes it worth a browser-level test rather than a unit test alone: the failure is SILENT and * POST-DISTRIBUTION. The export succeeds, the ZIP is well-formed, the job writes `done`, * /export/status is green, and the host hands out a file that only fails when a guest * double-clicks it — in every copy, unfixably. It is not visible by reading the escape. It is only * visible by running a real parser over the real artifact, which is what this does: release, pull * the actual Memories.zip, extract index.html, open it over file:// in Chromium, and assert the * viewer actually booted. * * The near-miss worth recording: `` comes back CLEAN, because the * trailing `-->` returns the parser to script-data state. A probe using the terminated form * quietly repairs the very thing it is testing for. Only the unterminated variant exposes it. */ import { test, expect } from '../../fixtures/test'; import { execFileSync } from 'node:child_process'; import { mkdtempSync, writeFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { seedUpload } from '../../helpers/seed'; import { BASE } from '../../helpers/env'; /** Unterminated on purpose — see the header. The terminated form self-repairs. */ const TOKENIZER_PAYLOAD = '