/** * Resilience test for a missing PDF render engine (OPL-2653). * * The desktop server bundle externalizes playwright-core. If it was not copied * into the packaged bundle, the first runtime access fails with a module-load * error (e.g. turbopack's "Failed to load external module playwright-core-…"). * `launchBrowser` must convert that into the typed PdfBrowserLaunchError sentinel * so PDF routes degrade gracefully (report -> 503, invoice -> libpdf fallback) * instead of leaking a bare 500. * * The failure is simulated through runtime.ts's import seam * (__setPlaywrightCoreImportForTests) rather than mock.module("playwright-core"): * bun's module mocks are process-global and leak across test files in * platform-dependent file order — on Linux CI a module mock here made * runtime.test.ts's static `chromium` import undefined and silently skipped * renderer.smoke.test.ts. The seam scopes the poison to exactly these tests. */ import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { __setPlaywrightCoreImportForTests, launchBrowser, PdfBrowserLaunchError, } from "./runtime"; beforeAll(() => { __setPlaywrightCoreImportForTests(() => { throw new Error("Failed to load external module playwright-core-deadbeef"); }); }); afterAll(() => { __setPlaywrightCoreImportForTests(null); }); describe("launchBrowser when playwright-core cannot be loaded", () => { test("local: a module-load failure surfaces as PdfBrowserLaunchError", async () => { await expect(launchBrowser("local")).rejects.toBeInstanceOf( PdfBrowserLaunchError, ); }); test("serverless: a module-load failure surfaces as PdfBrowserLaunchError", async () => { await expect(launchBrowser("serverless")).rejects.toBeInstanceOf( PdfBrowserLaunchError, ); }); });