muyu-portal/test/setup.ts
2026-06-15 19:47:45 +09:00

81 lines
2.5 KiB
TypeScript

import '@testing-library/jest-dom/vitest';
import { afterEach, vi } from 'vitest';
import { cleanup } from '@testing-library/react';
// jsdom is missing a handful of browser APIs that antd / pro-components touch on
// mount. Provide minimal stand-ins so component pages can render in tests.
if (!window.matchMedia) {
window.matchMedia = 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(),
}));
}
class ResizeObserverStub {
observe() {}
unobserve() {}
disconnect() {}
}
// @ts-expect-error -- assigning test stub
window.ResizeObserver = window.ResizeObserver || ResizeObserverStub;
class IntersectionObserverStub {
root = null;
rootMargin = '';
thresholds = [];
observe() {}
unobserve() {}
disconnect() {}
takeRecords() {
return [];
}
}
// @ts-expect-error -- assigning test stub
window.IntersectionObserver = window.IntersectionObserver || IntersectionObserverStub;
if (!window.scrollTo) {
// @ts-expect-error -- jsdom does not implement scrollTo
window.scrollTo = vi.fn();
}
// Some pages read auth tokens from localStorage during render; ensure a working
// Storage implementation is present regardless of the jsdom build.
if (typeof window.localStorage?.getItem !== 'function') {
const store = new Map<string, string>();
const storage: Storage = {
get length() {
return store.size;
},
clear: () => store.clear(),
getItem: (k: string) => (store.has(k) ? store.get(k)! : null),
key: (i: number) => Array.from(store.keys())[i] ?? null,
removeItem: (k: string) => void store.delete(k),
setItem: (k: string, v: string) => void store.set(k, String(v)),
};
Object.defineProperty(window, 'localStorage', { value: storage, configurable: true });
}
// jsdom's getContext is unimplemented; the CRM graph page guards against a null
// context, so returning null keeps it on its safe path.
if (!HTMLCanvasElement.prototype.getContext) {
HTMLCanvasElement.prototype.getContext = () => null;
}
// jsdom throws "Not implemented" when getComputedStyle is called with a
// pseudo-element (rc-table does this while measuring scrollbars). Drop the
// unsupported second argument so the call succeeds quietly.
const originalGetComputedStyle = window.getComputedStyle.bind(window);
window.getComputedStyle = ((elt: Element) =>
originalGetComputedStyle(elt)) as typeof window.getComputedStyle;
afterEach(() => {
cleanup();
});