/** * Jest Test Setup for TestDrive-JSUI * * Sets up the testing environment for JavaScript UI components. * Provides DOM mocking, global utilities, and test helpers. */ // Mock DOM globals that might be missing in JSDOM global.ResizeObserver = jest.fn().mockImplementation(() => ({ observe: jest.fn(), unobserve: jest.fn(), disconnect: jest.fn(), })); global.IntersectionObserver = jest.fn().mockImplementation(() => ({ observe: jest.fn(), unobserve: jest.fn(), disconnect: jest.fn(), })); // Mock window.matchMedia Object.defineProperty(window, 'matchMedia', { writable: true, value: jest.fn().mockImplementation(query => ({ matches: false, media: query, onchange: null, addListener: jest.fn(), // deprecated removeListener: jest.fn(), // deprecated addEventListener: jest.fn(), removeEventListener: jest.fn(), dispatchEvent: jest.fn(), })), }); // Mock local storage const localStorageMock = { getItem: jest.fn(), setItem: jest.fn(), removeItem: jest.fn(), clear: jest.fn(), }; global.localStorage = localStorageMock; // Mock session storage const sessionStorageMock = { getItem: jest.fn(), setItem: jest.fn(), removeItem: jest.fn(), clear: jest.fn(), }; global.sessionStorage = sessionStorageMock; // Global test utilities global.testUtils = { /** * Create a mock DOM element with specified tag and attributes */ createElement: (tag, attributes = {}) => { const element = document.createElement(tag); Object.entries(attributes).forEach(([key, value]) => { element.setAttribute(key, value); }); return element; }, /** * Create a test markdown content div */ createMarkdownContent: (content = '# Test Content') => { const div = document.createElement('div'); div.id = 'markdown-content'; div.innerHTML = content; return div; }, /** * Wait for next tick (useful for async operations) */ nextTick: () => new Promise(resolve => setTimeout(resolve, 0)), /** * Simulate user interaction events */ simulateEvent: (element, eventType, eventProperties = {}) => { const event = new Event(eventType, { bubbles: true, ...eventProperties }); Object.entries(eventProperties).forEach(([key, value]) => { event[key] = value; }); element.dispatchEvent(event); return event; }, /** * Clean up DOM after each test */ cleanupDOM: () => { document.body.innerHTML = ''; document.head.innerHTML = ''; } }; // Setup and teardown beforeEach(() => { // Reset mocks jest.clearAllMocks(); // Reset localStorage/sessionStorage localStorageMock.getItem.mockClear(); localStorageMock.setItem.mockClear(); localStorageMock.removeItem.mockClear(); localStorageMock.clear.mockClear(); sessionStorageMock.getItem.mockClear(); sessionStorageMock.setItem.mockClear(); sessionStorageMock.removeItem.mockClear(); sessionStorageMock.clear.mockClear(); }); afterEach(() => { // Clean up DOM global.testUtils.cleanupDOM(); // Clean up any timers jest.runOnlyPendingTimers(); jest.useRealTimers(); }); // Console helpers for test debugging global.console = { ...console, // Keep these methods for test debugging log: console.log, warn: console.warn, error: console.error, // Mock these to avoid noise in tests info: jest.fn(), debug: jest.fn(), };