Skip to content

Commit 9fe76b4

Browse files
authored
fix(type): wrap type in the asyncWrapper from DOM Testing Library (testing-library#303)
BREAKING CHANGE: The DOM Testing Library version 7.9.0 or greater is required
1 parent eb33bdb commit 9fe76b4

File tree

5 files changed

+137
-56
lines changed

5 files changed

+137
-56
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,33 @@
4040
"@babel/runtime": "^7.10.2"
4141
},
4242
"devDependencies": {
43-
"@testing-library/dom": "^7.8.0",
43+
"@testing-library/dom": "^7.9.0",
4444
"@testing-library/jest-dom": "^5.9.0",
4545
"@testing-library/react": "^10.0.5",
4646
"kcd-scripts": "^6.2.0",
4747
"react": "^16.13.1",
4848
"react-dom": "^16.13.1"
4949
},
5050
"peerDependencies": {
51-
"@testing-library/dom": ">=5"
51+
"@testing-library/dom": ">=7.9.0"
5252
},
5353
"eslintConfig": {
5454
"extends": "./node_modules/kcd-scripts/eslint.js",
5555
"rules": {
5656
"jsx-a11y/click-events-have-key-events": "off",
5757
"jsx-a11y/tabindex-no-positive": "off",
5858
"no-return-assign": "off"
59-
}
59+
},
60+
"overrides": [
61+
{
62+
"files": [
63+
"**/__tests__/**"
64+
],
65+
"rules": {
66+
"no-console": "off"
67+
}
68+
}
69+
]
6070
},
6171
"eslintIgnore": [
6272
"node_modules",

src/__tests__/type.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22
import {render, screen} from '@testing-library/react'
33
import userEvent from '../../src'
44

5-
test.each(['input', 'textarea'])('should type text in <%s>', type => {
5+
test.each(['input', 'textarea'])('should type text in <%s>', async type => {
66
const onChange = jest.fn()
77
render(
88
React.createElement(type, {
@@ -11,30 +11,30 @@ test.each(['input', 'textarea'])('should type text in <%s>', type => {
1111
}),
1212
)
1313
const text = 'Hello, world!'
14-
userEvent.type(screen.getByTestId('input'), text)
14+
await userEvent.type(screen.getByTestId('input'), text)
1515
expect(onChange).toHaveBeenCalledTimes(text.length)
1616
expect(screen.getByTestId('input')).toHaveProperty('value', text)
1717
})
1818

19-
test('should append text one by one', () => {
19+
test('should append text one by one', async () => {
2020
const onChange = jest.fn()
2121
render(<input data-testid="input" onChange={onChange} />)
22-
userEvent.type(screen.getByTestId('input'), 'hello')
23-
userEvent.type(screen.getByTestId('input'), ' world')
22+
await userEvent.type(screen.getByTestId('input'), 'hello')
23+
await userEvent.type(screen.getByTestId('input'), ' world')
2424
expect(onChange).toHaveBeenCalledTimes('hello world'.length)
2525
expect(screen.getByTestId('input')).toHaveProperty('value', 'hello world')
2626
})
2727

28-
test('should append text all at once', () => {
28+
test('should append text all at once', async () => {
2929
const onChange = jest.fn()
3030
render(<input data-testid="input" onChange={onChange} />)
31-
userEvent.type(screen.getByTestId('input'), 'hello', {allAtOnce: true})
32-
userEvent.type(screen.getByTestId('input'), ' world', {allAtOnce: true})
31+
await userEvent.type(screen.getByTestId('input'), 'hello', {allAtOnce: true})
32+
await userEvent.type(screen.getByTestId('input'), ' world', {allAtOnce: true})
3333
expect(onChange).toHaveBeenCalledTimes(2)
3434
expect(screen.getByTestId('input')).toHaveProperty('value', 'hello world')
3535
})
3636

37-
test('should not type when event.preventDefault() is called', () => {
37+
test('should not type when event.preventDefault() is called', async () => {
3838
const onChange = jest.fn()
3939
const onKeydown = jest
4040
.fn()
@@ -43,15 +43,15 @@ test('should not type when event.preventDefault() is called', () => {
4343
<input data-testid="input" onKeyDown={onKeydown} onChange={onChange} />,
4444
)
4545
const text = 'Hello, world!'
46-
userEvent.type(screen.getByTestId('input'), text)
46+
await userEvent.type(screen.getByTestId('input'), text)
4747
expect(onKeydown).toHaveBeenCalledTimes(text.length)
4848
expect(onChange).toHaveBeenCalledTimes(0)
4949
expect(screen.getByTestId('input')).not.toHaveProperty('value', text)
5050
})
5151

5252
test.each(['input', 'textarea'])(
5353
'should not type when <%s> is disabled',
54-
type => {
54+
async type => {
5555
const onChange = jest.fn()
5656
render(
5757
React.createElement(type, {
@@ -61,15 +61,15 @@ test.each(['input', 'textarea'])(
6161
}),
6262
)
6363
const text = 'Hello, world!'
64-
userEvent.type(screen.getByTestId('input'), text)
64+
await userEvent.type(screen.getByTestId('input'), text)
6565
expect(onChange).not.toHaveBeenCalled()
6666
expect(screen.getByTestId('input')).toHaveProperty('value', '')
6767
},
6868
)
6969

7070
test.each(['input', 'textarea'])(
7171
'should not type when <%s> is readOnly',
72-
type => {
72+
async type => {
7373
const onChange = jest.fn()
7474
const onKeyDown = jest.fn()
7575
const onKeyPress = jest.fn()
@@ -85,7 +85,7 @@ test.each(['input', 'textarea'])(
8585
}),
8686
)
8787
const text = 'Hello, world!'
88-
userEvent.type(screen.getByTestId('input'), text)
88+
await userEvent.type(screen.getByTestId('input'), text)
8989
expect(onKeyDown).toHaveBeenCalledTimes(text.length)
9090
expect(onKeyPress).toHaveBeenCalledTimes(text.length)
9191
expect(onKeyUp).toHaveBeenCalledTimes(text.length)
@@ -154,7 +154,7 @@ test.each(['input', 'textarea'])(
154154

155155
test.each(['input', 'textarea'])(
156156
'should enter text in <%s> up to maxLength if provided',
157-
type => {
157+
async type => {
158158
const onChange = jest.fn()
159159
const onKeyDown = jest.fn()
160160
const onKeyPress = jest.fn()
@@ -177,7 +177,7 @@ test.each(['input', 'textarea'])(
177177

178178
const inputEl = screen.getByTestId('input')
179179

180-
userEvent.type(inputEl, text)
180+
await userEvent.type(inputEl, text)
181181

182182
expect(inputEl).toHaveProperty('value', slicedText)
183183
expect(onChange).toHaveBeenCalledTimes(slicedText.length)
@@ -205,7 +205,7 @@ test.each(['input', 'textarea'])(
205205

206206
test.each(['input', 'textarea'])(
207207
'should append text in <%s> up to maxLength if provided',
208-
type => {
208+
async type => {
209209
const onChange = jest.fn()
210210
const onKeyDown = jest.fn()
211211
const onKeyPress = jest.fn()
@@ -230,8 +230,8 @@ test.each(['input', 'textarea'])(
230230

231231
const inputEl = screen.getByTestId('input')
232232

233-
userEvent.type(inputEl, text1)
234-
userEvent.type(inputEl, text2)
233+
await userEvent.type(inputEl, text1)
234+
await userEvent.type(inputEl, text2)
235235

236236
expect(inputEl).toHaveProperty('value', slicedText)
237237
expect(onChange).toHaveBeenCalledTimes(slicedText.length)

src/__tests__/wrapping-in-act-is-unnecessary.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,30 @@ test('act necessitating side effect', () => {
2222

2323
expect(effectCallback).toHaveBeenCalledTimes(1)
2424
})
25+
26+
test('act necessitating async side effect', async () => {
27+
function TestComponent() {
28+
const [renderMessage, setRenderMessage] = React.useState(false)
29+
function handleChange() {
30+
Promise.resolve().then(() => {
31+
setRenderMessage(true)
32+
})
33+
}
34+
return (
35+
<div>
36+
<input type="text" onChange={handleChange} />
37+
<div>{renderMessage ? 'MESSAGE' : null}</div>
38+
</div>
39+
)
40+
}
41+
render(<TestComponent />)
42+
43+
// https://github.com/testing-library/dom-testing-library/pull/602
44+
// before our fixes in DOM Testing Library, we had to wrap
45+
// this next line in act for this test to pass.
46+
await userEvent.type(screen.getByRole('textbox'), 'a')
47+
48+
expect(await screen.findByText('MESSAGE')).toBeInTheDocument()
49+
50+
expect(console.error).not.toHaveBeenCalled()
51+
})

0 commit comments

Comments
 (0)