-
Notifications
You must be signed in to change notification settings - Fork 78
Expand file tree
/
Copy pathjest.setup.js
More file actions
87 lines (81 loc) · 3.17 KB
/
Copy pathjest.setup.js
File metadata and controls
87 lines (81 loc) · 3.17 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
// Set timezone to UTC to ensure consistent test results
process.env.TZ = 'UTC';
// Note: React is imported via standard imports in test files.
// CJS mode in ts-jest handles the default export properly.
// Polyfill structuredClone for jsdom which does not expose it as a window global.
// structuredClone is a Node.js 17+ and modern-browser built-in; jsdom simply
// does not forward it to the window object.
//
// LIMITATION: JSON round-trip cannot clone functions, symbols, `undefined`
// values, or circular references. This is acceptable for `paramOverrides`
// which only contain JSON-serialisable values sourced from UI inputs.
// Do NOT rely on this polyfill for data that may include the above types.
if (typeof global.structuredClone === 'undefined') {
global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));
}
// jsdom exposes `crypto` without `subtle`, which a real browser always has and
// browser code uses — the sandbox module catalog verifies every delivered
// module body with SubtleCrypto. Node's WebCrypto is the same implementation,
// so hand that one member over rather than stub a hash a test would then be
// measuring instead of the real one. Only `subtle` is added: jsdom's own
// `getRandomValues`/`randomUUID` stay, because uuid-generating code all over
// the app is built against them.
if (global.crypto && global.crypto.subtle === undefined) {
Object.defineProperty(global.crypto, "subtle", {
value: require("node:crypto").webcrypto.subtle,
configurable: true
});
}
// Mock import.meta for Vite compatibility
global.import = {
meta: {
hot: undefined,
},
};
// Mock canvas before jsdom requires it
const Module = require("module");
const originalRequire = Module.prototype.require;
Module.prototype.require = function(id) {
// Only intercept the `canvas` npm package itself, not files that
// happen to have "canvas" in their path (e.g. rendering/canvasUtils).
// npm package requires are bare specifiers like "canvas" or "canvas/browser";
// file paths always start with "/" or ".".
if (id === "canvas" || /^canvas(\/|$)/.test(id)) {
return {
createCanvas: () => ({
getContext: () => ({
fillRect: () => {},
clearRect: () => {},
getImageData: () => ({ data: new Uint8ClampedArray(4) }),
putImageData: () => {},
createImageData: () => ({ data: new Uint8ClampedArray(4) }),
setTransform: () => {},
drawImage: () => {},
save: () => {},
fillText: () => {},
restore: () => {},
beginPath: () => {},
moveTo: () => {},
lineTo: () => {},
closePath: () => {},
stroke: () => {},
translate: () => {},
scale: () => {},
rotate: () => {},
arc: () => {},
fill: () => {},
measureText: () => ({ width: 0 }),
transform: () => {},
rect: () => {},
clip: () => {}
}),
toBuffer: (callback) => callback(null, Buffer.from("")),
width: 300,
height: 150
}),
loadImage: () => Promise.resolve({}),
Image: function() {}
};
}
return originalRequire.apply(this, arguments);
};