1import { readFileSync } from "node:fs";2import { resolve } from "node:path";3import { describe, expect, it } from "vitest";45type WebAccessibleResource = {6 matches: string[];7 resources: string[];8 use_dynamic_url?: boolean;9};1011type ExtensionManifest = {12 web_accessible_resources?: WebAccessibleResource[];13};1415function readManifest(target: "chrome" | "firefox"): ExtensionManifest {16 const directory = target === "chrome" ? "dist-chrome" : "dist-firefox";17 return JSON.parse(18 readFileSync(resolve(process.cwd(), directory, "manifest.json"), "utf8"),19 ) as ExtensionManifest;20}2122describe("shipped web-accessible resources", () => {23 it("uses session-randomized URLs for Chrome content-script resources", () => {24 const resources = readManifest("chrome").web_accessible_resources ?? [];2526 expect(resources).toHaveLength(1);27 expect(resources[0]?.use_dynamic_url).toBe(true);28 expect(resources[0]?.matches).toEqual(["<all_urls>"]);29 expect(resources[0]?.resources.length).toBeGreaterThan(0);30 });3132 it("keeps Firefox resources limited to content-script chunks with content hashes", () => {33 const resources = readManifest("firefox").web_accessible_resources ?? [];34 const files = resources.flatMap((entry) => entry.resources);3536 expect(files.length).toBeGreaterThan(0);37 expect(files.every((file) => /^assets\/[^/]+-[A-Za-z0-9_-]+\.(?:js|css)$/.test(file))).toBe(true);38 expect(files.every((file) => !file.includes("<dynamic_resource>"))).toBe(true);39 });40});