2026-04-22 09:42:00 +03:00
|
|
|
import { vi } from 'vitest';
|
|
|
|
|
|
|
|
|
|
// jsdom lacks ResizeObserver
|
|
|
|
|
global.ResizeObserver = class {
|
|
|
|
|
observe = vi.fn();
|
|
|
|
|
unobserve = vi.fn();
|
|
|
|
|
disconnect = vi.fn();
|
|
|
|
|
} as unknown as typeof ResizeObserver;
|
|
|
|
|
|
|
|
|
|
// jsdom lacks Web Animations API
|
|
|
|
|
Element.prototype.animate = vi.fn().mockReturnValue({
|
|
|
|
|
onfinish: null,
|
|
|
|
|
cancel: vi.fn(),
|
|
|
|
|
finish: vi.fn(),
|
|
|
|
|
pause: vi.fn(),
|
|
|
|
|
play: vi.fn(),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// jsdom lacks SVG geometry methods
|
2026-04-22 09:45:51 +03:00
|
|
|
(SVGElement.prototype as any).getTotalLength = vi.fn(() => 0);
|
2026-04-22 09:42:00 +03:00
|
|
|
|
|
|
|
|
// Robust localStorage mock for jsdom environment
|
|
|
|
|
const localStorageMock = (() => {
|
|
|
|
|
let store: Record<string, string> = {};
|
|
|
|
|
return {
|
|
|
|
|
getItem: vi.fn((key: string) => store[key] || null),
|
|
|
|
|
setItem: vi.fn((key: string, value: string) => {
|
|
|
|
|
store[key] = value.toString();
|
|
|
|
|
}),
|
|
|
|
|
removeItem: vi.fn((key: string) => {
|
|
|
|
|
delete store[key];
|
|
|
|
|
}),
|
|
|
|
|
clear: vi.fn(() => {
|
|
|
|
|
store = {};
|
|
|
|
|
}),
|
|
|
|
|
key: vi.fn((index: number) => Object.keys(store)[index] || null),
|
|
|
|
|
get length() {
|
|
|
|
|
return Object.keys(store).length;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
Object.defineProperty(window, 'localStorage', {
|
|
|
|
|
value: localStorageMock,
|
|
|
|
|
writable: true,
|
|
|
|
|
});
|
2026-06-02 11:08:07 +03:00
|
|
|
|
|
|
|
|
// jsdom lacks PointerEvent; back it with MouseEvent so clientX/clientY survive.
|
|
|
|
|
if (typeof PointerEvent === 'undefined') {
|
|
|
|
|
class PointerEventPolyfill extends MouseEvent {
|
|
|
|
|
pointerId: number;
|
|
|
|
|
constructor(type: string, params: PointerEventInit = {}) {
|
|
|
|
|
super(type, params);
|
|
|
|
|
this.pointerId = params.pointerId ?? 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// @ts-expect-error assigning polyfill to the global scope
|
|
|
|
|
global.PointerEvent = PointerEventPolyfill;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// jsdom lacks pointer capture
|
|
|
|
|
HTMLElement.prototype.setPointerCapture = vi.fn();
|
|
|
|
|
HTMLElement.prototype.releasePointerCapture = vi.fn();
|