// @vitest-environment node import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { parseHTML } from "linkedom"; import { describe, it, expect } from "vitest"; import { bundleToSingleHtml } from "./htmlBundler"; function makeTempProject(files: Record): string { const dir = mkdtempSync(join(tmpdir(), "hf-bundler-test-")); for (const [rel, content] of Object.entries(files)) { const full = join(dir, rel); mkdirSync(join(full, ".."), { recursive: true }); writeFileSync(full, content, "utf-8"); } return dir; } describe("bundleToSingleHtml", () => { it("does not merge author scripts into the runtime bootstrap placeholder", async () => { const dir = makeTempProject({ "index.html": `
`, }); const bundled = await bundleToSingleHtml(dir); const runtimeBlock = bundled.match( /]*data-hyperframes-preview-runtime[^>]*>[\s\S]*?<\/script>/i, )?.[0]; expect(runtimeBlock).toBeDefined(); expect(runtimeBlock).not.toContain("getElementById"); expect(bundled).toContain('document.getElementById("scene")'); }); it("hoists external CDN scripts from sub-compositions into the bundle", async () => { const dir = makeTempProject({ "index.html": `
`, "compositions/rockets.html": ``, }); const bundled = await bundleToSingleHtml(dir); // Lottie CDN script from sub-composition must be present in the bundle expect(bundled).toContain( "https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js", ); // Should only appear once (deduped) const occurrences = (bundled.match(/cdnjs\.cloudflare\.com\/ajax\/libs\/lottie-web/g) ?? []) .length; expect(occurrences).toBe(1); // GSAP CDN from main doc should still be present expect(bundled).toContain("cdn.jsdelivr.net/npm/gsap"); // data-composition-src should be stripped (composition was inlined) expect(bundled).not.toContain("data-composition-src"); }); it("does not duplicate CDN scripts already present in the main document", async () => { const dir = makeTempProject({ "index.html": `
`, "compositions/child.html": ``, }); const bundled = await bundleToSingleHtml(dir); // GSAP CDN should appear exactly once (deduped) const gsapOccurrences = ( bundled.match(/cdn\.jsdelivr\.net\/npm\/gsap@3\.14\.2\/dist\/gsap\.min\.js/g) ?? [] ).length; expect(gsapOccurrences).toBe(1); }); it("inlines