import { test, expect, type Locator, type Page } from "@playwright/test"; import { copyFileSync, existsSync, readFileSync, rmSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; // --------------------------------------------------------------------------- // Notes on a report video (lib/annotations, components/notes): // // video-notes-fixture a GENERATED manifest (`generatedBy`) with a built cut, // its schedule, and one take (`alt`) with its own. WRITES // its notes.json; every test starts from the fixture's // manifest and no notes. // // What is proved: a timed note at a second of the built cut and of a take's // preview, resolved to the entry on screen; take notes and row notes; and that // an edit made here to a generated manifest leaves an `edit` note, coalesced, // and gone again when the edit is put back. // --------------------------------------------------------------------------- const HERE = path.dirname(fileURLToPath(import.meta.url)); const DIR = path.join(HERE, "..", ".e2e-song", "reports", "video-notes-fixture"); const MANIFEST = path.join(DIR, "video.manifest.json"); const PRISTINE = path.join(DIR, "video.manifest.pristine"); const NOTES = path.join(DIR, "notes.json"); const PROJECT = "reports/video-notes-fixture"; const PAGE = `/browse/${PROJECT}`; type Note = { id: string; status: string; author: string; text: string; anchor: Record; replies: unknown[] }; const notesOnDisk = (): Note[] => (existsSync(NOTES) ? JSON.parse(readFileSync(NOTES, "utf8")).notes : []); test.beforeAll(() => { if (!existsSync(PRISTINE)) copyFileSync(MANIFEST, PRISTINE); }); test.beforeEach(() => { copyFileSync(PRISTINE, MANIFEST); rmSync(NOTES, { force: true }); rmSync(path.join(DIR, "revisions"), { recursive: true, force: true }); }); /** Seek a