mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
Sideloaded Widevine works on the first launch of a persistent context instead of needing a manual two-launch hint-file workaround. The wrapper writes Chromium's CDM hint file into the profile before launch when a WidevineCdm directory is present next to the binary. - New cloakbrowser/widevine.py and js/src/widevine.ts: resolve a sideloaded CDM (CLOAKBROWSER_WIDEVINE_CDM env var, else next to the binary) and seed the hint file. Linux only; no-op elsewhere. CLOAKBROWSER_WIDEVINE=0 disables. - Never bundles/downloads/copies the CDM (proprietary); seeds only when the user-provided CDM is already present. - Wired into launch_persistent_context[_async] and launchPersistentContext. - README + js/README: Widevine / DRM section, env vars, FPJS tradeoff note. - Tests: tests/test_widevine.py, js/tests/widevine.test.ts, persistent-context integration assertions.
58 lines
2.2 KiB
TypeScript
58 lines
2.2 KiB
TypeScript
import { describe, it, expect, vi, afterEach, beforeEach } from "vitest";
|
|
|
|
// Assert the persistent-context launchers actually invoke seedWidevineHint,
|
|
// so accidental removal of the wiring fails CI (parity with the Python
|
|
// test_persistent_context_seeds_widevine tests).
|
|
|
|
vi.mock("../src/widevine.js", () => ({
|
|
seedWidevineHint: vi.fn(),
|
|
resolveWidevineCdmDir: vi.fn(),
|
|
}));
|
|
vi.mock("../src/download.js", () => ({
|
|
ensureBinary: vi.fn().mockResolvedValue("/fake/chrome"),
|
|
}));
|
|
vi.mock("../src/geoip.js", () => ({
|
|
resolveProxyGeo: vi.fn().mockResolvedValue({ timezone: null, locale: null }),
|
|
maybeResolveGeoip: vi.fn().mockResolvedValue({}),
|
|
resolveWebrtcArgs: vi.fn().mockImplementation((opts: any) => Promise.resolve(opts.args)),
|
|
}));
|
|
vi.mock("playwright-core", () => ({ chromium: { launchPersistentContext: vi.fn() } }));
|
|
vi.mock("puppeteer-core", () => ({ default: { launch: vi.fn() } }));
|
|
|
|
describe("persistent context seeds Widevine (integration)", () => {
|
|
beforeEach(() => {
|
|
delete process.env.CLOAKBROWSER_BINARY_PATH;
|
|
});
|
|
afterEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("Playwright launchPersistentContext seeds with (userDataDir, binaryPath)", async () => {
|
|
const pw = await import("playwright-core");
|
|
vi.mocked(pw.chromium.launchPersistentContext).mockResolvedValue({
|
|
close: vi.fn(),
|
|
pages: () => [],
|
|
} as any);
|
|
|
|
const { seedWidevineHint } = await import("../src/widevine.js");
|
|
const { launchPersistentContext } = await import("../src/playwright.js");
|
|
await launchPersistentContext({ userDataDir: "/tmp/profile" });
|
|
|
|
expect(seedWidevineHint).toHaveBeenCalledWith("/tmp/profile", "/fake/chrome");
|
|
});
|
|
|
|
it("Puppeteer launchPersistentContext seeds with (userDataDir, binaryPath)", async () => {
|
|
const pptr = await import("puppeteer-core");
|
|
vi.mocked(pptr.default.launch).mockResolvedValue({
|
|
newPage: vi.fn().mockResolvedValue({ authenticate: vi.fn() }),
|
|
close: vi.fn(),
|
|
} as any);
|
|
|
|
const { seedWidevineHint } = await import("../src/widevine.js");
|
|
const { launchPersistentContext } = await import("../src/puppeteer.js");
|
|
await launchPersistentContext({ userDataDir: "/tmp/profile" });
|
|
|
|
expect(seedWidevineHint).toHaveBeenCalledWith("/tmp/profile", "/fake/chrome");
|
|
});
|
|
});
|