import '@testing-library/jest-dom/vitest'; import { cleanup } from '@testing-library/react'; import { toHaveNoViolations } from 'jest-axe'; import { afterEach, expect, vi } from 'vitest'; afterEach(cleanup); /* jest-axe ships a plain matcher object, so it plugs into Vitest unchanged. The matcher's type lives in test/vitest.d.ts. */ expect.extend(toHaveNoViolations); /* Everything below stubs a browser API, and `test/ssr.test.tsx` deliberately runs with `@vitest-environment node`, where there is no browser to stub. `setupFiles` applies to every suite regardless of its environment, so without this guard the SSR file fails at import — before a single component is rendered — on `window` being undefined. The guard is also the honest shape: a stub for an API that does not exist is not a stub, it is an invention, and inventing `window` in the one suite whose purpose is proving the kit works without it would defeat the suite. */ const isBrowserLike = typeof window !== 'undefined'; /* jsdom implements neither of these, and Radix uses both for positioning and scroll locking. Without the stubs most overlay components throw on render. */ if (isBrowserLike && !window.matchMedia) { window.matchMedia = vi.fn().mockImplementation((query: string) => ({ matches: false, media: query, onchange: null, addEventListener: vi.fn(), removeEventListener: vi.fn(), dispatchEvent: vi.fn(), addListener: vi.fn(), removeListener: vi.fn(), })); } if (isBrowserLike && !window.ResizeObserver) { window.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} }; } /* jsdom has no layout engine, so these are absent entirely. cmdk calls scrollIntoView to keep the highlighted item visible, and Radix uses the pointer-capture APIs for drag handling — without the stubs those components throw on render rather than failing a meaningful assertion. */ if (isBrowserLike && !Element.prototype.scrollIntoView) { Element.prototype.scrollIntoView = vi.fn(); } if (isBrowserLike && !Element.prototype.hasPointerCapture) { Element.prototype.hasPointerCapture = vi.fn(() => false); Element.prototype.setPointerCapture = vi.fn(); Element.prototype.releasePointerCapture = vi.fn(); }