-
Notifications
You must be signed in to change notification settings - Fork 467
/
helpers.js
138 lines (121 loc) · 3.86 KB
/
helpers.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
130
131
132
133
134
135
136
137
138
const globalObj = typeof window === 'undefined' ? global : window
// Constant node.nodeType for text nodes, see:
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType#Node_type_constants
const TEXT_NODE = 3
// Currently this fn only supports jest timers, but it could support other test runners in the future.
function runWithRealTimers(callback) {
// istanbul ignore else
if (typeof jest !== 'undefined') {
return runWithJestRealTimers(callback).callbackReturnValue
}
// istanbul ignore next
return callback()
}
function runWithJestRealTimers(callback) {
const timerAPI = {
clearImmediate,
clearInterval,
clearTimeout,
setImmediate,
setInterval,
setTimeout,
}
jest.useRealTimers()
const callbackReturnValue = callback()
const usedFakeTimers = Object.entries(timerAPI).some(
([name, func]) => func !== globalObj[name],
)
if (usedFakeTimers) {
jest.useFakeTimers(timerAPI.setTimeout?.clock ? 'modern' : 'legacy')
}
return {
callbackReturnValue,
usedFakeTimers,
}
}
function jestFakeTimersAreEnabled() {
// istanbul ignore else
if (typeof jest !== 'undefined') {
return runWithJestRealTimers(() => {}).usedFakeTimers
}
// istanbul ignore next
return false
}
// we only run our tests in node, and setImmediate is supported in node.
// istanbul ignore next
function setImmediatePolyfill(fn) {
return globalObj.setTimeout(fn, 0)
}
function getTimeFunctions() {
// istanbul ignore next
return {
clearTimeoutFn: globalObj.clearTimeout,
setImmediateFn: globalObj.setImmediate || setImmediatePolyfill,
setTimeoutFn: globalObj.setTimeout,
}
}
const {clearTimeoutFn, setImmediateFn, setTimeoutFn} = runWithRealTimers(
getTimeFunctions,
)
function getDocument() {
/* istanbul ignore if */
if (typeof window === 'undefined') {
throw new Error('Could not find default container')
}
return window.document
}
function getWindowFromNode(node) {
if (node.defaultView) {
// node is document
return node.defaultView
} else if (node.ownerDocument && node.ownerDocument.defaultView) {
// node is a DOM node
return node.ownerDocument.defaultView
} else if (node.window) {
// node is window
return node.window
} else if (node.then instanceof Function) {
throw new Error(
`It looks like you passed a Promise object instead of a DOM node. Did you do something like \`fireEvent.click(screen.findBy...\` when you meant to use a \`getBy\` query \`fireEvent.click(screen.getBy...\`, or await the findBy query \`fireEvent.click(await screen.findBy...\`?`,
)
} else if (Array.isArray(node)) {
throw new Error(
`It looks like you passed an Array instead of a DOM node. Did you do something like \`fireEvent.click(screen.getAllBy...\` when you meant to use a \`getBy\` query \`fireEvent.click(screen.getBy...\`?`,
)
} else {
// The user passed something unusual to a calling function
throw new Error(
`Unable to find the "window" object for the given node. Please file an issue with the code that's causing you to see this error: https://github.com/testing-library/dom-testing-library/issues/new`,
)
}
}
function checkContainerType(container) {
if (
!container ||
!(typeof container.querySelector === 'function') ||
!(typeof container.querySelectorAll === 'function')
) {
throw new TypeError(
`Expected container to be an Element, a Document or a DocumentFragment but got ${getTypeName(
container,
)}.`,
)
}
function getTypeName(object) {
if (typeof object === 'object') {
return object === null ? 'null' : object.constructor.name
}
return typeof object
}
}
export {
getWindowFromNode,
getDocument,
clearTimeoutFn as clearTimeout,
setImmediateFn as setImmediate,
setTimeoutFn as setTimeout,
runWithRealTimers,
checkContainerType,
jestFakeTimersAreEnabled,
TEXT_NODE,
}