Skip to content

feat(render): options.wrapper api + customRender usage #39

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

Merged
merged 2 commits into from
Feb 20, 2019
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
49 changes: 33 additions & 16 deletions docs/react-testing-library/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ title: API
`react-testing-library` re-exports everything from `dom-testing-library` as well
as these methods:

- [`render`](#act)
- [`cleanup`](#cleanup)
- [`act`](#act)

---

## `render`

```typescript
Expand Down Expand Up @@ -44,19 +50,17 @@ test('renders a message', () => {
> The [cleanup](#cleanup) function should be called between tests to remove the
> created DOM nodes and keep the tests isolated.

### `render` Options

<details>

<summary>Expand to see documentation on the options</summary>
## `render` Options

You wont often need to specify options, but if you ever do, here are the
available options which you could provide as a second argument to `render`.

**container**: By default, `react-testing-library` will create a `div` and
append that div to the `document.body` and this is where your react component
will be rendered. If you provide your own HTMLElement `container` via this
option, it will not be appended to the `document.body` automatically.
### `container`

By default, `react-testing-library` will create a `div` and append that div to
the `document.body` and this is where your react component will be rendered. If
you provide your own HTMLElement `container` via this option, it will not be
appended to the `document.body` automatically.

For Example: If you are unit testing a `tablebody` element, it cannot be a child
of a `div`. In this case, you can specify a `table` as the render `container`.
Expand All @@ -69,26 +73,35 @@ const { container } = render(<TableBody {...props} />, {
})
```

**baseElement**: If the `container` is specified, then this defaults to that,
otherwise this defaults to `document.documentElement`. This is used as the base
element for the queries as well as what is printed when you use `debug()`.
### `baseElement`

If the `container` is specified, then this defaults to that, otherwise this
defaults to `document.documentElement`. This is used as the base element for the
queries as well as what is printed when you use `debug()`.

### `hydrate`

**hydrate**: If hydrate is set to true, then it will render with
If hydrate is set to true, then it will render with
[ReactDOM.hydrate](https://reactjs.org/docs/react-dom.html#hydrate). This may be
useful if you are using server-side rendering and use ReactDOM.hydrate to mount
your components.

</details>
### `wrapper`

---
Pass a React Component as the `wrapper` option to have it rendered around the
inner element. This is most useful for creating reusable custom render functions
for common data providers. See [setup](setup.md#custom-render) for examples.

## `render` Result

The `render` method returns an object that has a few properties:

### `...queries`

The most important feature of `render` is that the queries from
[dom-testing-library](api-queries.md) are automatically returned with their
first argument bound to the rendered container.
first argument bound to the [baseElement](#baseelement), which defaults to
`document.body`.

See [Queries](api-queries.md) for a complete list.

Expand Down Expand Up @@ -222,6 +235,8 @@ fireEvent.click(getByText(/Click to increase/))
expect(firstRender).toMatchDiffSnapshot(asFragment())
```

---

## `cleanup`

Unmounts React trees that were mounted with [render](#render).
Expand All @@ -248,6 +263,8 @@ that you configure your test framework to run a file before your tests which
does this automatically. See the [setup](./setup) section for guidance on how to
set up your framework.

---

## `act`

This is a light wrapper around the
Expand Down
138 changes: 68 additions & 70 deletions docs/react-testing-library/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@ sidebar_label: Setup
demonstrated in the example above). However, there are some things you can do
when configuring your testing framework to reduce some boilerplate. In these
docs we'll demonstrate configuring Jest, but you should be able to do similar
things with any testing framework (react-testing-library does not require that
you use Jest).
things with [any testing framework](#using-without-jest) (react-testing-library
does not require that you use Jest).

## Global Config

There are several options you can add to your global test config that simplify
the setup and teardown of tests in individual files. For example, you can ensure
[`cleanup`](./api#cleanup) is called after each test and import additional
assertions.
Adding options to your global test config can simplify the setup and teardown of
tests in individual files.

To do this with Jest 24 and up, you can add the
### Cleanup

You can ensure [`cleanup`](./api#cleanup) is called after each test and import
additional assertions by adding it to the setup configuration in Jest.

In Jest 24 and up, add the
[`setupFilesAfterEnv`](https://jestjs.io/docs/en/configuration.html#setupfilesafterenv-array)
option to your Jest config.
option to your Jest config:

```javascript
// jest.config.js
Expand All @@ -33,10 +36,10 @@ module.exports = {
}
```

### Older versions of Jest

<details>

<summary>Older versions of Jest</summary>

Jest versions 23 and below use the
[`setupTestFrameworkScriptFile`](https://jestjs.io/docs/en/23.x/configuration#setuptestframeworkscriptfile-string)
option in your Jest config instead of `setupFilesAfterEnv`. This setup file can
Expand Down Expand Up @@ -72,7 +75,11 @@ It's often useful to define a custom render method that includes things like
global context providers, data stores, etc. To make this available globally, one
approach is to define a utility file that re-exports everything from
`react-testing-library`. You can replace react-testing-library with this file in
all your imports.
all your imports. See [below](#comfiguring-jest-with-test-utils) for a way to
make your test util file accessible without using relative paths.

The example below sets up data providers using the
[`wrapper`](api.md#render-options) option to `render`.

```diff
// my-component.test.js
Expand All @@ -87,27 +94,64 @@ import { ThemeProvider } from 'my-ui-lib'
import { TranslationProvider } from 'my-i18n-lib'
import defaultStrings from 'i18n/en-x-default'

const customRender = (node, options) => {
return render(
const AllTheProviders = ({ children }) => {
return (
<ThemeProvider theme="light">
<TranslationProvider messages={defaultStrings}>
{node}
{children}
</TranslationProvider>
</ThemeProvider>,
options
</ThemeProvider>
)
}

const customRender = (ui, options) =>
render(ui, { wrapper: AllTheProviders, ...options })

// re-export everything
export * from 'react-testing-library'

// override render method
export { customRender as render }
```

To make this file accessible without using relative imports, add the folder
containing the file to the Jest `moduleDirectories` option. Note: this will make
_all_ the .js files in that directory importable without `../`.
> **Note**
>
> Babel versions lower than 7 throw an error when trying to override the named
> export in the example above. See
> [#169](https://github.com/kentcdodds/react-testing-library/issues/169) and the
> workaround below.

<details>
<summary>Workaround for Babel 6</summary>

You can use CommonJS modules instead of ES modules, which should work in Node:

```js
// test-utils.js
const rtl = require('react-testing-library')

const customRender = (ui, options) =>
rtl.render(ui, {
myDefaultOption: 'something',
...options,
})

module.exports = {
...rtl,
render: customRender,
}
```

</details>

### Configuring Jest with Test Utils

To make your custom test file accessible in your Jest test files without using
relative imports (`../../test-utils`), add the folder containing the file to the
Jest `moduleDirectories` option.

This will make all the `.js` files in the test-utils directory importable
without `../`.

```diff
// my-component.test.js
Expand All @@ -128,9 +172,11 @@ module.exports = {
}
```

If your project is based on top of Create React App, to make the file accessible
without using relative imports, you just need to create a `.env` file in the
root of your project with the following configuration:
### Jest and Create React App

If your project is based on top of Create React App, to make the `test-utils`
file accessible without using relative imports, you just need to create a `.env`
file in the root of your project with the following configuration:

```
// Create React App project structure
Expand All @@ -151,54 +197,6 @@ $ app
NODE_PATH=src/utils
```

There is the case when you want to wrap your components in a `Provider`, this
might cause conflicts when `rerender`ed. To achieve this, we suggest the
`rerender` should be implemented the same way custom queries, by changing the
return value of the customRender.

```js
// test-utils.js

const customRender = (ui, options) => {
const rendered = render(<div>{ui}</div>, options)
return {
...rendered,
rerender: newUi =>
customRender(newUi, {
container: rendered.container,
baseElement: rendered.baseElement,
}),
}
}
```

### Export Issue with Babel Versions Lower Than 7

Babel versions lower than 7 throw an error when trying to override the named
export in the example above. (See
[#169](https://github.com/kentcdodds/react-testing-library/issues/169).)

<details>
<summary>Workaround</summary>

You can use CommonJS modules instead of ES modules, which should work in Node:

```js
// test-utils.js
const rtl = require('react-testing-library')

const customRender = (node, options) => {
return rtl.render(<Something>{node}</Something>)
}

module.exports = {
...rtl,
render: customRender,
}
```

</details>

## Using without Jest

If you're running your tests in the browser bundled with webpack (or similar)
Expand Down