/** * Jest test setup * Mocks browser APIs */ import { webcrypto } from 'crypto'; // Mock Web Crypto API Object.defineProperty(globalThis, 'crypto', { value: webcrypto }); // Mock Chrome API const mockChrome = { storage: { local: { get: jest.fn(), set: jest.fn(), remove: jest.fn(), clear: jest.fn() } }, runtime: { sendMessage: jest.fn(), onMessage: { addListener: jest.fn() }, onInstalled: { addListener: jest.fn() }, onStartup: { addListener: jest.fn() }, getURL: jest.fn((path) => `chrome-extension://test/${path}`) }, downloads: { search: jest.fn(), onChanged: { addListener: jest.fn() } }, action: { setBadgeText: jest.fn(), setBadgeBackgroundColor: jest.fn() }, alarms: { create: jest.fn(), onAlarm: { addListener: jest.fn() } }, tabs: { create: jest.fn(), onUpdated: { addListener: jest.fn() }, query: jest.fn() } }; Object.defineProperty(globalThis, 'chrome', { value: mockChrome, writable: true }); // Mock fetch Object.defineProperty(globalThis, 'fetch', { value: jest.fn(), writable: true }); // Mock btoa/atob Object.defineProperty(globalThis, 'btoa', { value: (str: string) => Buffer.from(str, 'binary').toString('base64'), writable: true }); Object.defineProperty(globalThis, 'atob', { value: (str: string) => Buffer.from(str, 'base64').toString('binary'), writable: true }); // Mock TextEncoder/TextDecoder (from util) import { TextEncoder, TextDecoder } from 'util'; Object.defineProperty(globalThis, 'TextEncoder', { value: TextEncoder, writable: true }); Object.defineProperty(globalThis, 'TextDecoder', { value: TextDecoder, writable: true });