Skip to content

Commit f23d0c3

Browse files
PklongKent C. Dodds
authored and
Kent C. Dodds
committed
add documentation for waitforElementToBeRemoved (#103) (#105)
* add documentation for waitforElementToBeRemoved (#103) * incorporate feedback on waitForElementToBeRemoved * clarify that observed element must be descendent of container * move waitForElementToBeRemoved example above wait example in guide * emphasize callback requirements * move that callback must return element above examples * move error handling from first example to second
1 parent 3582c10 commit f23d0c3

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

docs/dom-testing-library/api-async.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,74 @@ The default `timeout` is `4500ms` which will keep you under
187187
will detect additions and removals of child elements (including text nodes) in
188188
the `container` and any of its descendants. It will also detect attribute
189189
changes.
190+
191+
## `waitForElementToBeRemoved`
192+
193+
```typescript
194+
function waitForElementToBeRemoved<T>(
195+
callback: () => T,
196+
options?: {
197+
container?: HTMLElement
198+
timeout?: number
199+
mutationObserverOptions?: MutationObserverInit
200+
}
201+
): Promise<T>
202+
```
203+
204+
To wait for the removal of element(s) from the DOM you can use
205+
`waitForElementToBeRemoved`. The `waitForElementToBeRemoved` function is a small
206+
wrapper around the
207+
[`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).
208+
209+
The callback must return the pre-existing element or array of elements that are
210+
expected to be removed.
211+
212+
Here is an example where the promise resolves with `true` because the element is
213+
removed:
214+
215+
```javascript
216+
const el = document.querySelector('div.getOuttaHere')
217+
218+
waitForElementToBeRemoved(() =>
219+
document.querySelector('div.getOuttaHere')
220+
).then(() => console.log('Element no longer in DOM'))
221+
222+
el.setAttribute('data-neat', true)
223+
// other mutations are ignored...
224+
225+
el.parentElement.removeChild(el)
226+
// logs 'Element no longer in DOM'
227+
```
228+
229+
`waitForElementToBeRemoved` will throw an error when the provided callback does
230+
not return an element.
231+
232+
```javascript
233+
waitForElementToBeRemoved(() => null).catch(err => console.log(err))
234+
235+
// 'The callback function which was passed did not return an element
236+
// or non-empty array of elements.
237+
// waitForElementToBeRemoved requires that the element(s) exist
238+
// before waiting for removal.'
239+
```
240+
241+
Using
242+
[`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
243+
is more efficient than polling the DOM at regular intervals with `wait`. This
244+
library sets up a
245+
[`'mutationobserver-shim'`](https://github.com/megawac/MutationObserver.js) on
246+
the global `window` object for cross-platform compatibility with older browsers
247+
and the [`jsdom`](https://github.com/jsdom/jsdom/issues/639) that is usually
248+
used in Node-based tests.
249+
250+
The default `container` is the global `document`. Make sure the elements you
251+
wait for are descendants of `container`.
252+
253+
The default `timeout` is `4500ms` which will keep you under
254+
[Jest's default timeout of `5000ms`](https://facebook.github.io/jest/docs/en/jest-object.html#jestsettimeouttimeout).
255+
256+
<a name="mutationobserveroptions"></a>The default `mutationObserverOptions` is
257+
`{subtree: true, childList: true, attributes: true, characterData: true}` which
258+
will detect additions and removals of child elements (including text nodes) in
259+
the `container` and any of its descendants. It will also detect attribute
260+
changes.

docs/guide-disappearance.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ test('movie title appears', async () => {
2828

2929
## Waiting for disappearance
3030

31+
The `waitForElementToBeRemoved` [async helper][async-api] function uses a
32+
callback to query for the element on each DOM mutation and resolves to `true`
33+
when the element is removed.
34+
35+
```jsx
36+
test('movie title no longer present in DOM', async () => {
37+
// element is removed
38+
await waitForElementToBeRemoved(() => queryByText('the mummy'))
39+
})
40+
```
41+
42+
Using
43+
[`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
44+
is more efficient than polling the DOM at regular intervals with `wait`.
45+
3146
The `wait` [async helper][async-api] function retries until the wrapped function
3247
stops throwing an error. This can be used to assert that an element disappears
3348
from the page.

0 commit comments

Comments
 (0)