import { readFileSync, existsSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
// HTML-structure smoke test for the release-announcement composition. We
// parse the HTML as text and assert structural invariants — no jsdom mount,
// no rendering. The render-truth check lives on the sidecar; this test only
// guards the authoring-side contract: dimensions, props.js wiring, theme
// link, timed clips, and the offline-render constraint (no CDN scripts).
const here = dirname(fileURLToPath(import.meta.url));
const dir = here;
const read = (name) => readFileSync(join(dir, name), "utf8");
const orientations = [
{ file: "vertical.html", height: "1920" },
{ file: "square.html", height: "1080" },
];
describe("release-announcement composition", () => {
it("ships props.js (default preview values, sidecar overwrites at render)", () => {
expect(existsSync(join(dir, "props.js"))).toBe(true);
const src = read("props.js");
expect(src).toContain("window.__PROPS__");
expect(src).toContain("window.__ORIENTATION__");
});
it("ships theme.css", () => {
expect(existsSync(join(dir, "theme.css"))).toBe(true);
});
it.each(orientations)("$file parses with correct dimensions and wiring", ({ file, height }) => {
const html = read(file);
// HyperFrames render params on .
expect(html).toContain('data-width="1080"');
expect(html).toContain(`data-height="${height}"`);
expect(html).toMatch(/data-duration="\d+"/);
expect(html).toMatch(/data-fps="\d+"/);
// props.js is loaded before the inline script reads window.__PROPS__.
expect(html).toContain('');
// theme.css is linked.
expect(html).toContain('href="theme.css"');
// At least one timed clip element.
expect(html).toMatch(/class="[^"]*clip[^"]*"/);
// No CDN scripts — the render is offline. Fonts load via @font-face from
// ../../public/fonts/, never from a CDN.
expect(html).not.toMatch(/