Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(type): wrap type in the asyncWrapper from DOM Testing Library #303

Merged
merged 2 commits into from Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions package.json
Expand Up @@ -40,23 +40,33 @@
"@babel/runtime": "^7.10.2"
},
"devDependencies": {
"@testing-library/dom": "^7.8.0",
"@testing-library/dom": "^7.9.0",
"@testing-library/jest-dom": "^5.9.0",
"@testing-library/react": "^10.0.5",
"kcd-scripts": "^6.2.0",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"peerDependencies": {
"@testing-library/dom": ">=5"
"@testing-library/dom": ">=7.9.0"
},
"eslintConfig": {
"extends": "./node_modules/kcd-scripts/eslint.js",
"rules": {
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/tabindex-no-positive": "off",
"no-return-assign": "off"
}
},
"overrides": [
{
"files": [
"**/__tests__/**"
],
"rules": {
"no-console": "off"
}
}
]
},
"eslintIgnore": [
"node_modules",
Expand Down
38 changes: 19 additions & 19 deletions src/__tests__/type.js
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import {render, screen} from '@testing-library/react'
import userEvent from '../../src'

test.each(['input', 'textarea'])('should type text in <%s>', type => {
test.each(['input', 'textarea'])('should type text in <%s>', async type => {
const onChange = jest.fn()
render(
React.createElement(type, {
Expand All @@ -11,30 +11,30 @@ test.each(['input', 'textarea'])('should type text in <%s>', type => {
}),
)
const text = 'Hello, world!'
userEvent.type(screen.getByTestId('input'), text)
await userEvent.type(screen.getByTestId('input'), text)
expect(onChange).toHaveBeenCalledTimes(text.length)
expect(screen.getByTestId('input')).toHaveProperty('value', text)
})

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

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

test('should not type when event.preventDefault() is called', () => {
test('should not type when event.preventDefault() is called', async () => {
const onChange = jest.fn()
const onKeydown = jest
.fn()
Expand All @@ -43,15 +43,15 @@ test('should not type when event.preventDefault() is called', () => {
<input data-testid="input" onKeyDown={onKeydown} onChange={onChange} />,
)
const text = 'Hello, world!'
userEvent.type(screen.getByTestId('input'), text)
await userEvent.type(screen.getByTestId('input'), text)
expect(onKeydown).toHaveBeenCalledTimes(text.length)
expect(onChange).toHaveBeenCalledTimes(0)
expect(screen.getByTestId('input')).not.toHaveProperty('value', text)
})

test.each(['input', 'textarea'])(
'should not type when <%s> is disabled',
type => {
async type => {
const onChange = jest.fn()
render(
React.createElement(type, {
Expand All @@ -61,15 +61,15 @@ test.each(['input', 'textarea'])(
}),
)
const text = 'Hello, world!'
userEvent.type(screen.getByTestId('input'), text)
await userEvent.type(screen.getByTestId('input'), text)
expect(onChange).not.toHaveBeenCalled()
expect(screen.getByTestId('input')).toHaveProperty('value', '')
},
)

test.each(['input', 'textarea'])(
'should not type when <%s> is readOnly',
type => {
async type => {
const onChange = jest.fn()
const onKeyDown = jest.fn()
const onKeyPress = jest.fn()
Expand All @@ -85,7 +85,7 @@ test.each(['input', 'textarea'])(
}),
)
const text = 'Hello, world!'
userEvent.type(screen.getByTestId('input'), text)
await userEvent.type(screen.getByTestId('input'), text)
expect(onKeyDown).toHaveBeenCalledTimes(text.length)
expect(onKeyPress).toHaveBeenCalledTimes(text.length)
expect(onKeyUp).toHaveBeenCalledTimes(text.length)
Expand Down Expand Up @@ -154,7 +154,7 @@ test.each(['input', 'textarea'])(

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

const inputEl = screen.getByTestId('input')

userEvent.type(inputEl, text)
await userEvent.type(inputEl, text)

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

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

const inputEl = screen.getByTestId('input')

userEvent.type(inputEl, text1)
userEvent.type(inputEl, text2)
await userEvent.type(inputEl, text1)
await userEvent.type(inputEl, text2)

expect(inputEl).toHaveProperty('value', slicedText)
expect(onChange).toHaveBeenCalledTimes(slicedText.length)
Expand Down
27 changes: 27 additions & 0 deletions src/__tests__/wrapping-in-act-is-unnecessary.js
Expand Up @@ -22,3 +22,30 @@ test('act necessitating side effect', () => {

expect(effectCallback).toHaveBeenCalledTimes(1)
})

test('act necessitating async side effect', async () => {
function TestComponent() {
const [renderMessage, setRenderMessage] = React.useState(false)
function handleChange() {
Promise.resolve().then(() => {
setRenderMessage(true)
})
}
return (
<div>
<input type="text" onChange={handleChange} />
<div>{renderMessage ? 'MESSAGE' : null}</div>
</div>
)
}
render(<TestComponent />)

// https://github.com/testing-library/dom-testing-library/pull/602
// before our fixes in DOM Testing Library, we had to wrap
// this next line in act for this test to pass.
await userEvent.type(screen.getByRole('textbox'), 'a')

expect(await screen.findByText('MESSAGE')).toBeInTheDocument()

expect(console.error).not.toHaveBeenCalled()
})