// ======================================== // Test Setup // ======================================== // Global test configuration for Vitest import { afterEach, beforeEach, vi } from 'vitest'; import { cleanup } from '@testing-library/react'; import '@testing-library/jest-dom/vitest'; // Cleanup after each test afterEach(() => { cleanup(); }); // Mock window.matchMedia for theme detection Object.defineProperty(window, 'matchMedia', { writable: true, value: vi.fn().mockImplementation((query: string) => ({ matches: false, media: query, onchange: null, addListener: vi.fn(), removeListener: vi.fn(), addEventListener: vi.fn(), removeEventListener: vi.fn(), dispatchEvent: vi.fn(), })), }); // Mock localStorage const localStorageMock = (() => { let store: Record = {}; return { getItem: (key: string) => store[key] ?? null, setItem: (key: string, value: string) => { store[key] = value.toString(); }, removeItem: (key: string) => { delete store[key]; }, clear: () => { store = {}; }, }; })(); Object.defineProperty(global, 'localStorage', { value: localStorageMock, }); // Reset all mocks before each test beforeEach(() => { vi.clearAllMocks(); localStorageMock.clear(); }); // Mock browser APIs not available in jsdom (for Radix UI components) Element.prototype.scrollIntoView = vi.fn(); Element.prototype.hasPointerCapture = vi.fn(() => false); Element.prototype.setPointerCapture = vi.fn(); Element.prototype.releasePointerCapture = vi.fn(); // Mock ResizeObserver for components that use it (e.g., recharts, allotment) class ResizeObserverMock { observe = vi.fn(); unobserve = vi.fn(); disconnect = vi.fn(); } Object.defineProperty(global, 'ResizeObserver', { writable: true, configurable: true, value: ResizeObserverMock, });