v7.0.0
7.0.0 (2020-03-12)
Features
- waitFor: replace
wait
withwaitFor
(read more in the Breaking changes list below) (2b641e1), closes #376 #416 - waitForElementToBeRemoved: support passing an element directly (#460) (1b711a4)
The new feature in waitForElementToBeRemoved
is pretty cool. Here's what you had to do before:
const submitButton = screen.getByText(/submit/i)
fireEvent.click(submitButton)
await waitForElementToBeRemoved(() => screen.getByText(/submit/i))
// submit is now gone
That still works, but you can now do this too:
const submitButton = screen.getByText(/submit/i)
fireEvent.click(submitButton)
await waitForElementToBeRemoved(submitButton)
// submit is now gone
Cool right!?
BREAKING CHANGES
Drop Node 8
Node 10 or greater is required. Node 8 is out of LTS (#459) (c3ab843), closes #430
MutationObserver shim removed.
MutationObserver is supported by all major browsers and recent versions of JSDOM. If you need, you can create your own shim (using @sheerun/mutationobserver-shim
) and attach it to the window
. If you're on an old version of Jest, either update your version of Jest or use jest-environment-jsdom-sixteen
(#457) (e3fdb8e9)
If you're using the latest version of react-scripts
(Create React App), here are your options:
Option 1:
Wait until the react-scripts
updates to the latest version of Jest (subscribe to this PR)
Option 2 (recommended):
Install jest-environment-jsdom-sixteen
and then update your test
script:
...
"scripts": {
...
- "test": "react-scripts test --env=dom"
+ "test": "react-scripts test --env=jest-environment-jsdom-sixteen"
...
},
...
"devDependencies": {
...
"jest-environment-jsdom-sixteen": "^1.0.3",
...
},
...
Option 3:
Add the MutationObserver constructor to window
via @sheerun/mutationobserver-shim
:
npm install --save-dev @sheerun/mutationobserver-shim
# yarn add --dev @sheerun/mutationobserver-shim
// src/setupTests.js
import MutationObserver from '@sheerun/mutationobserver-shim'
window.MutationObserver = MutationObserver
waitFor: wait
is now deprecated in favor of waitFor
waitFor
satisfies the use cases of wait
, waitForElement
, and waitForDomChange
, so those have been deprecated (will be removed in the next major version). Here are some examples of how you can change those:
- await wait()
+ await waitFor(() => {})
This should get you going on the upgrade, but it's recommended to avoid an empty callback and instead insert an assertion in that callback function. This is because otherwise your test is relying on the "next tick of the event loop" before proceeding, and that's not consistent with the philosophy of the library:
The more your tests resemble the way your software is used, the more confidence they can give you.
So it would be better to move the assertion that followed await wait()
into the callback you provide to await waitFor(() => { /* assertion here */ })
As for waitForElement
, that should normally be accomplished with one of the find*
queries:
- const element = await waitForElement(() => screen.getByText(/loading/i))
+ const element = await screen.findByText(/loading/i)
However, if for some reason you cannot use a find
query, then waitFor
should be a find/replace for waitForElement
:
- const element = await waitForElement(() => container.querySelector('.loading'))
+ const element = await waitFor(() => container.querySelector('.loading'))
waitForDomChange
encouraged testing implementation details because the user doesn't care about when the DOM changes, they care about when something appears or disappears from the page, so it's better to use waitFor
with a specific assertion or waitForElementToBeRemoved
(if that's what you're actually trying to do):
- await waitForDomChange()
+ await waitFor(() => {})
// remember, this is not recommended, provide a specific assertion
- await waitForDomChange(mutationObserverOptions)
+ await waitFor(() => {}, mutationObserverOptions)
// if you provided mutationObserverOptions, you can provide those as a second argument
Note that wait
called your callback function on an interval and waitFor
also does this, but it also calls your callback with the mutation observer as well, which is why it supports the use cases of the deprecated methods so well.
And to be clear, waitForElementToBeRemoved
, is not getting deprecated or removed, in fact, it got a really neat new feature which you can read about above.
default timeout for async utilities is now 1000ms rather than 4500ms
Most of the time in the kinds of tests that people are writing with DOM Testing Library, if something doesn't happen within 1 second, then it probably won't happen at all and waiting a full 4.5 seconds is a frustrating amount of time. So that's why the default has been changed, however this can be configured when calling the async utility via the timeout
option and it can also be globally configured: https://testing-library.com/docs/dom-testing-library/api-configuration
- ByLabelText: If you used the
selector
option inByLabelText
queries, then you will probably need to update that code to be able to find the label you're looking for:
// <label for="example-input" class="example">Example</label><input id="example-input" />
- screen.getByLabelText(/example/i, {selector: '.example'})
+ screen.getByLabelText(/example/i)
+ // or: screen.getByLabelText(/example/i, {selector: '#example-input})
Changed the selector
option in ByLabelText
queries.
If you used the selector
option in ByLabelText
queries, then you will probably need to update that code to be able to find the label you're looking for as a result of #373.