Repository navigation
Expand file tree
/
Copy pathjest.setup.js
More file actions
134 lines (123 loc) · 4.66 KB
/
Copy pathjest.setup.js
File metadata and controls
134 lines (123 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import '@testing-library/jest-dom';
// Polyfill TextEncoder and TextDecoder for jsdom environments (common issue with Stellar SDK etc.)
if (typeof global.TextEncoder === 'undefined') {
const { TextEncoder, TextDecoder } = require('util');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
}
// jsdom exposes getRandomValues but not SubtleCrypto; use Node's WebCrypto
// implementation so HMAC signing/verification works in component tests.
if (typeof globalThis.crypto === 'undefined' || !globalThis.crypto.subtle) {
const { webcrypto } = require('crypto');
Object.defineProperty(globalThis, 'crypto', { value: webcrypto, configurable: true });
if (typeof window !== 'undefined') {
Object.defineProperty(window, 'crypto', { value: webcrypto, configurable: true });
}
}
// Mock matchMedia
if (typeof window !== 'undefined') {
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
}
// jsdom does not implement canvas; QR rendering tests only need a drawing surface.
// Skip in non-DOM environments (e.g. @jest-environment node suites) where the
// HTMLCanvasElement global does not exist.
if (typeof HTMLCanvasElement !== 'undefined') {
HTMLCanvasElement.prototype.getContext = jest.fn(() => ({
clearRect: jest.fn(), fillRect: jest.fn(), drawImage: jest.fn(),
getImageData: jest.fn(), putImageData: jest.fn(), createImageData: jest.fn(),
setTransform: jest.fn(), resetTransform: jest.fn(), scale: jest.fn(),
save: jest.fn(), restore: jest.fn(), beginPath: jest.fn(), closePath: jest.fn(),
moveTo: jest.fn(), lineTo: jest.fn(), stroke: jest.fn(), fill: jest.fn(),
translate: jest.fn(), rotate: jest.fn(), arc: jest.fn(), rect: jest.fn(),
clip: jest.fn(), measureText: jest.fn(() => ({ width: 0 })), fillText: jest.fn(),
}));
// Canvas toDataURL is used by QRCode download/print flows; stub it.
if (!HTMLCanvasElement.prototype.toDataURL) {
HTMLCanvasElement.prototype.toDataURL = jest.fn(() => 'data:image/png;base64,mock');
} else {
const origToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = jest.fn(function(type) {
try { return origToDataURL.call(this, type); } catch { return 'data:image/png;base64,mock'; }
});
}
}
// jsdom does not implement EventSource (used by NotificationCenter)
if (typeof global.EventSource === 'undefined') {
class MockEventSource {
url;
onmessage = null;
onerror = null;
onopen = null;
readyState = 0;
close = jest.fn();
addEventListener = jest.fn();
removeEventListener = jest.fn();
dispatchEvent = jest.fn(() => true);
constructor(url) {
this.url = url;
}
}
global.EventSource = MockEventSource;
if (typeof window !== 'undefined') {
window.EventSource = MockEventSource;
}
}
// jsdom does not implement document.execCommand (used by some clipboard fallbacks)
if (typeof document !== 'undefined') {
// Always stub execCommand to return false by default so clipboard fallbacks
// don't incorrectly succeed when mocked clipboard fails (CopyAddress test).
// Tests that need it to succeed can override with mockReturnValueOnce(true).
document.execCommand = jest.fn(() => false);
}
// Ensure fetch exists in tests that don't provide their own mock
if (typeof global.fetch === 'undefined') {
global.fetch = jest.fn(() => Promise.resolve({ ok: true, json: async () => ({}) }));
}
// Stub window.matchMedia already handled above, ensure fetch on window as well
if (typeof window !== 'undefined' && typeof window.fetch === 'undefined') {
window.fetch = global.fetch;
}
// Mock custom UI components that use complex Base UI primitives to avoid JSDOM compatibility issues
jest.mock('@/components/ui/input', () => {
const React = require('react');
const Input = React.forwardRef(({ className, type, ...props }, ref) => {
return (
<input
ref={ref}
type={type}
className={className}
{...props}
/>
);
});
Input.displayName = 'Input';
return { Input };
});
jest.mock('@/components/ui/button', () => {
const React = require('react');
const Button = React.forwardRef(({ className, children, ...props }, ref) => {
return (
<button
ref={ref}
className={className}
{...props}
>
{children}
</button>
);
});
Button.displayName = 'Button';
return { Button };
});