-
Notifications
You must be signed in to change notification settings - Fork 11
/
jest.setup.js
129 lines (117 loc) · 4.6 KB
/
jest.setup.js
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
Object.assign(global, require('jest-chrome'))
// Mocks chrome API calls needed for autofill to run successfully
// @ts-ignore
chrome.runtime.sendMessage.mockImplementation(
(message, callback) => {
let response = {}
if (message.getAddresses) {
response = {
privateAddress: '123test321',
personalAddress: 'test'
}
}
callback(response)
}
)
// The autofill script bails if context is insecure, this enables tests to run
global.isSecureContext = true
const crypto = require('crypto')
Object.defineProperty(global.self, 'crypto', {
value: {
...global.self.crypto,
// @ts-ignore TS doesn't know of `crypto.webcrypto.subtle`
subtle: crypto.webcrypto.subtle,
getRandomValues: arr => crypto.randomFillSync(arr)
}
})
/**
* Utility function that mocks the `IntersectionObserver` API. Necessary for components that rely
* on it, otherwise the tests will crash. Recommended to execute inside `beforeEach`.
* @param intersectionObserverMock - Parameter that is sent to the `Object.defineProperty`
* overwrite method. `jest.fn()` mock functions can be passed here if the goal is to not only
* mock the intersection observer, but its methods.
* @source https://javascript.tutorialink.com/js-testing-code-that-uses-an-intersectionobserver/
*/
function setupIntersectionObserverMock ({
root = null,
rootMargin = '',
thresholds = [],
disconnect = () => null,
observe = () => null,
takeRecords = () => [],
unobserve = () => null
} = {}) {
class MockIntersectionObserver {
constructor () {
this.root = root
this.rootMargin = rootMargin
this.thresholds = thresholds
this.disconnect = disconnect
this.observe = observe
this.takeRecords = takeRecords
this.unobserve = unobserve
}
}
Object.defineProperty(window, 'IntersectionObserver', {
writable: true,
configurable: true,
value: MockIntersectionObserver
})
Object.defineProperty(global, 'IntersectionObserver', {
writable: true,
configurable: true,
value: MockIntersectionObserver
})
}
setupIntersectionObserverMock()
/**
* Enable the use of clientWidth, clientHeight, offsetWidth and offsetHeight on html elements
* @source https://github.com/jsdom/jsdom/issues/2342#issuecomment-468253441 (adapted)
**/
// Enables setting clientWidth by the data-mock-clientWidth attribute or the property _jsdomMockClientWidth
Object.defineProperty(window.HTMLElement.prototype, 'clientWidth', {
get: function () {
const mockClientWidthAttribute = this.getAttribute('data-mock-clientWidth')
if (mockClientWidthAttribute) return mockClientWidthAttribute
return this._jsdomMockClientWidth || 0
}
})
// Enables setting clientHeight by the data-mock-clientHeight attribute or the property _jsdomMockClientHeight
Object.defineProperty(window.HTMLElement.prototype, 'clientHeight', {
get: function () {
const mockClientHeightAttribute = this.getAttribute('data-mock-clientHeight')
if (mockClientHeightAttribute) return mockClientHeightAttribute
return this._jsdomMockClientHeight || 0
}
})
// Enables setting offsetWidth by the data-mock-offsetWidth attribute or the property _jsdomMockOffsetWidth
Object.defineProperty(window.HTMLElement.prototype, 'offsetWidth', {
get: function () {
const mockOffsetWidthAttribute = this.getAttribute('data-mock-offsetWidth')
if (mockOffsetWidthAttribute) return mockOffsetWidthAttribute
return this._jsdomMockOffsetWidth || 0
}
})
// Enables setting offsetHeight by the data-mock-offsetHeight attribute or the property _jsdomMockOffsetHeight
Object.defineProperty(window.HTMLElement.prototype, 'offsetHeight', {
get: function () {
const mockOffsetHeightAttribute = this.getAttribute('data-mock-offsetHeight')
if (mockOffsetHeightAttribute) return mockOffsetHeightAttribute
return this._jsdomMockOffsetHeight || 0
}
})
// getComputedStyle is super slow on jsdom, by providing this mock we speed tests up significantly
const defaultStyle = {
display: 'block',
visibility: 'visible',
opacity: '1',
paddingRight: '10'
}
const mockGetComputedStyle = (el) => {
return {
// since we don't load stylesheets in the tests, the style prop is all the css applied, so it's a safe fallback
getPropertyValue: (prop) => el.style?.[prop] || defaultStyle[prop]
}
}
// @ts-ignore
jest.spyOn(window, 'getComputedStyle').mockImplementation(mockGetComputedStyle)