import "@testing-library/jest-dom/vitest"; function createMemoryStorage(): Storage { const values = new Map(); return { get length() { return values.size; }, clear: () => values.clear(), getItem: (key: string) => values.get(key) ?? null, key: (index: number) => Array.from(values.keys())[index] ?? null, removeItem: (key: string) => { values.delete(key); }, setItem: (key: string, value: string) => { values.set(key, value); }, }; } if (typeof globalThis.localStorage?.clear !== "function") { const storage = createMemoryStorage(); Object.defineProperty(globalThis, "localStorage", { configurable: true, value: storage, }); Object.defineProperty(window, "localStorage", { configurable: true, value: storage, }); } // jsdom doesn't provide matchMedia; useIsMobile() relies on it. if (typeof window.matchMedia !== "function") { window.matchMedia = (query: string) => ({ matches: false, media: query, onchange: null, addListener: () => {}, removeListener: () => {}, addEventListener: () => {}, removeEventListener: () => {}, dispatchEvent: () => false, }) as MediaQueryList; } // jsdom doesn't provide ResizeObserver; stub it so components that rely on it // (e.g. input-otp) can render in tests. if (typeof globalThis.ResizeObserver === "undefined") { globalThis.ResizeObserver = class ResizeObserver { observe() {} unobserve() {} disconnect() {} } as unknown as typeof ResizeObserver; } // jsdom doesn't implement elementFromPoint; input-otp uses it internally. if (typeof document.elementFromPoint !== "function") { document.elementFromPoint = () => null; }