import '@testing-library/jest-dom'; import { cleanup } from '@testing-library/react'; import { afterEach, vi } from 'vitest'; // Radix UI / @floating-ui calls requestAnimationFrame for layout and // positioning on every render (Popover, DropdownMenu, Checkbox focus rings, // etc.). In jsdom those callbacks are deferred to a future tick, landing // outside the current act() boundary. React queues the resulting state // updates, which schedule more microtasks, and the act() settlement loop // keeps running until Vitest's 5000ms hard timeout kills the test. // // Making rAF synchronous keeps every callback inside the current act() cycle // so there are no pending tasks when the test finishes. This fixes the whole // class of flaky timeouts without touching individual test files. global.requestAnimationFrame = (cb: FrameRequestCallback): number => { cb(performance.now()); return 0; }; global.cancelAnimationFrame = (_id: number): void => {}; // Cleanup after each test afterEach(() => { cleanup(); }); // Mock environment variables process.env.NODE_ENV = 'test'; // jsdom does not implement scrollTo on elements HTMLElement.prototype.scrollTo = vi.fn(); // jsdom does not implement these APIs that Radix UI relies on for pointer // interactions and option positioning (Select, DropdownMenu, etc.). Without // them, opening a Radix Select in a test throws. HTMLElement.prototype.scrollIntoView = vi.fn(); HTMLElement.prototype.hasPointerCapture = vi.fn(() => false); HTMLElement.prototype.setPointerCapture = vi.fn(); HTMLElement.prototype.releasePointerCapture = vi.fn(); // Mock BetterAuth vi.mock('~/lib/auth.server', () => ({ auth: { api: { getSession: vi.fn(() => Promise.resolve({ user: { id: 'test-user-id', email: 'test@example.com', name: 'Test User' }, session: { userId: 'test-user-id' }, })), }, }, })); // Mock database context vi.mock('~/database/context', () => ({ database: vi.fn(() => ({ query: {}, insert: vi.fn(), update: vi.fn(), delete: vi.fn(), select: vi.fn(), })), }));