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

docs(dom): Document breaking changes of v8 #866

Merged
merged 3 commits into from
Jun 23, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 3 additions & 164 deletions docs/dom-testing-library/api-async.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
// ...
```

`waitFor` may run the callback a variable number of times.
`waitFor` may run the callback a number of times until the timeout is reached.
Note that the number of calls is constrained by the `timeout` and `interval` options.

This can be useful if you have a unit test that mocks API calls and you need to
wait for your mock promises to all resolve.
Expand All @@ -71,8 +72,7 @@ wait for are descendants of `container`.
The default `interval` is `50ms`. However it will run your callback immediately
before starting the intervals.

The default `timeout` is `1000ms` which will keep you under
[Jest's default timeout of `5000ms`](https://jestjs.io/docs/en/jest-object.html#jestsettimeouttimeout).
The default `timeout` is `1000ms`.

The default `onTimeout` takes the error and appends the `container`'s printed
state to the error message which should hopefully make it easier to track down
Expand Down Expand Up @@ -141,164 +141,3 @@ waitForElementToBeRemoved(() => getByText(/not here/i)).catch((err) =>
```

The options object is forwarded to `waitFor`.

## Deprecated Methods

`wait`, `waitForDomChange`, and `waitForElement` have been combined into the
`waitFor` method.

<details>

<br />

<summary>Deprecated Methods</summary>

### `wait`

> (DEPRECATED, use `waitFor` instead)

```typescript
function wait<T>(
callback: () => void,
options?: {
container?: HTMLElement
timeout?: number
interval?: number
mutationObserverOptions?: MutationObserverInit
}
): Promise<T>
```

Previously, wait was a wrapper around wait-for-expect and used polling instead
of a MutationObserver to look for changes. It is now an alias to waitFor and
will be removed in a future release.

Unlike wait, the callback parameter is mandatory in waitFor. Although you can
migrate an existing `wait()` call to `waitFor( () => {} )`, it is considered bad
practice to use an empty callback because it will make the tests more fragile.

### `waitForDomChange`

> (DEPRECATED, use `waitFor` instead)

```typescript
function waitForDomChange<T>(options?: {
container?: HTMLElement
timeout?: number
mutationObserverOptions?: MutationObserverInit
}): Promise<T>
```

When in need to wait for the DOM to change you can use `waitForDomChange`. The
`waitForDomChange` function is a small wrapper around the
[`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).

Here is an example where the promise will be resolved because the container is
changed:

```javascript
const container = document.createElement('div')
waitForDomChange({ container })
.then(() => console.log('DOM changed!'))
.catch((err) => console.log(`Error you need to deal with: ${err}`))
container.append(document.createElement('p'))
// if 👆 was the only code affecting the container and it was not run,
// waitForDomChange would throw an error
```

The promise will resolve with a
[`mutationsList`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver)
which you can use to determine what kind of a change (or changes) affected the
container

```javascript
const container = document.createElement('div')
container.setAttribute('data-cool', 'true')
waitForDomChange({ container }).then((mutationsList) => {
const mutation = mutationsList[0]
console.log(
`was cool: ${mutation.oldValue}\ncurrently cool: ${mutation.target.dataset.cool}`
)
})
container.setAttribute('data-cool', 'false')
/*
logs:
was cool: true
currently cool: false
*/
```

The default `container` is the global `document`. Make sure the elements you
wait for are descendants of `container`.

The default `timeout` is `1000ms` which will keep you under
[Jest's default timeout of `5000ms`](https://jestjs.io/docs/en/jest-object.html#jestsettimeouttimeout).

The default `mutationObserverOptions` is
`{subtree: true, childList: true, attributes: true, characterData: true}` which
will detect additions and removals of child elements (including text nodes) in
the `container` and any of its descendants. It will also detect attribute
changes.

### `waitForElement`

> (DEPRECATED, use `find*` queries or `waitFor`)

```typescript
function waitForElement<T>(
callback: () => T,
options?: {
container?: HTMLElement
timeout?: number
mutationObserverOptions?: MutationObserverInit
}
): Promise<T>
```

When in need to wait for DOM elements to appear, disappear, or change you can
use `waitForElement`. The `waitForElement` function is a small wrapper around
the
[`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).

Here's a simple example:

```javascript
// ...
// Wait until the callback does not throw an error and returns a truthy value. In this case, that means
// it'll wait until we can get a form control with a label that matches "username".
// Previously, the difference from `wait` is that rather than running your callback on
// an interval, it's run as soon as there are DOM changes in the container
// and returns the value returned by the callback.
const usernameElement = await waitForElement(
() => getByLabelText(container, 'username'),
{ container }
)
usernameElement.value = 'chucknorris'
// ...
```

You can also wait for multiple elements at once:

```javascript
const [usernameElement, passwordElement] = await waitForElement(
() => [
getByLabelText(container, 'username'),
getByLabelText(container, 'password'),
],
{ container }
)
```

The default `container` is the global `document`. Make sure the elements you
wait for will be attached to it, or set a different `container`.

The default `timeout` is `4500ms` which will keep you under
[Jest's default timeout of `5000ms`](https://facebook.github.io/jest/docs/en/jest-object.html#jestsettimeouttimeout).

The default `mutationObserverOptions` is
`{subtree: true, childList: true, attributes: true, characterData: true}` which
will detect additions and removals of child elements (including text nodes) in
the `container` and any of its descendants. It will also detect attribute
changes.

</details>
11 changes: 9 additions & 2 deletions docs/dom-testing-library/api-debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ tree of a node. This can be helpful for instance when debugging tests.
It is defined as:

```typescript
interface Options extends prettyFormat.OptionsReceived {
filterNode?: (node: Node) => boolean;
}

function prettyDOM(
node: HTMLElement,
maxLength?: number,
Expand All @@ -59,10 +63,13 @@ function prettyDOM(

It receives the root node to print out, an optional extra parameter to limit the
size of the resulting string, for cases when it becomes too large. It has a last
parameter which allows you to configure your formatting as defined in the
[options](https://github.com/facebook/jest/tree/master/packages/pretty-format#usage-with-options)
parameter which allows you to configure your formatting.
In addition to the options listed you can also pass the [options](https://github.com/facebook/jest/tree/master/packages/pretty-format#usage-with-options)
of `pretty-format`.

By default, `<style />`, `<script />` and comment nodes are ignored.
You can configure this behavior by passing a custom `filterNode` function that should return `true` for every node that you wish to include in the output.

This function is usually used alongside `console.log` to temporarily print out
DOM trees during tests for debugging purposes:

Expand Down