Files
portal/app/tests/Frontend/setup.ts
T

69 lines
2.1 KiB
TypeScript
Raw Normal View History

// Vitest setup для Vuetify в JSDOM-среде.
// Vuetify-компоненты используют ResizeObserver/IntersectionObserver/matchMedia,
// которые отсутствуют в JSDOM. Добавляем минимальные stub'ы.
class ResizeObserverStub {
observe(): void {}
unobserve(): void {}
disconnect(): void {}
}
class IntersectionObserverStub {
observe(): void {}
unobserve(): void {}
disconnect(): void {}
takeRecords(): never[] {
return [];
}
root = null;
rootMargin = '';
thresholds: number[] = [];
}
// Глобальные браузерные API заглушки для JSDOM-среды.
(globalThis as unknown as { ResizeObserver: typeof ResizeObserverStub }).ResizeObserver = ResizeObserverStub;
(globalThis as unknown as { IntersectionObserver: typeof IntersectionObserverStub }).IntersectionObserver =
IntersectionObserverStub;
if (!window.matchMedia) {
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: (query: string) => ({
matches: false,
media: query,
onchange: null,
addListener: () => {},
removeListener: () => {},
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => false,
}),
});
}
// CSS.supports — Vuetify проверяет наличие color-mix.
if (!window.CSS || !window.CSS.supports) {
Object.defineProperty(window, 'CSS', {
writable: true,
value: { supports: () => true },
});
}
// visualViewport — VOverlay/v-menu/v-snackbar используют для location strategies.
if (!window.visualViewport) {
Object.defineProperty(window, 'visualViewport', {
writable: true,
value: {
width: 1024,
height: 768,
offsetLeft: 0,
offsetTop: 0,
pageLeft: 0,
pageTop: 0,
scale: 1,
addEventListener: () => {},
removeEventListener: () => {},
},
});
}