Skip to content

Commit 8807c56

Browse files
authored
Merge branch 'master' into pr/pass-through-data-transfer-object
2 parents 34e811e + c6acb0a commit 8807c56

File tree

7 files changed

+100
-85
lines changed

7 files changed

+100
-85
lines changed

.all-contributorsrc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,8 @@
13091309
"profile": "https://codepen.io/ariperkkio/",
13101310
"contributions": [
13111311
"bug",
1312-
"code"
1312+
"code",
1313+
"doc"
13131314
]
13141315
},
13151316
{
@@ -1320,6 +1321,15 @@
13201321
"contributions": [
13211322
"code"
13221323
]
1324+
},
1325+
{
1326+
"login": "ph-fritsche",
1327+
"name": "Philipp Fritsche",
1328+
"avatar_url": "https://avatars.githubusercontent.com/u/39068198?v=4",
1329+
"profile": "https://github.com/ph-fritsche",
1330+
"contributions": [
1331+
"code"
1332+
]
13231333
}
13241334
],
13251335
"repoHost": "https://github.com"

.github/workflows/validate.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ jobs:
2626

2727
- name: ⬇️ Checkout repo
2828
uses: actions/checkout@v2
29+
with:
30+
# required by codecov/codecov-action
31+
fetch-depth: 0
2932

3033
- name: ⎔ Setup node
3134
uses: actions/setup-node@v1
@@ -42,6 +45,9 @@ jobs:
4245

4346
- name: ⬆️ Upload coverage report
4447
uses: codecov/codecov-action@v1
48+
with:
49+
fail_ci_if_error: true
50+
flags: node-${{ matrix.node }}
4551

4652
release:
4753
needs: main

CONTRIBUTING.md

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,6 @@ Please make sure to run the tests before you commit your changes. You can run
3232
`npm run test:update` which will update any snapshots that need updating. Make
3333
sure to include those changes (if they exist) in your commit.
3434
35-
### opt into git hooks
36-
37-
There are git hooks set up with this project that are automatically installed
38-
when you install dependencies. They're really handy, but are turned off by
39-
default (so as to not hinder new contributors). You can opt into these by
40-
creating a file called `.opt-in` at the root of the project and putting this
41-
inside:
42-
43-
```
44-
pre-commit
45-
```
46-
4735
## Help needed
4836
4937
Please checkout the [the open issues][issues]

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,11 @@ Thanks goes to these people ([emoji key][emojis]):
300300
<td align="center"><a href="https://github.com/romain-trotard"><img src="https://avatars0.githubusercontent.com/u/17161484?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Romain Trotard</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=romain-trotard" title="Code">💻</a></td>
301301
<td align="center"><a href="http://www.thomasmarshall.com"><img src="https://avatars0.githubusercontent.com/u/770763?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Thomas Marshall</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=thomasmarshall" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=thomasmarshall" title="Tests">⚠️</a></td>
302302
<td align="center"><a href="https://github.com/johnjesse"><img src="https://avatars1.githubusercontent.com/u/6839660?v=4?s=100" width="100px;" alt=""/><br /><sub><b>johnjessewood</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/issues?q=author%3Ajohnjesse" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=johnjesse" title="Code">💻</a></td>
303-
<td align="center"><a href="https://codepen.io/ariperkkio/"><img src="https://avatars2.githubusercontent.com/u/14806298?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ari Perkkiö</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/issues?q=author%3AAriPerkkio" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=AriPerkkio" title="Code">💻</a></td>
303+
<td align="center"><a href="https://codepen.io/ariperkkio/"><img src="https://avatars2.githubusercontent.com/u/14806298?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ari Perkkiö</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/issues?q=author%3AAriPerkkio" title="Bug reports">🐛</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=AriPerkkio" title="Code">💻</a> <a href="https://github.com/testing-library/dom-testing-library/commits?author=AriPerkkio" title="Documentation">📖</a></td>
304304
</tr>
305305
<tr>
306306
<td align="center"><a href="https://github.com/nathanforce"><img src="https://avatars2.githubusercontent.com/u/6694194?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nathan Force</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=nathanforce" title="Code">💻</a></td>
307+
<td align="center"><a href="https://github.com/ph-fritsche"><img src="https://avatars.githubusercontent.com/u/39068198?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Philipp Fritsche</b></sub></a><br /><a href="https://github.com/testing-library/dom-testing-library/commits?author=ph-fritsche" title="Code">💻</a></td>
307308
</tr>
308309
</table>
309310

