import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { describe, expect, it } from "vitest"; type WebAccessibleResource = { matches: string[]; resources: string[]; use_dynamic_url?: boolean; }; type ExtensionManifest = { web_accessible_resources?: WebAccessibleResource[]; }; function readManifest(target: "chrome" | "firefox"): ExtensionManifest { const directory = target === "chrome" ? "dist-chrome" : "dist-firefox"; return JSON.parse( readFileSync(resolve(process.cwd(), directory, "manifest.json"), "utf8"), ) as ExtensionManifest; } describe("shipped web-accessible resources", () => { it("allows Chrome content-script chunks from stable extension URLs", () => { const resources = readManifest("chrome").web_accessible_resources ?? []; expect(resources).toHaveLength(1); expect(resources[0]?.use_dynamic_url).toBe(false); expect(resources[0]?.matches).toEqual([""]); expect(resources[0]?.resources.length).toBeGreaterThan(0); }); it("keeps Firefox resources limited to content-script chunks with content hashes", () => { const resources = readManifest("firefox").web_accessible_resources ?? []; const files = resources.flatMap((entry) => entry.resources); expect(files.length).toBeGreaterThan(0); expect(files.every((file) => /^assets\/[^/]+-[A-Za-z0-9_-]+\.(?:js|css)$/.test(file))).toBe(true); expect(files.every((file) => !file.includes(""))).toBe(true); }); });