Skip to content

Commit

Permalink
docs: setup automatic table of contents (#1482)
Browse files Browse the repository at this point in the history
* docs: automate table of contents for all pages
* docs: custom anchors
* docs: tweaks
  • Loading branch information
mdjastrzebski committed Aug 31, 2023
1 parent 5cbe69a commit 3ff0afb
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 229 deletions.
175 changes: 55 additions & 120 deletions website/docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,11 @@
id: api
title: API
---
import TOCInline from '@theme/TOCInline';

### Table of contents:

- [`render`](#render)
- [`render` options](#render-options)
- [`...queries`](#queries)
- [`update`](#update)
- [`unmount`](#unmount)
- [`debug`](#debug)
- [`toJSON`](#tojson)
- [`root`](#root)
- [`UNSAFE_root`](#unsaferoot)
- [`screen`](#screen)
- [`cleanup`](#cleanup)
- [`fireEvent`](#fireevent)
- [`fireEvent[eventName]`](#fireeventeventname)
- [`fireEvent.press`](#fireeventpress)
- [`fireEvent.changeText`](#fireeventchangetext)
- [`fireEvent.scroll`](#fireeventscroll)
- [`waitFor`](#waitfor)
- [Using a React Native version \< 0.71 with Jest fake timers](#using-a-react-native-version--071-with-jest-fake-timers)
- [`waitForElementToBeRemoved`](#waitforelementtoberemoved)
- [`within`, `getQueriesForElement`](#within-getqueriesforelement)
- [`queryBy*` APIs](#queryby-apis)
- [`queryAll*` APIs](#queryall-apis)
- [`act`](#act)
- [`renderHook`](#renderhook)
- [`callback`](#callback)
- [`options` (Optional)](#options-optional)
- [`RenderHookResult` object](#renderhookresult-object)
- [Examples](#examples)
- [Configuration](#configuration)
- [`configure`](#configure)
- [`resetToDefaults()`](#resettodefaults)
- [Environment variables](#environment-variables)
- [Accessibility](#accessibility)
- [`isHiddenFromAccessibility`](#ishiddenfromaccessibility)

This page gathers public API of React Native Testing Library along with usage examples.

## `render`
<TOCInline toc={toc} />

## `render` API

- [`Example code`](https://github.com/callstack/react-native-testing-library/blob/main/src/__tests__/render.test.tsx)

Expand Down Expand Up @@ -79,7 +43,7 @@ Latest `render` result is kept in [`screen`](#screen) variable that can be impor
Using `screen` instead of destructuring `render` result is recommended approach. See [this article](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen) from Kent C. Dodds for more details.
:::

### `render` options
### Options {#render-options}

The behavior of `render` method can be customized by passing various options as a second argument of `RenderOptions` type:

Expand Down Expand Up @@ -257,7 +221,7 @@ This API typically will return a composite view which goes against recommended t
This API has been previously named `container` for compatibility with [React Testing Library](https://testing-library.com/docs/react-testing-library/api#container-1). However, despite the same name, the actual behavior has been signficantly different, hence the name change to `UNSAFE_root`.
:::

## `screen`
## `screen` API

```ts
let screen: RenderResult;
Expand All @@ -274,48 +238,7 @@ This can also be used to build test utils that would normally require to be in r
const debugText = () => screen.debug({ mapProps: (props) => ({}) });
```

## `cleanup`

```ts
const cleanup: () => void;
```

Unmounts React trees that were mounted with `render` and clears `screen` variable that holds latest `render` output.

:::info
Please note that this is done automatically if the testing framework you're using supports the `afterEach` global (like mocha, Jest, and Jasmine). If not, you will need to do manual cleanups after each test.
:::

For example, if you're using the `jest` testing framework, then you would need to use the `afterEach` hook like so:

```jsx
import { cleanup, render } from '@testing-library/react-native/pure';
import { View } from 'react-native';

afterEach(cleanup);

it('renders a view', () => {
render(<View />);
// ...
});
```

The `afterEach(cleanup)` call also works in `describe` blocks:

```jsx
describe('when logged in', () => {
afterEach(cleanup);

it('renders the user', () => {
render(<SiteHeader />);
// ...
});
});
```

Failing to call `cleanup` when you've called `render` could result in a memory leak and tests which are not "idempotent" (which can lead to difficult to debug errors in your tests).

## `fireEvent`
## `fireEvent` API

```ts
function fireEvent(
Expand Down Expand Up @@ -374,13 +297,7 @@ render(
fireEvent(screen.getByPlaceholderText('my placeholder'), 'blur');
```

## `fireEvent[eventName]`

```ts
fireEvent[eventName](element: ReactTestInstance, ...data: Array<any>): void
```

Convenience methods for common events like: `press`, `changeText`, `scroll`.
FireEvent exposes convenience methods for common events like: `press`, `changeText`, `scroll`.

### `fireEvent.press`

Expand Down Expand Up @@ -520,7 +437,9 @@ expect(onEndReached).toHaveBeenCalled();
If you're noticing that components are not being found on a list, even after mocking a scroll event, try changing the [`initialNumToRender`](https://reactnative.dev/docs/flatlist#initialnumtorender) that you have set. If you aren't comfortable changing the code to accept this prop from the unit test, try using an e2e test that might better suit what use case you're attempting to replicate.
:::

## `waitFor`
## Helper functions

### `waitFor`

- [`Example code`](https://github.com/callstack/react-native-testing-library/blob/main/src/__tests__/waitFor.test.tsx)

Expand Down Expand Up @@ -573,7 +492,7 @@ Avoiding side effects in `expectation` callback can be partially enforced with t

It is also recommended to have a [single assertion per each `waitFor`](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#having-multiple-assertions-in-a-single-waitfor-callback) for more consistency and faster failing tests. If you want to make several assertions, then they should be in seperate `waitFor` calls. In many cases you won't actually need to wrap the second assertion in `waitFor` since the first one will do the waiting required for asynchronous change to happen.

### Using a React Native version < 0.71 with Jest fake timers
#### Using a React Native version < 0.71 with Jest fake timers

:::caution
When using a version of React Native < 0.71 and modern fake timers (the default for `Jest` >= 27), `waitFor` won't work (it will always timeout even if `expectation()` doesn't throw) unless you use the custom [@testing-library/react-native preset](https://github.com/callstack/react-native-testing-library#custom-jest-preset).
Expand Down Expand Up @@ -624,7 +543,7 @@ In order to properly use `waitFor` you need at least React >=16.9.0 (featuring a
If you receive warnings related to `act()` function consult our [Undestanding Act](./UnderstandingAct.md) function document.
:::

## `waitForElementToBeRemoved`
### `waitForElementToBeRemoved`

- [`Example code`](https://github.com/callstack/react-native-testing-library/blob/main/src/__tests__/waitForElementToBeRemoved.test.tsx)

Expand Down Expand Up @@ -665,7 +584,7 @@ In order to properly use `waitForElementToBeRemoved` you need at least React >=1
If you receive warnings related to `act()` function consult our [Undestanding Act](./UnderstandingAct.md) function document.
:::

## `within`, `getQueriesForElement`
### `within`, `getQueriesForElement`

- [`Example code`](https://github.com/callstack/react-native-testing-library/blob/main/src/__tests__/within.test.tsx)

Expand Down Expand Up @@ -696,37 +615,55 @@ Use cases for scoped queries include:
- queries scoped to a single item inside a FlatList containing many items
- queries scoped to a single screen in tests involving screen transitions (e.g. with react-navigation)

## `queryBy*` APIs

Each of the `getBy*` APIs listed in the render section above have a complimentary `queryBy*` API. The `getBy*` APIs will throw errors if a proper node cannot be found. This is normally the desired effect. However, if you want to make an assertion that an element is not present in the hierarchy, then you can use the `queryBy*` API instead:
### `act`

```jsx
import { render, screen } from '@testing-library/react-native';
Useful function to help testing components that use hooks API. By default any `render`, `update`, `fireEvent`, and `waitFor` calls are wrapped by this function, so there is no need to wrap it manually. This method is re-exported from [`react-test-renderer`](https://github.com/facebook/react/blob/main/packages/react-test-renderer/src/ReactTestRenderer.js#L567]).

render(<Form />);
const submitButton = screen.queryByText('submit');
expect(submitButton).not.toBeOnTheScreen(); // it doesn't exist
Consult our [Undestanding Act function](./UnderstandingAct.md) document for more understanding of its intricacies.

### `cleanup`

```ts
const cleanup: () => void;
```

## `queryAll*` APIs
Unmounts React trees that were mounted with `render` and clears `screen` variable that holds latest `render` output.

:::info
Please note that this is done automatically if the testing framework you're using supports the `afterEach` global (like mocha, Jest, and Jasmine). If not, you will need to do manual cleanups after each test.
:::

Each of the query APIs have a corresponding `queryAll*` version that always returns an array of matching nodes. `getAll*` is the same but throws when the array has a length of 0.
For example, if you're using the `jest` testing framework, then you would need to use the `afterEach` hook like so:

```jsx
import { render } from '@testing-library/react-native';
import { cleanup, render } from '@testing-library/react-native/pure';
import { View } from 'react-native';

afterEach(cleanup);

render(<Forms />);
const submitButtons = screen.queryAllByText('submit');
expect(submitButtons).toHaveLength(3); // expect 3 elements
it('renders a view', () => {
render(<View />);
// ...
});
```

## `act`
The `afterEach(cleanup)` call also works in `describe` blocks:

Useful function to help testing components that use hooks API. By default any `render`, `update`, `fireEvent`, and `waitFor` calls are wrapped by this function, so there is no need to wrap it manually. This method is re-exported from [`react-test-renderer`](https://github.com/facebook/react/blob/main/packages/react-test-renderer/src/ReactTestRenderer.js#L567]).
```jsx
describe('when logged in', () => {
afterEach(cleanup);

Consult our [Undestanding Act function](./UnderstandingAct.md) document for more understanding of its intricacies.
it('renders the user', () => {
render(<SiteHeader />);
// ...
});
});
```

Failing to call `cleanup` when you've called `render` could result in a memory leak and tests which are not "idempotent" (which can lead to difficult to debug errors in your tests).

## `renderHook`
## `renderHook` API

Defined as:

Expand Down Expand Up @@ -767,13 +704,11 @@ export const useCount = () => {

The `renderHook` function accepts the following arguments:

### `callback`

The function that is called each `render` of the test component. This function should call one or more hooks for testing.
Callback is a function that is called each `render` of the test component. This function should call one or more hooks for testing.

The `props` passed into the callback will be the `initialProps` provided in the `options` to `renderHook`, unless new props are provided by a subsequent `rerender` call.

### `options` (Optional)
### `options`

A `RenderHookOptions<Props>` object to modify the execution of the `callback` function, containing the following properties:

Expand All @@ -785,7 +720,7 @@ The initial values to pass as `props` to the `callback` function of `renderHook`

A React component to wrap the test component in when rendering. This is usually used to add context providers from `React.createContext` for the hook to access with `useContext`.

### `RenderHookResult` object
### `RenderHookResult`

```ts
interface RenderHookResult<Result, Props> {
Expand All @@ -797,15 +732,15 @@ interface RenderHookResult<Result, Props> {

The `renderHook` function returns an object that has the following properties:

#### `result`
### `result`

The `current` value of the `result` will reflect the latest of whatever is returned from the `callback` passed to `renderHook`. The `Result` type is determined by the type passed to or inferred by the `renderHook` call.

#### `rerender`
### `rerender`

A function to rerender the test component, causing any hooks to be recalculated. If `newProps` are passed, they will replace the `callback` function's `initialProps` for subsequent rerenders. The `Props` type is determined by the type passed to or inferred by the `renderHook` call.

#### `unmount`
### `unmount`

A function to unmount the test component. This is commonly used to trigger cleanup effects for `useEffect` hooks.

Expand Down
1 change: 0 additions & 1 deletion website/docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
id: getting-started
title: Getting Started
---

## The problem

You want to write maintainable tests for your React Native components. As a part of this goal, you want your tests to avoid including implementation details of your components and rather focus on making your tests give you the confidence for which they are intended. As part of this, you want your testbase to be maintainable in the long run so refactors of your components (changes to implementation but not functionality) don't break your tests and slow you and your team down.
Expand Down
13 changes: 8 additions & 5 deletions website/docs/MigrationV11.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
id: migration-v11
title: Migration to 11.0
---
import TOCInline from '@theme/TOCInline';

Migration to React Native Testing Library version 11 from version 9.x or 10.x should be a relatively easy task due small amount of breaking changes.

<TOCInline toc={toc} />

# Breaking changes

## Update to Jest 28 if you use fake timers
### Update to Jest 28 if you use fake timers

If you use fake timers in any of your tests you should update your Jest dependencies to version 28. This is due to the fact that [`jest.useFakeTimers()` config structure](https://jestjs.io/docs/jest-object#jestusefaketimersfaketimersconfig) has changed.

## Refactor legacy `waitForOptions` position
### Refactor legacy `waitForOptions` position

In version 9 we introducted query `options` parameters for each query type. This affected all `findBy` and `findAllBy` queries because their signatures changed e.g. from:

Expand Down Expand Up @@ -41,13 +44,13 @@ should become
findByText(/Text/, {}, { timeout: 1000 })
```

## Triggering non-touch events on targets with `pointerEvents="box-none"` prop
### Triggering non-touch events on targets with `pointerEvents="box-none"` prop

Up to version 10, RNTL disables all events for a target with `pointerEvents="box-none"`. This behavior is counter to how React Native itself functions.

From version 11, RNTL continues to disable `press` event for these targets but allows triggering other events, e.g. `layout`.

# All changes
## All changes

* chore(breaking): update Jest to 28 by @mdjastrzebski in https://github.com/callstack/react-native-testing-library/pull/1008
* refactor(breaking): remove legacy wait for options support by @mdjastrzebski in https://github.com/callstack/react-native-testing-library/pull/1018
Expand All @@ -59,6 +62,6 @@ From version 11, RNTL continues to disable `press` event for these targets but a
* chore: Organise a11y queries by predicate by @MattAgn in https://github.com/callstack/react-native-testing-library/pull/977
* chore: reenable skipped byText tests by @mdjastrzebski in https://github.com/callstack/react-native-testing-library/pull/1017

# Full Changelog
## Full Changelog
https://github.com/callstack/react-native-testing-library/compare/v10.1.1...v11.0.0

Loading

0 comments on commit 3ff0afb

Please sign in to comment.