Skip to content

Commit 6147830

Browse files
authored
fix(fireEvent): automatically configure fireEvent to be wrapped in act (#685)
1 parent 7b7460a commit 6147830

File tree

3 files changed

+55
-57
lines changed

3 files changed

+55
-57
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ cache: npm
33
notifications:
44
email: false
55
node_js:
6-
- 10.0.0
6+
# technically we support 10.0.0, but some of our tooling doesn't
7+
- 10.14.2
78
- 12
89
- 14
910
- node

src/fire-event.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {fireEvent as dtlFireEvent} from '@testing-library/dom'
2+
3+
// react-testing-library's version of fireEvent will call
4+
// dom-testing-library's version of fireEvent. The reason
5+
// we make this distinction however is because we have
6+
// a few extra events that work a bit differently
7+
const fireEvent = (...args) => dtlFireEvent(...args)
8+
9+
Object.keys(dtlFireEvent).forEach(key => {
10+
fireEvent[key] = (...args) => dtlFireEvent[key](...args)
11+
})
12+
13+
// React event system tracks native mouseOver/mouseOut events for
14+
// running onMouseEnter/onMouseLeave handlers
15+
// @link https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/events/EnterLeaveEventPlugin.js#L24-L31
16+
const mouseEnter = fireEvent.mouseEnter
17+
const mouseLeave = fireEvent.mouseLeave
18+
fireEvent.mouseEnter = (...args) => {
19+
mouseEnter(...args)
20+
return fireEvent.mouseOver(...args)
21+
}
22+
fireEvent.mouseLeave = (...args) => {
23+
mouseLeave(...args)
24+
return fireEvent.mouseOut(...args)
25+
}
26+
27+
const select = fireEvent.select
28+
fireEvent.select = (node, init) => {
29+
select(node, init)
30+
// React tracks this event only on focused inputs
31+
node.focus()
32+
33+
// React creates this event when one of the following native events happens
34+
// - contextMenu
35+
// - mouseUp
36+
// - dragEnd
37+
// - keyUp
38+
// - keyDown
39+
// so we can use any here
40+
// @link https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/events/SelectEventPlugin.js#L203-L224
41+
fireEvent.keyUp(node, init)
42+
}
43+
44+
export {fireEvent}

src/pure.js

Lines changed: 9 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import ReactDOM from 'react-dom'
33
import {
44
getQueriesForElement,
55
prettyDOM,
6-
fireEvent as dtlFireEvent,
76
configure as configureDTL,
87
} from '@testing-library/dom'
98
import act, {asyncAct} from './act-compat'
9+
import {fireEvent} from './fire-event'
1010
import flush from './flush-microtasks'
1111

1212
configureDTL({
@@ -17,6 +17,13 @@ configureDTL({
1717
})
1818
return result
1919
},
20+
eventWrapper: cb => {
21+
let result
22+
act(() => {
23+
result = cb()
24+
})
25+
return result
26+
},
2027
})
2128

2229
const mountedContainers = new Set()
@@ -104,63 +111,9 @@ function cleanupAtContainer(container) {
104111
mountedContainers.delete(container)
105112
}
106113

107-
// react-testing-library's version of fireEvent will call
108-
// dom-testing-library's version of fireEvent wrapped inside
109-
// an "act" call so that after all event callbacks have been
110-
// called, the resulting useEffect callbacks will also be
111-
// called.
112-
function fireEvent(...args) {
113-
let returnValue
114-
act(() => {
115-
returnValue = dtlFireEvent(...args)
116-
})
117-
return returnValue
118-
}
119-
120-
Object.keys(dtlFireEvent).forEach(key => {
121-
fireEvent[key] = (...args) => {
122-
let returnValue
123-
act(() => {
124-
returnValue = dtlFireEvent[key](...args)
125-
})
126-
return returnValue
127-
}
128-
})
129-
130-
// React event system tracks native mouseOver/mouseOut events for
131-
// running onMouseEnter/onMouseLeave handlers
132-
// @link https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/events/EnterLeaveEventPlugin.js#L24-L31
133-
const mouseEnter = fireEvent.mouseEnter
134-
const mouseLeave = fireEvent.mouseLeave
135-
fireEvent.mouseEnter = (...args) => {
136-
mouseEnter(...args)
137-
return fireEvent.mouseOver(...args)
138-
}
139-
fireEvent.mouseLeave = (...args) => {
140-
mouseLeave(...args)
141-
return fireEvent.mouseOut(...args)
142-
}
143-
144-
const select = fireEvent.select
145-
fireEvent.select = (node, init) => {
146-
select(node, init)
147-
// React tracks this event only on focused inputs
148-
node.focus()
149-
150-
// React creates this event when one of the following native events happens
151-
// - contextMenu
152-
// - mouseUp
153-
// - dragEnd
154-
// - keyUp
155-
// - keyDown
156-
// so we can use any here
157-
// @link https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/events/SelectEventPlugin.js#L203-L224
158-
fireEvent.keyUp(node, init)
159-
}
160-
161114
// just re-export everything from dom-testing-library
162115
export * from '@testing-library/dom'
163-
export {render, cleanup, fireEvent, act}
116+
export {render, cleanup, act, fireEvent}
164117

165118
// NOTE: we're not going to export asyncAct because that's our own compatibility
166119
// thing for people using [email protected]. Anyone else doesn't need it and

0 commit comments

Comments
 (0)