Files
stack/apps/web/vitest.setup.ts
Jason Woltje 8de2d9469a
All checks were successful
ci/woodpecker/push/web Pipeline was successful
fix(web): ensure localStorage mock exists for tests
2026-02-18 19:31:23 -06:00

58 lines
1.6 KiB
TypeScript

import { cleanup } from "@testing-library/react";
import { afterEach, expect } from "vitest";
import * as matchers from "@testing-library/jest-dom/matchers";
// Extend Vitest's expect with jest-dom matchers
expect.extend(matchers);
// Cleanup after each test to prevent test pollution
afterEach(() => {
cleanup();
});
// Mock window.matchMedia for tests that might use it
Object.defineProperty(window, "matchMedia", {
writable: true,
value: (query: string) => ({
matches: false,
media: query,
onchange: null,
addListener: () => {},
removeListener: () => {},
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => false,
}),
});
// Ensure localStorage exists with a full Storage API for tests.
if (!window.localStorage || typeof window.localStorage.clear !== "function") {
let store: Record<string, string> = {};
const storageMock: Storage = {
getItem: (key: string): string | null => store[key] ?? null,
setItem: (key: string, value: string): void => {
store[key] = value;
},
removeItem: (key: string): void => {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete store[key];
},
clear: (): void => {
store = {};
},
get length(): number {
return Object.keys(store).length;
},
key: (index: number): string | null => {
const keys = Object.keys(store);
return keys[index] ?? null;
},
};
Object.defineProperty(window, "localStorage", {
value: storageMock,
writable: true,
configurable: true,
});
}