44 lines
1.8 KiB
TypeScript
44 lines
1.8 KiB
TypeScript
import "@testing-library/jest-dom/vitest";
|
|
import { server } from "./msw";
|
|
import { workspacePreferences } from "../workspaces/preferences";
|
|
|
|
// Node 25 ships an experimental global `localStorage` that shadows jsdom's Storage and
|
|
// lacks spec methods like clear(), so tests calling localStorage.clear()/setItem() throw.
|
|
// Swap in a spec-compliant in-memory Storage. Feature-detected: inert on runtimes whose
|
|
// localStorage already implements clear() (e.g. CI on an LTS Node with working jsdom).
|
|
if (typeof localStorage === "undefined" || typeof localStorage.clear !== "function") {
|
|
const store = new Map<string, string>();
|
|
const storage: Storage = {
|
|
get length() { return store.size; },
|
|
clear() { store.clear(); },
|
|
getItem(key: string) { return store.has(key) ? store.get(key)! : null; },
|
|
key(index: number) { return Array.from(store.keys())[index] ?? null; },
|
|
removeItem(key: string) { store.delete(key); },
|
|
setItem(key: string, value: string) { store.set(String(key), String(value)); },
|
|
};
|
|
Object.defineProperty(globalThis, "localStorage", { value: storage, configurable: true, writable: true });
|
|
if (typeof window !== "undefined") {
|
|
Object.defineProperty(window, "localStorage", { value: storage, configurable: true, writable: true });
|
|
}
|
|
}
|
|
|
|
// jsdom lacks matchMedia; sonner's <Toaster> (mounted in AppShell) needs it.
|
|
if (!window.matchMedia) {
|
|
window.matchMedia = (query: string) =>
|
|
({
|
|
matches: false,
|
|
media: query,
|
|
onchange: null,
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {},
|
|
addListener: () => {},
|
|
removeListener: () => {},
|
|
dispatchEvent: () => false,
|
|
}) as unknown as MediaQueryList;
|
|
}
|
|
|
|
beforeAll(() => server.listen());
|
|
beforeEach(() => workspacePreferences.reset());
|
|
afterEach(() => server.resetHandlers());
|
|
afterAll(() => server.close());
|