humanize v13 docs

This commit is contained in:
Maciej Jastrzebski
2026-01-20 22:56:30 +01:00
parent b4bca76939
commit ab2b2c5963
19 changed files with 121 additions and 122 deletions
@@ -2,13 +2,12 @@
## Introduction
Mocking network requests is an essential part of testing React Native applications. By mocking
network
requests, you can control the data that is returned from the server and test how your application
behaves in different scenarios, such as when the request is successful or when it fails.
Mocking network requests is essential for testing React Native applications. By mocking
network requests, you can control the data returned from the server and test how your application
behaves in different scenarios, such as when the request succeeds or fails.
In this guide, we will show you how to mock network requests and guard your test suits from unwanted
and unmocked/unhandled network requests
This guide shows how to mock network requests and guard your test suites against unwanted
and unmocked/unhandled network requests.
:::info
To simulate a real-world scenario, we will use the [Random User Generator API](https://randomuser.me/) that provides random user data.
@@ -363,14 +362,14 @@ Which will result in a warning in the console if you forget to mock an API reque
## Conclusion
Testing a component that makes network requests in combination with MSW takes some initial preparation to configure and describe the overridden networks.
We can achieve that by using MSW's request handlers and intercepting APIs.
Testing components that make network requests with MSW requires initial setup to configure and describe the overridden networks.
Use MSW's request handlers and intercepting APIs to achieve this.
Once up and running we gain full grip over the network requests, their responses, statuses.
Doing so is crucial to be able to test how our application behaves in different
scenarios, such as when the request is successful or when it fails.
Once configured, you have full control over network requests, their responses, and statuses.
This lets you test how your application behaves in different
scenarios, such as when requests succeed or fail.
When global configuration is in place, MSW's will also warn us when an unhandled network requests has occurred throughout a test suite.
With global configuration in place, MSW will also warn you when an unhandled network request occurs during a test suite.
## Further Reading and Alternatives
@@ -6,7 +6,7 @@ This document is intended for a more advanced audience who want to understand th
:::
React Native Testing Library allows you to write integration and component tests for your React Native app or library. While the JSX code used in tests closely resembles your React Native app, things are not as simple as they might appear. This document will describe the key elements of our testing environment and highlight things to be aware of when writing more advanced tests or diagnosing issues.
React Native Testing Library allows you to write integration and component tests for your React Native app or library. While the JSX code used in tests closely resembles your React Native app, things aren't as simple as they might appear. This document describes the key elements of our testing environment and highlights things to be aware of when writing more advanced tests or diagnosing issues.
## React renderers
@@ -37,7 +37,7 @@ Disadvantages:
- Assertions do not operate on native view hierarchy
- Runtime behaviors are simulated, sometimes imperfectly
It's worth noting that the React Testing Library (web one) works a bit differently. While RTL also runs in Jest, it has access to a simulated browser DOM environment from the `jsdom` package, which allows it to use a regular React DOM renderer. Unfortunately, there is no similar React Native runtime environment package. This is probably because while the browser environment is well-defined and highly standardized, the React Native environment constantly evolves in sync with the evolution of underlying OS-es. Maintaining such an environment would require duplicating countless React Native behaviors and keeping them in sync as React Native develops.
The React Testing Library (web one) works differently. While RTL also runs in Jest, it has access to a simulated browser DOM environment from the `jsdom` package, which allows it to use a regular React DOM renderer. Unfortunately, there's no similar React Native runtime environment package. This is probably because while the browser environment is well-defined and highly standardized, the React Native environment constantly evolves in sync with the evolution of underlying OS-es. Maintaining such an environment would require duplicating countless React Native behaviors and keeping them in sync as React Native develops.
## Element tree
@@ -111,7 +111,7 @@ function isHostElement(element: ReactTestInstance) {
## Tree nodes
We encourage you to only assert values on host views in your tests because they represent the user interface view and controls which the user can see and interact with. Users cannot see or interact with composite views as they exist purely in the JavaScript domain and do not generate any visible UI.
We encourage you to only assert values on host views in your tests because they represent the user interface view and controls that users can see and interact with. Users can't see or interact with composite views as they exist purely in the JavaScript domain and don't generate any visible UI.
### Asserting props
@@ -1,6 +1,6 @@
# Third-Party Library Integration
The React Native Testing Library is designed to simulate the core behaviors of React Native. However, it does not replicate the internal logic of third-party libraries. This guide explains how to integrate your library with RNTL.
The React Native Testing Library is designed to simulate the core behaviors of React Native. However, it doesn't replicate the internal logic of third-party libraries. This guide explains how to integrate your library with RNTL.
## Handling Events in Third-Party Libraries
@@ -1,6 +1,6 @@
# Understanding `act` function
When writing RNTL tests one of the things that confuses developers the most are cryptic [`act()`](https://reactjs.org/docs/testing-recipes.html#act) function errors logged into console. In this article I will try to build an understanding of the purpose and behaviour of `act()` so you can build your tests with more confidence.
When writing RNTL tests, one of the things that confuses developers the most are cryptic [`act()`](https://reactjs.org/docs/testing-recipes.html#act) function errors logged to the console. This article explains the purpose and behavior of `act()` so you can write tests with more confidence.
## `act` warnings
@@ -33,7 +33,7 @@ This function is intended only for using in automated tests and works only in de
The responsibility for `act` function is to make React renders and updates work in tests in a similar way they work in real application by grouping and executing related units of interaction (e.g. renders, effects, etc) together.
To showcase that behaviour let make a small experiment. First we define a function component that uses `useEffect` hook in a trivial way.
To show that behavior, let's make a small experiment. First we define a function component that uses `useEffect` hook in a trivial way.
```jsx
function TestComponent() {
@@ -58,7 +58,7 @@ test('render without act', () => {
});
```
When testing without `act` call wrapping rendering call, we see that the assertion runs just after the rendering but before `useEffect`hooks effects are applied. Which is not what we expected in our tests.
When testing without wrapping the rendering call in `act`, the assertion runs just after rendering but before `useEffect` hooks effects are applied. This is not what we expected in our tests.
```jsx
test('render with act', () => {
@@ -73,13 +73,13 @@ test('render with act', () => {
});
```
When wrapping rendering call with `act` we see that the changes caused by `useEffect` hook have been applied as we would expect.
When wrapping the rendering call with `act`, the changes caused by the `useEffect` hook are applied as expected.
### When to use act
The name `act` comes from [Arrange-Act-Assert](http://wiki.c2.com/?ArrangeActAssert) unit testing pattern. Which means it’s related to part of the test when we execute some actions on the component tree.
So far we learned that `act` function allows tests to wait for all pending React interactions to be applied before we make our assertions. When using `act` we get guarantee that any state updates will be executed as well as any enqueued effects will be executed.
The `act` function allows tests to wait for all pending React interactions to be applied before making assertions. When using `act`, we get a guarantee that any state updates will be executed and any enqueued effects will be executed.
Therefore, we should use `act` whenever there is some action that causes element tree to render, particularly:
@@ -87,7 +87,7 @@ Therefore, we should use `act` whenever there is some action that causes element
- re-rendering of component -`renderer.update` call
- triggering any event handlers that cause component tree render
Thankfully, for these basic cases RNTL has got you covered as our `render`, `update` and `fireEvent` methods already wrap their calls in sync `act` so that you do not have to do it explicitly.
For these basic cases, RNTL handles it for you. Our `render`, `update`, and `fireEvent` methods already wrap their calls in sync `act` so you don't have to do it explicitly.
Note that `act` calls can be safely nested and internally form a stack of calls. However, overlapping `act` calls, which can be achieved using async version of `act`, [are not supported](https://github.com/facebook/react/blob/main/packages/react/src/ReactAct.js#L161).
@@ -103,9 +103,9 @@ So far we have seen synchronous version of `act` which runs its callback immedia
### Asynchronous code
Asynchronous version of `act` also is executed immediately, but the callback is not yet completed because of some asynchronous operations inside.
The asynchronous version of `act` is also executed immediately, but the callback doesn't complete right away because of asynchronous operations inside.
Lets look at a simple example with component using `setTimeout` call to simulate asynchronous behaviour:
Let's look at a simple example with a component using `setTimeout` to simulate asynchronous behavior:
```jsx
function TestAsyncComponent() {
@@ -129,7 +129,7 @@ test('render async natively', () => {
});
```
If we test our component in a native way without handling its asynchronous behaviour we will end up with sync act warning:
If we test our component without handling its asynchronous behavior, we'll get a sync act warning:
```
Warning: An update to TestAsyncComponent inside a test was not wrapped in act(...).
@@ -142,7 +142,7 @@ act(() => {
/* assert on the output */
```
Note that this is not yet the infamous async act warning. It only asks us to wrap our event code with `act` calls. However, this time our immediate state change does not originate from externally triggered events but rather forms an internal part of the component. So how can we apply `act` in such scenario?
This is not yet the async act warning. It only asks us to wrap our event code with `act` calls. However, this time the state change doesn't come from externally triggered events but from an internal part of the component. So how can we apply `act` in this scenario?
### Solution with fake timers
@@ -160,7 +160,7 @@ test('render with fake timers', () => {
});
```
That way we can wrap `jest.runAllTimers()` call which triggers the `setTimeout` updates inside an `act` call, hence resolving the act warning. Note that this whole code is synchronous thanks to usage of Jest fake timers.
This way we can wrap the `jest.runAllTimers()` call, which triggers the `setTimeout` updates, inside an `act` call, resolving the act warning. Note that this whole code is synchronous thanks to Jest fake timers.
### Solution with real timers
@@ -177,7 +177,7 @@ test('render with real timers - sleep', async () => {
});
```
This works correctly as we use an explicit async `act()` call that resolves the console error. However, it relies on our knowledge of exact implementation details which is a bad practice.
This works correctly because we use an explicit async `act()` call that resolves the console error. However, it relies on knowing exact implementation details, which is a bad practice.
Let’s try more elegant solution using `waitFor` that will wait for our desired state:
@@ -190,7 +190,7 @@ test('render with real timers - waitFor', async () => {
});
```
This also works correctly, because `waitFor` call executes async `act()` call internally.
This also works correctly because `waitFor` executes async `act()` internally.
The above code can be simplified using `findBy` query:
@@ -202,13 +202,13 @@ test('render with real timers - findBy', async () => {
});
```
This also works since `findByText` internally calls `waitFor` which uses async `act()`.
This also works because `findByText` internally calls `waitFor`, which uses async `act()`.
Note that all of the above examples are async tests using & awaiting async `act()` function call.
### Async act warning
If we modify any of the above async tests and remove `await` keyword, then we will trigger the notorious async `act()`warning:
If we modify any of the above async tests and remove the `await` keyword, we'll trigger the async `act()` warning:
```jsx
Warning: You called act(async () => ...) without await. This could lead to unexpected
@@ -218,7 +218,7 @@ testing behaviour, interleaving multiple act calls and mixing their scopes. You
React decides to show this error whenever it detects that async `act()`call [has not been awaited](https://github.com/facebook/react/blob/ce13860281f833de8a3296b7a3dad9caced102e9/packages/react/src/ReactAct.js#L93).
The exact reasons why you might see async `act()` warnings vary, but finally it means that `act()` has been called with callback that returns `Promise`-like object, but it has not been waited on.
The exact reasons why you might see async `act()` warnings vary, but it means that `act()` has been called with a callback that returns a `Promise`-like object, but it hasn't been awaited.
## References
@@ -2,11 +2,11 @@
## Comparison with Fire Event API
Fire Event is our original event simulation API. It can invoke **any event handler** declared on **either host or composite elements**. Suppose the element does not have `onEventName` event handler for the passed `eventName` event, or the element is disabled. In that case, Fire Event will traverse up the component tree, looking for an event handler on both host and composite elements along the way. By default, it will **not pass any event data**, but the user might provide it in the last argument.
Fire Event is our original event simulation API. It can invoke **any event handler** declared on **either host or composite elements**. If the element doesn't have an `onEventName` event handler for the passed `eventName` event, or the element is disabled, Fire Event will traverse up the component tree, looking for an event handler on both host and composite elements along the way. By default, it will **not pass any event data**, but you can provide it in the last argument.
In contrast, User Event provides realistic event simulation for user interactions like `press` or `type`. Each interaction will trigger a **sequence of events** corresponding to React Native runtime behavior. These events will be invoked **only on host elements**, and **will automatically receive event data** corresponding to each event.
In contrast, User Event provides realistic event simulation for user interactions like `press` or `type`. Each interaction triggers a **sequence of events** corresponding to React Native runtime behavior. These events are invoked **only on host elements**, and **automatically receive event data** corresponding to each event.
If User Event supports a given interaction, you should always prefer it over the Fire Event counterpart, as it will make your tests much more realistic and, hence, reliable. In other cases, e.g., when User Event does not support the given event or when invoking event handlers on composite elements, you have to use Fire Event as the only available option.
If User Event supports a given interaction, prefer it over the Fire Event counterpart, as it makes your tests more realistic and reliable. In other cases, e.g., when User Event doesn't support the given event or when invoking event handlers on composite elements, use Fire Event as the only available option.
## `setup()`
@@ -45,7 +45,7 @@ const user = userEvent.setup();
await user.press(element);
```
This helper simulates a press on any pressable element, e.g. `Pressable`, `TouchableOpacity`, `Text`, `TextInput`, etc. Unlike `fireEvent.press()`, a more straightforward API that will only call the `onPress` prop, this function simulates the entire press interaction in a more realistic way by reproducing the event sequence emitted by React Native runtime. This helper will trigger additional events like `pressIn` and `pressOut`.
This helper simulates a press on any pressable element, e.g. `Pressable`, `TouchableOpacity`, `Text`, `TextInput`, etc. Unlike `fireEvent.press()`, which only calls the `onPress` prop, this function simulates the entire press interaction by reproducing the event sequence emitted by React Native runtime. This helper triggers additional events like `pressIn` and `pressOut`.
This event will take a minimum of 130 ms to run due to the internal React Native logic. Consider using fake timers to speed up test execution for tests involving `press` and `longPress` interactions.
@@ -65,7 +65,7 @@ const user = userEvent.setup();
await user.longPress(element);
```
Simulates a long press user interaction. In React Native, the `longPress` event is emitted when the press duration exceeds the long press threshold (by default, 500 ms). In other aspects, this action behaves similarly to regular `press` action, e.g., by emitting `pressIn` and `pressOut` events. The press duration is customizable through the options. This should be useful if you use the `delayLongPress` prop.
Simulates a long press user interaction. In React Native, the `longPress` event is emitted when the press duration exceeds the long press threshold (by default, 500 ms). In other aspects, this action behaves like regular `press` action, e.g., by emitting `pressIn` and `pressOut` events. The press duration is customizable through the options. This is useful if you use the `delayLongPress` prop.
This event will, by default, take 500 ms to run. Due to internal React Native logic, it will take at least 130 ms regardless of the duration option passed. Consider using fake timers to speed up test execution for tests involving `press` and `longPress` interactions.
@@ -95,7 +95,7 @@ await user.type(textInput, 'Hello world!');
This helper simulates the user focusing on a `TextInput` element, typing `text` one character at a time, and leaving the element.
This function supports only host `TextInput` elements. Passing other element types will result in throwing an error.
This function supports only host `TextInput` elements. Passing other element types will throw an error.
:::note
This function will add text to the text already present in the text input (as specified by `value` or `defaultValue` props). To replace existing text, use [`clear()`](#clear) helper first.
@@ -155,7 +155,7 @@ await user.clear(textInput);
This helper simulates the user clearing the content of a `TextInput` element.
This function supports only host `TextInput` elements. Passing other element types will result in throwing an error.
This function supports only host `TextInput` elements. Passing other element types will throw an error.
### Sequence of events {#clear-sequence}
@@ -199,7 +199,7 @@ await user.paste(textInput, 'Text to paste');
This helper simulates the user pasting given text to a `TextInput` element.
This function supports only host `TextInput` elements. Passing other element types will result in throwing an error.
This function supports only host `TextInput` elements. Passing other element types will throw an error.
### Sequence of events {#paste-sequence}
@@ -251,7 +251,7 @@ await user.scrollTo(scrollView, { y: 100, momentumY: 200 });
This helper simulates the user scrolling a host `ScrollView` element.
This function supports only host `ScrollView` elements, passing other element types will result in an error. Note that `FlatList` is accepted as it renders to a host `ScrollView` element.
This function supports only host `ScrollView` elements. Passing other element types will throw an error. Note that `FlatList` is accepted as it renders to a host `ScrollView` element.
Scroll interaction should match the `ScrollView` element direction:
+3 -3
View File
@@ -1,6 +1,6 @@
# Jest matchers
This guide describes built-in Jest matchers, we recommend using these matchers as they provide readable tests, accessibility support, and a better developer experience.
This guide describes built-in Jest matchers. We recommend using these matchers as they provide readable tests, accessibility support, and a better developer experience.
## Setup
@@ -133,7 +133,7 @@ expect(element).toBeExpanded();
expect(element).toBeCollapsed();
```
These allows you to assert whether the given element is expanded or collapsed from the user's perspective. It relies on the accessibility disabled state as set by `aria-expanded` or `accessibilityState.expanded` props.
These allow you to assert whether the given element is expanded or collapsed from the user's perspective. They rely on the accessibility expanded state as set by `aria-expanded` or `accessibilityState.expanded` props.
:::note
These matchers are the negation of each other for expandable elements (elements with explicit `aria-expanded` or `accessibilityState.expanded` props). However, both won't pass for non-expandable elements (ones without explicit `aria-expanded` or `accessibilityState.expanded` props).
@@ -145,7 +145,7 @@ These matchers are the negation of each other for expandable elements (elements
expect(element).toBeBusy();
```
This allows you to assert whether the given element is busy from the user's perspective. It relies on the accessibility selected state as set by `aria-busy` or `accessibilityState.busy` props.
This allows you to assert whether the given element is busy from the user's perspective. It relies on the accessibility busy state as set by `aria-busy` or `accessibilityState.busy` props.
## Checking element style
@@ -11,9 +11,9 @@ Also available as `isInaccessible()` alias for React Testing Library compatibili
Checks if given element is hidden from assistive technology, e.g. screen readers.
:::note
Like [`isInaccessible`](https://testing-library.com/docs/dom-testing-library/api-accessibility/#isinaccessible) function from DOM Testing Library this function considers both accessibility elements and presentational elements (regular `View`s) to be accessible, unless they are hidden in terms of host platform.
Like the [`isInaccessible`](https://testing-library.com/docs/dom-testing-library/api-accessibility/#isinaccessible) function from DOM Testing Library, this function considers both accessibility elements and presentational elements (regular `View`s) to be accessible, unless they're hidden in terms of the host platform.
This covers only part of [ARIA notion of Accessiblity Tree](https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion), as ARIA excludes both hidden and presentational elements from the Accessibility Tree.
This covers only part of the [ARIA notion of Accessibility Tree](https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion), as ARIA excludes both hidden and presentational elements from the Accessibility Tree.
:::
For the scope of this function, element is inaccessible when it, or any of its ancestors, meets any of the following conditions:
+10 -10
View File
@@ -13,20 +13,20 @@ function waitFor<T>(
): Promise<T>;
```
Waits for a period of time for the `expectation` callback to pass. `waitFor` may run the callback a number of times until timeout is reached, as specified by the `timeout` and `interval` options. The callback must throw an error when the expectation is not met. Returning any value, including a falsy one, will be treated as meeting the expectation, and the callback result will be returned to the caller of `waitFor` function.
Waits for the `expectation` callback to pass. `waitFor` may run the callback multiple times until the timeout is reached, as specified by the `timeout` and `interval` options. The callback must throw an error when the expectation isn't met. Returning any value, including a falsy one, is treated as meeting the expectation, and the callback result is returned to the caller of `waitFor`.
```tsx
await waitFor(() => expect(mockFunction).toHaveBeenCalledWith());
```
`waitFor` function will be executing `expectation` callback every `interval` (default: every 50 ms) until `timeout` (default: 1000 ms) is reached. The repeated execution of callback is stopped as soon as it does not throw an error, in such case the value returned by the callback is returned to `waitFor` caller. Otherwise, when it reaches the timeout, the final error thrown by `expectation` will be re-thrown by `waitFor` to the calling code.
`waitFor` executes the `expectation` callback every `interval` (default: every 50 ms) until `timeout` (default: 1000 ms) is reached. The repeated execution stops as soon as it doesn't throw an error, and the value returned by the callback is returned to the `waitFor` caller. Otherwise, when it reaches the timeout, the final error thrown by `expectation` is re-thrown by `waitFor` to the calling code.
```tsx
// ❌ `waitFor` will return immediately because callback does not throw
await waitFor(() => false);
```
`waitFor` is an async function so you need to `await` the result to pause test execution.
`waitFor` is an async function, so you need to `await` the result to pause test execution.
```jsx
// ❌ missing `await`: `waitFor` will just return Promise that will be rejected when the timeout is reached
@@ -37,7 +37,7 @@ waitFor(() => expect(1).toBe(2));
You can enforce awaiting `waitFor` by using the [await-async-utils](https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/await-async-utils.md) rule from [eslint-plugin-testing-library](https://github.com/testing-library/eslint-plugin-testing-library).
:::
Since `waitFor` is likely to run `expectation` callback multiple times, it is highly recommended for it [not to perform any side effects](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#performing-side-effects-in-waitfor) in `waitFor`.
Since `waitFor` is likely to run the `expectation` callback multiple times, it's highly recommended [not to perform any side effects](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#performing-side-effects-in-waitfor) in `waitFor`.
```jsx
await waitFor(() => {
@@ -51,9 +51,9 @@ await waitFor(() => {
Avoiding side effects in `expectation` callback can be partially enforced with the [`no-wait-for-side-effects` rule](https://github.com/testing-library/eslint-plugin-testing-library/blob/main/docs/rules/no-wait-for-side-effects.md).
:::
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.
It's 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, put them in separate `waitFor` calls. In many cases you won't need to wrap the second assertion in `waitFor` since the first one will do the waiting required for the asynchronous change to happen.
`waitFor` checks whether Jest fake timers are enabled and adapts its behavior in such case. The following snippet is a simplified version of how it behaves when fake timers are enabled:
`waitFor` checks whether Jest fake timers are enabled and adapts its behavior accordingly. The following snippet is a simplified version of how it behaves when fake timers are enabled:
```tsx
let fakeTimeRemaining = timeout;
@@ -74,7 +74,7 @@ while (fakeTimeRemaining > 0) {
throw lastError;
```
In the following example we test that a function is called after 10 seconds using fake timers. Since we're using fake timers, the test won't depend on real time passing and thus be much faster and more reliable. Also we don't have to advance fake timers through Jest fake timers API because `waitFor` already does this for us.
In the following example we test that a function is called after 10 seconds using fake timers. Since we're using fake timers, the test won't depend on real time passing and will be much faster and more reliable. We don't have to advance fake timers through Jest fake timers API because `waitFor` already does this for us.
```tsx
// in component
@@ -103,7 +103,7 @@ function waitForElementToBeRemoved<T>(
): Promise<T>;
```
Waits for non-deterministic periods of time until queried element is removed or times out. `waitForElementToBeRemoved` periodically calls `expectation` every `interval` milliseconds to determine whether the element has been removed or not.
Waits until the queried element is removed or times out. `waitForElementToBeRemoved` periodically calls `expectation` every `interval` milliseconds to determine whether the element has been removed or not.
```jsx
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react-native';
@@ -115,9 +115,9 @@ test('waiting for an Banana to be removed', async () => {
});
```
This method expects that the element is initially present in the render tree and then is removed from it. If the element is not present when you call this method it throws an error.
This method expects the element to be initially present in the render tree and then removed from it. If the element isn't present when you call this method, it throws an error.
You can use any of `getBy`, `getAllBy`, `queryBy` and `queryAllBy` queries for `expectation` parameter.
You can use any of `getBy`, `getAllBy`, `queryBy`, and `queryAllBy` queries for the `expectation` parameter.
:::note
If you receive warnings related to `act()` function consult our [Understanding Act](/docs/advanced/understanding-act.md) function document.
+4 -4
View File
@@ -19,18 +19,18 @@ Default timeout, in ms, for async helper functions (`waitFor`, `waitForElementTo
### `defaultIncludeHiddenElements` option
Default value for [includeHiddenElements](/docs/api/queries#includehiddenelements-option) query option for all queries. The default value is set to `false`, so all queries will not match [elements hidden from accessibility](#ishiddenfromaccessibility). This is because the users of the app would not be able to see such elements.
Default value for [includeHiddenElements](/docs/api/queries#includehiddenelements-option) query option for all queries. The default value is `false`, so all queries won't match [elements hidden from accessibility](#ishiddenfromaccessibility). This is because users of the app wouldn't be able to see such elements.
This option is also available as `defaultHidden` alias for compatibility with [React Testing Library](https://testing-library.com/docs/dom-testing-library/api-configuration/#defaulthidden).
### `defaultDebugOptions` option
Default [debug options](#debug) to be used when calling `debug()`. These default options will be overridden by the ones you specify directly when calling `debug()`.
Default [debug options](#debug) used when calling `debug()`. These default options are overridden by the ones you specify directly when calling `debug()`.
### `concurrentRoot` option {#concurrent-root}
Set to `false` to disable concurrent rendering.
Otherwise, `render` will default to using concurrent rendering used in the React Native New Architecture.
Otherwise, `render` defaults to using concurrent rendering used in the React Native New Architecture.
## `resetToDefaults()`
@@ -42,7 +42,7 @@ function resetToDefaults() {}
### `RNTL_SKIP_AUTO_CLEANUP`
Set to `true` to disable automatic `cleanup()` after each test. It works the same as importing `react-native-testing-library/dont-cleanup-after-each` or using `react-native-testing-library/pure`.
Set to `true` to disable automatic `cleanup()` after each test. This works the same as importing `react-native-testing-library/dont-cleanup-after-each` or using `react-native-testing-library/pure`.
```shell
$ RNTL_SKIP_AUTO_CLEANUP=true jest
+6 -6
View File
@@ -29,7 +29,7 @@ Use cases for scoped queries include:
## `act`
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]).
Useful function for testing components that use hooks API. By default, any `render`, `update`, `fireEvent`, and `waitFor` calls are wrapped by this function, so you don't 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]).
Consult our [Understanding Act function](/docs/advanced/understanding-act.md) document for more understanding of its intricacies.
@@ -39,13 +39,13 @@ Consult our [Understanding Act function](/docs/advanced/understanding-act.md) do
const cleanup: () => void;
```
Unmounts React trees that were mounted with `render` and clears `screen` variable that holds latest `render` output.
Unmounts React trees that were mounted with `render` and clears the `screen` variable that holds the 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.
This is done automatically if the testing framework you're using supports the `afterEach` global (like mocha, Jest, and Jasmine). If not, you'll 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:
For example, if you're using the `jest` testing framework, you would need to use the `afterEach` hook like so:
```jsx
import { cleanup, render } from '@testing-library/react-native/pure';
@@ -59,7 +59,7 @@ it('renders a view', () => {
});
```
The `afterEach(cleanup)` call also works in `describe` blocks:
The `afterEach(cleanup)` call also works in `describe` blocks.
```jsx
describe('when logged in', () => {
@@ -72,4 +72,4 @@ describe('when logged in', () => {
});
```
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).
Failing to call `cleanup` when you've called `render` could result in a memory leak and tests that aren't "idempotent" (which can lead to difficult-to-debug errors).
@@ -9,7 +9,7 @@ function renderHook<Result, Props>(
): RenderHookResult<Result, Props>;
```
Renders a test component that will call the provided `callback`, including any hooks it calls, every time it renders. Returns [`RenderHookResult`](#renderhookresult) object, which you can interact with.
Renders a test component that calls the provided `callback`, including any hooks it calls, every time it renders. Returns a [`RenderHookResult`](#renderhookresult) object that you can interact with.
```ts
import { renderHook } from '@testing-library/react-native';
@@ -78,7 +78,7 @@ The `current` value of the `result` will reflect the latest of whatever is retur
#### `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.
A function to rerender the test component, causing any hooks to be recalculated. If `newProps` are passed, they 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`
@@ -86,7 +86,7 @@ A function to unmount the test component. This is commonly used to trigger clean
### Examples
Here we present some extra examples of using `renderHook` API.
Here are some additional examples of using the `renderHook` API.
#### With `initialProps`
@@ -157,7 +157,7 @@ interface RenderHookAsyncResult<Result, Props> {
}
```
The `RenderHookAsyncResult` differs from `RenderHookResult` in that `rerenderAsync` and `unmountAsync` are async functions.
The `RenderHookAsyncResult` differs from `RenderHookResult` in that `rerenderAsync` and `unmountAsync` are async functions that return Promises.
```ts
import { renderHookAsync, act } from '@testing-library/react-native';
@@ -179,4 +179,4 @@ test('should handle async hook behavior', async () => {
});
```
Use `renderHookAsync` when testing hooks that use React Suspense, `React.use()`, or other concurrent features where timing of re-renders matters.
Use `renderHookAsync` when testing hooks that use React Suspense, `React.use()`, or other concurrent features where re-render timing matters.
+35 -35
View File
@@ -4,7 +4,7 @@ Queries are one of the main building blocks for the React Native Testing Library
## Accessing queries
All queries described below are accessible in two main ways: through the `screen` object or by capturing the `render` function call result.
All queries described below are accessible in two main ways: through the `screen` object or by capturing the result of the `render` function call.
### Using `screen` object
@@ -18,7 +18,7 @@ test('accessing queries using "screen" object', () => {
})
```
The modern and recommended way of accessing queries is to use the `screen` object exported by the `@testing-library/react-native` package. This object will contain methods of all available queries bound to the most recently rendered UI.
The modern and recommended way to access queries is to use the `screen` object exported by the `@testing-library/react-native` package. This object contains methods for all available queries bound to the most recently rendered UI.
### Using `render` result
@@ -31,7 +31,7 @@ test('accessing queries using "render" result', () => {
})
```
The classic way is to capture query functions, as they are returned from the `render` function call. This provides access to the same functions as in the case of the `screen` object.
The classic way is to capture query functions returned from the `render` function call. This provides access to the same functions as the `screen` object.
## Query parts
@@ -58,7 +58,7 @@ The query variants describe the expected number (and timing) of matching element
| [`findBy*`](/docs/api/queries#find-by) | Exactly one matching element | `Promise<ReactTestInstance>` | Yes |
| [`findAllBy*`](/docs/api/queries#find-all-by) | At least one matching element | `Promise<Array<ReactTestInstance>>` | Yes |
Queries work as implicit assertions on the number of matching elements and will throw an error when the assertion fails.
Queries work as implicit assertions on the number of matching elements and throw an error when the assertion fails.
### `getBy*` queries {#get-by}
@@ -66,7 +66,7 @@ Queries work as implicit assertions on the number of matching elements and will
getByX(...): ReactTestInstance
```
`getBy*` queries return the single matching element for a query, and throw an error if no elements match or if more than one match is found. If you need to find more than one element, then use `getAllBy`.
`getBy*` queries return the single matching element for a query and throw an error if no elements match or if more than one match is found. If you need to find more than one element, use `getAllBy`.
### `getAllBy*` queries {#get-all-by}
@@ -82,7 +82,7 @@ getAllByX(...): ReactTestInstance[]
queryByX(...): ReactTestInstance | null
```
`queryBy*` queries return the first matching node for a query, and return `null` if no elements match. This is useful for asserting an element that is not present. This throws if more than one match is found (use `queryAllBy` instead).
`queryBy*` queries return the first matching node for a query and return `null` if no elements match. This is useful for asserting that an element is not present. This throws if more than one match is found (use `queryAllBy` instead).
### `queryAllBy*` queries {#query-all-by}
@@ -104,7 +104,7 @@ findByX(
): Promise<ReactTestInstance>
```
`findBy*` queries return a promise which resolves when a matching element is found. The promise is rejected if no elements match or if more than one match is found after a default timeout of 1000 ms. If you need to find more than one element use `findAllBy*` queries.
`findBy*` queries return a promise that resolves when a matching element is found. The promise is rejected if no elements match or if more than one match is found after a default timeout of 1000 ms. If you need to find more than one element, use `findAllBy*` queries.
### `findAllBy*` queries {#find-all-by}
@@ -118,14 +118,14 @@ findAllByX(
): Promise<ReactTestInstance[]>
```
`findAllBy*` queries return a promise which resolves to an array of matching elements. The promise is rejected if no elements match after a default timeout of 1000 ms.
`findAllBy*` queries return a promise that resolves to an array of matching elements. The promise is rejected if no elements match after a default timeout of 1000 ms.
:::info
`findBy*` and `findAllBy*` queries accept optional `waitForOptions` object arguments, which can contain `timeout`, `interval` and `onTimeout` properties which have the same meaning as respective options for [`waitFor`](/docs/api/misc/async#waitfor) function.
:::
:::info
In cases when your `findBy*` and `findAllBy*` queries throw when unable to find matching elements, it is helpful to pass `onTimeout: () => { screen.debug(); }` callback using the `waitForOptions` parameter.
When your `findBy*` and `findAllBy*` queries throw because they can't find matching elements, it's helpful to pass `onTimeout: () => { screen.debug(); }` callback using the `waitForOptions` parameter.
:::
## Query predicates
@@ -192,29 +192,29 @@ const element3 = screen.getByRole('button', { name: 'Hello', disabled: true });
#### Options {#by-role-options}
- `name`: Finds an element with given `role`/`accessibilityRole` and an accessible name (= accessability label or text content).
- `name`: Finds an element with the given `role`/`accessibilityRole` and an accessible name (= accessibility label or text content).
- `disabled`: You can filter elements by their disabled state (coming either from `aria-disabled` prop or `accessbilityState.disabled` prop). The possible values are `true` or `false`. Querying `disabled: false` will also match elements with `disabled: undefined` (see the [wiki](https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State) for more details).
- `disabled`: You can filter elements by their disabled state (coming either from `aria-disabled` prop or `accessibilityState.disabled` prop). The possible values are `true` or `false`. Querying `disabled: false` will also match elements with `disabled: undefined` (see the [wiki](https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State) for more details).
- See [React Native's accessibilityState](https://reactnative.dev/docs/accessibility#accessibilitystate) docs to learn more about the `disabled` state.
- This option can alternatively be expressed using the [`toBeEnabled()` / `toBeDisabled()`](/docs/api/jest-matchers#tobeenabled) Jest matchers.
- `selected`: You can filter elements by their selected state (coming either from `aria-selected` prop or `accessbilityState.selected` prop). The possible values are `true` or `false`. Querying `selected: false` will also match elements with `selected: undefined` (see the [wiki](https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State) for more details).
- `selected`: You can filter elements by their selected state (coming either from `aria-selected` prop or `accessibilityState.selected` prop). The possible values are `true` or `false`. Querying `selected: false` will also match elements with `selected: undefined` (see the [wiki](https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State) for more details).
- See [React Native's accessibilityState](https://reactnative.dev/docs/accessibility#accessibilitystate) docs to learn more about the `selected` state.
- This option can alternatively be expressed using the [`toBeSelected()`](/docs/api/jest-matchers#tobeselected) Jest matcher.
* `checked`: You can filter elements by their checked state (coming either from `aria-checked` prop or `accessbilityState.checked` prop). The possible values are `true`, `false`, or `"mixed"`.
* `checked`: You can filter elements by their checked state (coming either from `aria-checked` prop or `accessibilityState.checked` prop). The possible values are `true`, `false`, or `"mixed"`.
- See [React Native's accessibilityState](https://reactnative.dev/docs/accessibility#accessibilitystate) docs to learn more about the `checked` state.
- This option can alternatively be expressed using the [`toBeChecked()` / `toBePartiallyChecked()`](/docs/api/jest-matchers#tobechecked) Jest matchers.
* `busy`: You can filter elements by their busy state (coming either from `aria-busy` prop or `accessbilityState.busy` prop). The possible values are `true` or `false`. Querying `busy: false` will also match elements with `busy: undefined` (see the [wiki](https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State) for more details).
* `busy`: You can filter elements by their busy state (coming either from `aria-busy` prop or `accessibilityState.busy` prop). The possible values are `true` or `false`. Querying `busy: false` will also match elements with `busy: undefined` (see the [wiki](https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State) for more details).
- See [React Native's accessibilityState](https://reactnative.dev/docs/accessibility#accessibilitystate) docs to learn more about the `busy` state.
- This option can alternatively be expressed using the [`toBeBusy()`](/docs/api/jest-matchers#tobebusy) Jest matcher.
* `expanded`: You can filter elements by their expanded state (coming either from `aria-expanded` prop or `accessbilityState.expanded` prop). The possible values are `true` or `false`.
* `expanded`: You can filter elements by their expanded state (coming either from `aria-expanded` prop or `accessibilityState.expanded` prop). The possible values are `true` or `false`.
- See [React Native's accessibilityState](https://reactnative.dev/docs/accessibility#accessibilitystate) docs to learn more about the `expanded` state.
- This option can alternatively be expressed using the [`toBeExpanded()` / `toBeCollapsed()`](/docs/api/jest-matchers#tobeexpanded) Jest matchers.
* `value`: Filter elements by their accessibility value, based on either `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext` or `accessibilityValue` props. Accessiblity value conceptually consists of numeric `min`, `max` and `now` entries, as well as string `text` entry.
* `value`: Filter elements by their accessibility value, based on either `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext`, or `accessibilityValue` props. Accessibility value conceptually consists of numeric `min`, `max`, and `now` entries, as well as string `text` entry.
- See React Native [accessibilityValue](https://reactnative.dev/docs/accessibility#accessibilityvalue) docs to learn more about the accessibility value concept.
- This option can alternatively be expressed using the [`toHaveAccessibilityValue()`](/docs/api/jest-matchers#tohaveaccessibilityvalue) Jest matcher.
@@ -260,7 +260,7 @@ getByPlaceholderText(
): ReactTestInstance;
```
Returns a `ReactTestInstance` for a `TextInput` with a matching placeholder – may be a string or regular expression.
Returns a `ReactTestInstance` for a `TextInput` with a matching placeholder—may be a string or regular expression.
```jsx
import { render, screen } from '@testing-library/react-native';
@@ -284,7 +284,7 @@ getByDisplayValue(
): ReactTestInstance;
```
Returns a `ReactTestInstance` for a `TextInput` with a matching display value – may be a string or regular expression.
Returns a `ReactTestInstance` for a `TextInput` with a matching display value—may be a string or regular expression.
```jsx
import { render, screen } from '@testing-library/react-native';
@@ -308,9 +308,9 @@ getByText(
): ReactTestInstance;
```
Returns a `ReactTestInstance` with matching text – may be a string or regular expression.
Returns a `ReactTestInstance` with matching text—may be a string or regular expression.
This method will join `<Text>` siblings to find matches, similarly to [how React Native handles these components](https://reactnative.dev/docs/text#containers). This will allow for querying for strings that will be visually rendered together, but may be semantically separate React components.
This method joins `<Text>` siblings to find matches, similarly to [how React Native handles these components](https://reactnative.dev/docs/text#containers). This allows querying for strings that will be visually rendered together but may be semantically separate React components.
```jsx
import { render, screen } from '@testing-library/react-native';
@@ -364,7 +364,7 @@ getByTestId(
): ReactTestInstance;
```
Returns a `ReactTestInstance` with matching `testID` prop. `testID` – may be a string or a regular expression.
Returns a `ReactTestInstance` with a matching `testID` prop. `testID` may be a string or a regular expression.
```jsx
import { render, screen } from '@testing-library/react-native';
@@ -374,16 +374,16 @@ const element = screen.getByTestId('unique-id');
```
:::info
In the spirit of [the guiding principles](https://testing-library.com/docs/guiding-principles), it is recommended to use this only after the other queries don't work for your use case. Using `testID` attributes do not resemble how your software is used and should be avoided if possible. However, they are particularly useful for end-to-end testing on real devices, e.g. using Detox and it's an encouraged technique to use there. Learn more from the blog post ["Making your UI tests resilient to change"](https://kentcdodds.com/blog/making-your-ui-tests-resilient-to-change).
In the spirit of [the guiding principles](https://testing-library.com/docs/guiding-principles), use this only after the other queries don't work for your use case. Using `testID` attributes doesn't resemble how your software is used and should be avoided if possible. However, they're particularly useful for end-to-end testing on real devices, e.g. using Detox, and it's an encouraged technique to use there. Learn more from the blog post ["Making your UI tests resilient to change"](https://kentcdodds.com/blog/making-your-ui-tests-resilient-to-change).
:::
### Common options
Usually query first argument can be a **string** or a **regex**. All queries take at least the [`hidden`](#hidden-option) option as an optionnal second argument and some queries accept more options which change string matching behaviour. See [TextMatch](#textmatch) for more info.
Usually the query's first argument can be a **string** or a **regex**. All queries take at least the [`hidden`](#hidden-option) option as an optional second argument, and some queries accept more options that change string matching behavior. See [TextMatch](#textmatch) for more info.
#### `includeHiddenElements` option
All queries have the `includeHiddenElements` option which affects whether [elements hidden from accessibility](/docs/api/misc/accessibility#ishiddenfromaccessibility) are matched by the query. By default queries will not match hidden elements, because the users of the app would not be able to see such elements.
All queries have the `includeHiddenElements` option which affects whether [elements hidden from accessibility](/docs/api/misc/accessibility#ishiddenfromaccessibility) are matched by the query. By default, queries won't match hidden elements because users of the app wouldn't be able to see such elements.
You can configure the default value with the [`configure` function](/docs/api/misc/config#configure).
@@ -414,7 +414,7 @@ expect(
type TextMatch = string | RegExp;
```
Most of the query APIs take a `TextMatch` as an argument, which means the argument can be either a _string_ or _regex_.
Most query APIs take a `TextMatch` as an argument, which means the argument can be either a _string_ or _regex_.
### Examples
@@ -462,26 +462,26 @@ type TextMatchOptions = {
};
```
Queries that take a `TextMatch` also accept an object as the second argument that can contain options that affect the precision of string matching:
Queries that take a `TextMatch` also accept an object as the second argument that contains options affecting the precision of string matching:
- `exact`: Defaults to `true`; matches full strings, case-sensitive. When false, matches substrings and is not case-sensitive.
- `exact` has no effect on regex argument.
- In most cases using a `regex` instead of a string gives you more control over fuzzy matching and should be preferred over `{ exact: false }`.
- `normalizer`: An optional function which overrides normalization behavior. See [Normalization](#normalization).
`exact` option defaults to `true` but if you want to search for a text slice or make text matching case-insensitive you can override it. That being said we advise you to use regex in more complex scenarios.
The `exact` option defaults to `true`, but if you want to search for a text slice or make text matching case-insensitive, you can override it. That said, we advise you to use regex in more complex scenarios.
#### Normalization
Before running any matching logic against text, it is automatically normalized. By default, normalization consists of trimming whitespace from the start and end of text, and collapsing multiple adjacent whitespace characters into a single space.
Before running any matching logic against text, it's automatically normalized. By default, normalization consists of trimming whitespace from the start and end of text and collapsing multiple adjacent whitespace characters into a single space.
If you want to prevent that normalization, or provide alternative normalization (e.g. to remove Unicode control characters), you can provide a `normalizer` function in the options object. This function will be given a string and is expected to return a normalized version of that string.
If you want to prevent that normalization or provide alternative normalization (e.g., to remove Unicode control characters), you can provide a `normalizer` function in the options object. This function is given a string and is expected to return a normalized version of that string.
:::info
Specifying a value for `normalizer` replaces the built-in normalization, but you can call `getDefaultNormalizer` to obtain a built-in normalizer, either to adjust that normalization or to call it from your own normalizer.
:::
`getDefaultNormalizer` take options object which allows the selection of behaviour:
`getDefaultNormalizer` takes an options object that allows selection of behavior:
- `trim`: Defaults to `true`. Trims leading and trailing whitespace.
- `collapseWhitespace`: Defaults to `true`. Collapses inner whitespace (newlines, tabs repeated spaces) into a single space.
@@ -508,24 +508,24 @@ screen.getByText(node, 'text', {
`render` from `@testing-library/react-native` exposes additional queries that **should not be used in integration or component testing**, but some users (like component library creators) interested in unit testing some components may find helpful.
The interface is the same as for other queries, but we won't provide full names so that they're harder to find by search engines.
The interface is the same as for other queries, but we won't provide full names so they're harder to find via search engines.
### `UNSAFE_ByType`
> UNSAFE_getByType, UNSAFE_getAllByType, UNSAFE_queryByType, UNSAFE_queryAllByType
Returns a `ReactTestInstance` with matching a React component type.
Returns a `ReactTestInstance` with a matching React component type.
:::caution
This query has been marked unsafe, since it requires knowledge about implementation details of the component. Use responsibly.
This query has been marked unsafe because it requires knowledge about implementation details of the component. Use responsibly.
:::
### `UNSAFE_ByProps`
> UNSAFE_getByProps, UNSAFE_getAllByProps, UNSAFE_queryByProps, UNSAFE_queryAllByProps
Returns a `ReactTestInstance` with matching props object.
Returns a `ReactTestInstance` with matching props.
:::caution
This query has been marked unsafe, since it requires knowledge about implementation details of the component. Use responsibly.
This query has been marked unsafe because it requires knowledge about implementation details of the component. Use responsibly.
:::
+2 -2
View File
@@ -63,7 +63,7 @@ React Test Renderer does not enforce this check; hence, by default, React Native
### Result
The `render` function returns the same queries and utilities as the [`screen`](/docs/api/screen) object. We recommended using the `screen` object as more developer-friendly way.
The `render` function returns the same queries and utilities as the [`screen`](/docs/api/screen) object. We recommend using the `screen` object for a more developer-friendly experience.
See [this article](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen) from Kent C. Dodds for more details.
@@ -99,7 +99,7 @@ test('async component test', async () => {
### Result
The `renderAsync` function returns a promise that resolves to the same queries and utilities as the [`screen`](/docs/api/screen) object. We recommend using the `screen` object for queries and the lifecycle methods from the render result when needed.
The `renderAsync` function returns a promise that resolves to the same queries and utilities as the [`screen`](/docs/api/screen) object. Use the `screen` object for queries and the lifecycle methods from the render result when needed.
:::warning Async lifecycle methods
+8 -8
View File
@@ -39,7 +39,7 @@ _Also available under `update` alias_
function rerender(element: React.Element<unknown>): void;
```
Re-render the in-memory tree with a new root element. This simulates a React update render at the root. If the new element has the same type (and `key`) as the previous element, the tree will be updated; otherwise, it will re-mount a new tree, in both cases triggering the appropriate lifecycle events.
Re-renders the in-memory tree with a new root element. This simulates a React update render at the root. If the new element has the same type (and `key`) as the previous element, the tree is updated; otherwise, it re-mounts a new tree. In both cases, it triggers the appropriate lifecycle events.
### `rerenderAsync`
@@ -53,7 +53,7 @@ This API requires RNTL v13.3.0 or later.
function rerenderAsync(element: React.Element<unknown>): Promise<void>;
```
Async versions of [`rerender`](#rerender) designed for working with React 19 and React Suspense. This method uses async `act` function internally to ensure all pending React updates are executed during updating.
Async version of [`rerender`](#rerender) designed for working with React 19 and React Suspense. This method uses async `act` internally to ensure all pending React updates are executed during updating.
```jsx
import { renderAsync, screen } from '@testing-library/react-native';
@@ -90,7 +90,7 @@ This API requires RNTL v13.3.0 or later.
function unmountAsync(): Promise<void>;
```
Async version of [`unmount`](#unmount) designed for working with React 19 and React Suspense. This method uses async `act` function internally to ensure all pending React updates are executed during unmounting.
Async version of [`unmount`](#unmount) designed for working with React 19 and React Suspense. This method uses async `act` internally to ensure all pending React updates are executed during unmounting.
:::note
Usually you should not need to call `unmountAsync` as it is done automatically if your test runner supports `afterEach` hook (like Jest, mocha, Jasmine).
@@ -131,7 +131,7 @@ optional message
function debug({ mapProps: (props) => ({}) });
```
You can use the `mapProps` option to transform the props that will be printed :
You can use the `mapProps` option to transform the props that will be printed:
```jsx
render(<View style={{ backgroundColor: 'red' }} />);
@@ -144,7 +144,7 @@ The `children` prop cannot be filtered out so the following will print all rende
This option can be used to target specific props when debugging a query (for instance, keeping only the `children` prop when debugging a `getByText` query).
You can also transform prop values so that they are more readable (e.g., flatten styles).
You can also transform prop values to make them more readable (e.g., flatten styles).
```ts
import { StyleSheet } from 'react-native';
@@ -152,7 +152,7 @@ import { StyleSheet } from 'react-native';
screen.debug({ mapProps : {({ style, ...props })} => ({ style : StyleSheet.flatten(style), ...props }) });
```
Or remove props that have little value when debugging tests, e.g. path prop for svgs
Or remove props that have little value when debugging tests, e.g., path prop for SVGs
```ts
screen.debug({ mapProps: ({ path, ...props }) => ({ ...props }) });
@@ -174,7 +174,7 @@ const root: ReactTestInstance;
Returns the rendered root [host element](/docs/advanced/testing-env#host-and-composite-components).
This API is primarily useful for component tests, as it allows you to access root host view without using `*ByTestId` queries or similar methods.
This API is primarily useful for component tests, as it allows you to access the root host view without using `*ByTestId` queries or similar methods.
### `UNSAFE_root`
@@ -189,5 +189,5 @@ const UNSAFE_root: ReactTestInstance;
Returns the rendered [composite root element](/docs/advanced/testing-env#host-and-composite-components).
:::note
This API has been previously named `container` for compatibility with [React Testing Library](https://testing-library.com/docs/react-testing-library/other#container-1). However, despite the same name, the actual behavior has been significantly different; hence, we decided to change the name to `UNSAFE_root`.
This API was previously named `container` for compatibility with [React Testing Library](https://testing-library.com/docs/react-testing-library/other#container-1). However, despite the same name, the actual behavior was significantly different, so we changed the name to `UNSAFE_root`.
:::
+1 -1
View File
@@ -36,4 +36,4 @@ For new code, you are encouraged to use `screen` as there are some good reasons
## Should I use/migrate to User Event interactions?
We encourage you to migrate existing tests to use the [User Event interactions](/docs/api/events/user-event), which offer more realistic event handling than the basic [Fire Event API](/docs/api/events/fire-event). Hence, it will provide more confidence in the quality of your code.
We encourage you to migrate existing tests to use the [User Event interactions](/docs/api/events/user-event), which offer more realistic event handling than the basic [Fire Event API](/docs/api/events/fire-event). This provides more confidence in the quality of your code.
@@ -1,6 +1,6 @@
# How should I query?
React Native Testing Library provides various query types, allowing great flexibility in finding views appropriate for your tests. At the same time, the number of queries might be confusing. This guide aims to help you pick the correct queries for your test scenarios.
React Native Testing Library provides various query types for finding views in your tests. The number of queries might be confusing. This guide helps you pick the right queries for your test scenarios.
## Query parts
@@ -58,7 +58,7 @@ The query predicate describes how you decide whether to match the given element.
### Idiomatic query predicates
Choosing the proper query predicate helps better express the test's intent and make the tests resemble how users interact with your code (components, screens, etc.) as much as possible following our [Guiding Principles](https://testing-library.com/docs/guiding-principles). Additionally, most predicates promote the usage of proper accessibility props, which add a semantic layer on top of an element tree composed primarily of [`View`](https://reactnative.dev/docs/view) elements.
Choosing the right query predicate helps express the test's intent and makes tests resemble how users interact with your code (components, screens, etc.) following our [Guiding Principles](https://testing-library.com/docs/guiding-principles). Most predicates also promote using proper accessibility props, which add a semantic layer on top of an element tree composed primarily of [`View`](https://reactnative.dev/docs/view) elements.
It is recommended to use query predicates in the following order of priority:
+1 -1
View File
@@ -73,4 +73,4 @@ You can migrate gradually:
### Future direction
Async APIs will become the default recommendation as React 19 adoption grows. Starting with them now saves migration effort later.
Async APIs will become the default recommendation as React 19 adoption grows. Starting with them now saves migration effort.
@@ -57,7 +57,7 @@ within(getByText('Hello', {exact: false})).getByText('world')
## Future plans
This release changes a lot of internal logic in the library, paving the way for more improvements to bring us closer to our web counterpart, with a possibly better story for accessibility queries.
This release changes a lot of internal logic in the library, enabling more improvements to bring us closer to our web counterpart, with better support for accessibility queries.
We're also [migrating the codebase to TypeScript](https://github.com/callstack/react-native-testing-library/issues/877). Please let us know if you're interested in helping us with this effort.
+1 -1
View File
@@ -2,7 +2,7 @@
## 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 focus on making your tests give you the confidence they are intended. As part of this, you want your tests 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.
You want to write maintainable tests for your React Native components. Your tests should avoid implementation details and focus on giving you confidence that your components work correctly. Tests should also be maintainable so refactors (changes to implementation but not functionality) don't break your tests and slow you and your team down.
## This solution