vitest.setup.ts
Rama main · réplica de lectura del repositorio original.
import "@testing-library/jest-dom/vitest";
import { cleanup } from "@testing-library/react";
import { afterEach, vi } from "vitest";
import {
clearIntersectionObservers,
installIntersectionObserverStub,
} from "./src/test/intersection";
// Testing Library's own auto-cleanup only runs when it detects a global `afterEach`,
// which it does under Vitest - but registering it explicitly means a component test
// that forgets `render` isolation still can't leak DOM into the next one.
afterEach(cleanup);
// jsdom implements neither, and Base UI (dialogs, selects, popovers) and the app's own
// responsive hooks both reach for them on mount. Without these, every test that
// renders a dialog throws before it reaches its assertion.
Object.defineProperty(window, "matchMedia", {
writable: true,
value: (query: string) => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
}),
});
window.ResizeObserver = class {
observe() {}
unobserve() {}
disconnect() {}
};
// Same reason, one layer up: `LoadMoreTrigger` observes its button so a list
// pulls its next page in as the diver scrolls, and `new IntersectionObserver`
// throws outright in jsdom. The stub reports nothing until a test says the
// reader has scrolled there - see `src/test/intersection.ts` for why that is the
// honest default and how to ask for the other answer.
installIntersectionObserverStub();
afterEach(clearIntersectionObservers);
// Popup positioning measures with these; jsdom reports zeroes and warns without them.
Element.prototype.scrollIntoView = vi.fn();
// The calendar's swipe captures the pointer once a drag passes its threshold, and
// jsdom implements none of the three, so a test swiping it would throw.
Element.prototype.hasPointerCapture = () => false;
Element.prototype.setPointerCapture = () => {};
Element.prototype.releasePointerCapture = () => {};