Files
vdm/extension/tests/setup.ts
T
samiandClaude Sonnet 5 c5d596d93b ext: MV3 manifest + esbuild build; drop polyfill for Firefox's browser global
Firefox-only extension, so webextension-polyfill (a Chrome shim) is dead
weight and forces a bundler just to resolve one bare import. Use the native
`browser.*` global with @types/firefox-webext-browser instead.

  - manifest.json: MV3, event-page background (dist/background.js), the
    docs/05 §7 permission set (<all_urls> in host_permissions),
    strict_min_version 128.0, data_collection_permissions none.
  - scripts/build.mjs: esbuild bundle of src/background/index.ts -> dist/,
    esm, target firefox128. Wired to `prepare` so `npm ci` produces the
    bundle and CI's `web-ext lint` (which needs it to exist) passes with no
    added CI step. dist/ stays gitignored.
  - src/background/index.ts: event-page entry — brings the transport up,
    holds the shared reference. Capture surfaces attach here next.
  - transport/storage.ts, transport/index.ts: use the browser global.
  - tests/setup.ts: stub the browser global instead of mocking a module.

web-ext lint clean (0/0/0). typecheck clean. 38 tests still green.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012Y9RU58hD1BuwP82DySUHk
2026-09-10 13:50:23 +04:00

44 lines
1.4 KiB
TypeScript

// Global test setup: a minimal stand-in for Firefox's `browser` global with an
// in-memory storage.local, so storage.ts and the transport picker run under vitest.
import { beforeEach } from 'vitest';
function makeBrowserShim() {
const store = new Map<string, unknown>();
const local = {
get: async (keys?: string | string[] | Record<string, unknown> | null) => {
if (keys == null) return Object.fromEntries(store);
const names =
typeof keys === 'string' ? [keys] : Array.isArray(keys) ? keys : Object.keys(keys);
const out: Record<string, unknown> = {};
for (const k of names) if (store.has(k)) out[k] = store.get(k);
return out;
},
set: async (obj: Record<string, unknown>) => {
for (const [k, v] of Object.entries(obj)) store.set(k, v);
},
remove: async (keys: string | string[]) => {
for (const k of typeof keys === 'string' ? [keys] : keys) store.delete(k);
},
clear: async () => {
store.clear();
},
};
return {
storage: { local },
runtime: {
getURL: (path = '/') => `moz-extension://11111111-2222-3333-4444-555555555555${path}`,
connectNative: () => {
throw new Error('browser.runtime.connectNative was not stubbed for this test');
},
},
};
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).browser = makeBrowserShim();
beforeEach(async () => {
await browser.storage.local.clear();
});