src/__tests__/helpers.js

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ import {
55
runWithRealTimers,
66
} from '../helpers'
77

8-
const globalObj = typeof window === 'undefined' ? global : window
9-
10-
afterEach(() => jest.useRealTimers())
11-
128
test('returns global document if exists', () => {
139
expect(getDocument()).toBe(document)
1410
})
@@ -21,6 +17,11 @@ describe('window retrieval throws when given something other than a node', () =>
2117
`"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...\`?"`,
2218
)
2319
})
20+
test('Array as node', () => {
21+
expect(() => getWindowFromNode([])).toThrowErrorMatchingInlineSnapshot(
22+
`"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...\`?"`,
23+
)
24+
})
2425
test('unknown as node', () => {
2526
expect(() => getWindowFromNode({})).toThrowErrorMatchingInlineSnapshot(
2627
`"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"`,
@@ -53,42 +54,47 @@ describe('query container validation throws when validation fails', () => {
5354
})
5455
})
5556

56-
test('should always use realTimers before using callback when timers are faked with useFakeTimers', () => {
57-
const originalSetTimeout = globalObj.setTimeout
57+
describe('run with real timers', () => {
58+
const realSetTimeout = global.setTimeout
5859

59-
// legacy timers use mocks and do not rely on a clock instance
60-
jest.useFakeTimers('legacy')
61-
runWithRealTimers(() => {
62-
expect(originalSetTimeout).toEqual(globalObj.setTimeout)
60+
afterEach(() => {
61+
// restore timers replaced by jest.useFakeTimers()
62+
jest.useRealTimers()
63+
// restore setTimeout replaced by assignment
64+
global.setTimeout = realSetTimeout
6365
})
64-
expect(globalObj.setTimeout._isMockFunction).toBe(true)
65-
expect(globalObj.setTimeout.clock).toBeUndefined()
66-
67-
jest.useRealTimers()
6866

69-
// modern timers use a clock instance instead of a mock
70-
jest.useFakeTimers('modern')
71-
runWithRealTimers(() => {
72-
expect(originalSetTimeout).toEqual(globalObj.setTimeout)
67+
test('use real timers when timers are faked with jest.useFakeTimers(legacy)', () => {
68+
// legacy timers use mocks and do not rely on a clock instance
69+
jest.useFakeTimers('legacy')
70+
runWithRealTimers(() => {
71+
expect(global.setTimeout).toBe(realSetTimeout)
72+
})
73+
expect(global.setTimeout._isMockFunction).toBe(true)
74+
expect(global.setTimeout.clock).toBeUndefined()
7375
})
74-
expect(globalObj.setTimeout._isMockFunction).toBeUndefined()
75-
expect(globalObj.setTimeout.clock).toBeDefined()
76-
})
77-
78-
test('should not use realTimers when timers are not faked with useFakeTimers', () => {
79-
const originalSetTimeout = globalObj.setTimeout
8076

81-
// useFakeTimers is not used, timers are faked in some other way
82-
const fakedSetTimeout = callback => {
83-
callback()
84-
}
85-
fakedSetTimeout.clock = jest.fn()
77+
test('use real timers when timers are faked with jest.useFakeTimers(modern)', () => {
78+
// modern timers use a clock instance instead of a mock
79+
jest.useFakeTimers('modern')
80+
runWithRealTimers(() => {
81+
expect(global.setTimeout).toBe(realSetTimeout)
82+
})
83+
expect(global.setTimeout._isMockFunction).toBeUndefined()
84+
expect(global.setTimeout.clock).toBeDefined()
85+
})
8686

87-
globalObj.setTimeout = fakedSetTimeout
87+
test('do not use real timers when timers are not faked with jest.useFakeTimers', () => {
88+
// useFakeTimers is not used, timers are faked in some other way
89+
const fakedSetTimeout = callback => {
90+
callback()
91+
}
92+
fakedSetTimeout.clock = jest.fn()
93+
global.setTimeout = fakedSetTimeout
8894

89-
runWithRealTimers(() => {
90-
expect(fakedSetTimeout).toEqual(globalObj.setTimeout)
95+
runWithRealTimers(() => {
96+
expect(global.setTimeout).toBe(fakedSetTimeout)
97+
})
98+
expect(global.setTimeout).toBe(fakedSetTimeout)
9199
})
92-
93-
globalObj.setTimeout = originalSetTimeout
94100
})

src/helpers.js

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,52 @@ const TEXT_NODE = 3
55

66
// Currently this fn only supports jest timers, but it could support other test runners in the future.
77
function runWithRealTimers(callback) {
8-
const fakeTimersType = getJestFakeTimersType()
9-
if (fakeTimersType) {
10-
jest.useRealTimers()
8+
// istanbul ignore else
9+
if (typeof jest !== 'undefined') {
10+
return runWithJestRealTimers(callback).callbackReturnValue
1111
}
1212

13-
const callbackReturnValue = callback()
13+
// istanbul ignore next
14+
return callback()
15+
}
1416

15-
if (fakeTimersType) {
16-
jest.useFakeTimers(fakeTimersType)
17+
function runWithJestRealTimers(callback) {
18+
const timerAPI = {
19+
clearImmediate,
20+
clearInterval,
21+
clearTimeout,
22+
setImmediate,
23+
setInterval,
24+
setTimeout,
1725
}
1826

19-
return callbackReturnValue
20-
}
27+
jest.useRealTimers()
2128

22-
function getJestFakeTimersType() {
23-
// istanbul ignore if
24-
if (
25-
typeof jest === 'undefined' ||
26-
typeof globalObj.setTimeout === 'undefined'
27-
) {
28-
return null
29-
}
29+
const callbackReturnValue = callback()
3030

31-
if (
32-
typeof globalObj.setTimeout._isMockFunction !== 'undefined' &&
33-
globalObj.setTimeout._isMockFunction
34-
) {
35-
return 'legacy'
31+
const usedFakeTimers = Object.entries(timerAPI).some(
32+
([name, func]) => func !== globalObj[name],
33+
)
34+
35+
if (usedFakeTimers) {
36+
jest.useFakeTimers(timerAPI.setTimeout?.clock ? 'modern' : 'legacy')
3637
}
3738

38-
if (
39-
typeof globalObj.setTimeout.clock !== 'undefined' &&
40-
typeof jest.getRealSystemTime !== 'undefined'
41-
) {
42-
try {
43-
// jest.getRealSystemTime is only supported for Jest's `modern` fake timers and otherwise throws
44-
jest.getRealSystemTime()
45-
return 'modern'
46-
} catch {
47-
// not using Jest's modern fake timers
48-
}
39+
return {
40+
callbackReturnValue,
41+
usedFakeTimers,
4942
}
50-
return null
5143
}
5244

53-
const jestFakeTimersAreEnabled = () => Boolean(getJestFakeTimersType())
45+
function jestFakeTimersAreEnabled() {
46+
// istanbul ignore else
47+
if (typeof jest !== 'undefined') {
48+
return runWithJestRealTimers(() => {}).usedFakeTimers
49+
}
50+
51+
// istanbul ignore next
52+
return false
53+
}
5454

5555
// we only run our tests in node, and setImmediate is supported in node.
5656
// istanbul ignore next
@@ -92,6 +92,10 @@ function getWindowFromNode(node) {
9292
throw new Error(
9393
`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...\`?`,
9494
)
95+
} else if (Array.isArray(node)) {
96+
throw new Error(
97+
`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...\`?`,
98+
)
9599
} else {
96100
// The user passed something unusual to a calling function
97101
throw new Error(

src/wait-for.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ function waitFor(
5252

5353
const overallTimeoutTimer = setTimeout(handleTimeout, timeout)
5454

55-
const usingFakeTimers = jestFakeTimersAreEnabled()
56-
if (usingFakeTimers) {
55+
const usingJestFakeTimers = jestFakeTimersAreEnabled()
56+
if (usingJestFakeTimers) {
5757
checkCallback()
5858
// this is a dangerous rule to disable because it could lead to an
5959
// infinite loop. However, eslint isn't smart enough to know that we're
@@ -107,7 +107,7 @@ function waitFor(
107107
finished = true
108108
clearTimeout(overallTimeoutTimer)
109109

110-
if (!usingFakeTimers) {
110+
if (!usingJestFakeTimers) {
111111
clearInterval(intervalId)
112112
observer.disconnect()
113113
}

0 commit comments

Comments
 (0)