From dc6c0625e8b413bec26df765cc9034a982442e94 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 17:29:32 +0100 Subject: [PATCH 01/11] render --- website/docs/14.x/docs/api/render.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/website/docs/14.x/docs/api/render.mdx b/website/docs/14.x/docs/api/render.mdx index 79018dd5..797d5e01 100644 --- a/website/docs/14.x/docs/api/render.mdx +++ b/website/docs/14.x/docs/api/render.mdx @@ -9,7 +9,7 @@ async function render( ): Promise; ``` -The `render` function is the entry point for writing React Native Testing Library tests. It deeply renders the given React element and returns helpers to query the output components' structure. This function is async by default and uses async `act` internally to ensure all pending React updates are executed during rendering, making it compatible with async React features like `Suspense` boundary or `use()` hook. +The `render` function is the entry point for writing React Native Testing Library tests. It deeply renders the given React element and returns helpers to query the output. The function is async and uses async `act` internally, so all pending React updates run before it resolves. This works with async React features like `Suspense` boundaries and the `use()` hook. ```jsx import { render, screen } from '@testing-library/react-native'; @@ -20,11 +20,11 @@ test('basic test', async () => { }); ``` -> When using React context providers, like Redux Provider, you'll likely want to wrap rendered component with them. In such cases, it's convenient to create your own custom `render` method. [Follow this great guide on how to set this up](https://testing-library.com/docs/react-testing-library/setup#custom-render). +> When using React context providers like Redux Provider, you'll likely want to wrap the rendered component with them. In such cases, create your own custom `render` method. [Follow this guide on how to set it up](https://testing-library.com/docs/react-testing-library/setup#custom-render). ### Options -The behavior of the `render` method can be customized by passing various options as a second argument of the `RenderOptions` type: +You can customize the `render` method by passing options as the second argument: #### `wrapper` @@ -32,7 +32,7 @@ The behavior of the `render` method can be customized by passing various options wrapper?: React.ComponentType, ``` -This option allows you to wrap the tested component, passed as the first option to the `render()` function, in an additional wrapper component. This is useful for creating reusable custom render functions for common React Context providers. +Wraps the tested component in an additional wrapper component. Use this to create custom render functions for common React Context providers. #### `createNodeMock` {#create-node-mock} @@ -40,24 +40,24 @@ This option allows you to wrap the tested component, passed as the first option createNodeMock?: (element: React.ReactElement) => object, ``` -This option allows you to pass `createNodeMock` option to the renderer's `create()` method in order to allow for custom mock refs. This option is passed through to [Test Renderer](https://github.com/mdjastrzebski/test-renderer). +Passes `createNodeMock` to the renderer's `create()` method for custom mock refs. This option is passed through to [Test Renderer](https://github.com/mdjastrzebski/test-renderer). :::note Text string validation -Test Renderer automatically enforces React Native's requirement that text strings must be rendered within a `` component. If you try to render a `string` value under components other than `` (e.g., under ``), it will throw an `Invariant Violation: Text strings must be rendered within a component` error, matching React Native's runtime behavior. +Test Renderer enforces React Native's requirement that text strings must be rendered within a `` component. If you render a `string` value under components other than `` (e.g., under ``), it throws an `Invariant Violation: Text strings must be rendered within a component` error. This matches React Native's runtime behavior. -This validation is always enabled and cannot be disabled, ensuring your tests accurately reflect how your code will behave in production. +This validation is always enabled and cannot be disabled. Your tests will catch the same text rendering errors that would occur in production. ::: ### Result -The `render` 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 `render` function returns a promise that resolves to the same queries and utilities as the [`screen`](/docs/api/screen) object. Use `screen` for queries and the lifecycle methods from the render result when needed. See [this article](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen) from Kent C. Dodds for more details. :::note Type information -Query results and element references use the `HostElement` type from [Test Renderer](https://github.com/mdjastrzebski/test-renderer). If you need to type element variables, you can import this type directly from `test-renderer`. +Query results and element references use the `HostElement` type from [Test Renderer](https://github.com/mdjastrzebski/test-renderer). If you need to type element variables, import this type directly from `test-renderer`. ::: From a47fd8f27738c7534e92183b77a48fb983924eb6 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 17:33:32 +0100 Subject: [PATCH 02/11] migration guide --- .../docs/14.x/docs/start/migration-v14.mdx | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/website/docs/14.x/docs/start/migration-v14.mdx b/website/docs/14.x/docs/start/migration-v14.mdx index 4cd2f153..60fefe3d 100644 --- a/website/docs/14.x/docs/start/migration-v14.mdx +++ b/website/docs/14.x/docs/start/migration-v14.mdx @@ -12,13 +12,13 @@ This guide describes the migration to React Native Testing Library version 14 fr ## Overview -RNTL v14 is a major release that **drops support for React 18** and fully embraces React 19's async-first paradigm. Key changes include: +RNTL v14 drops support for React 18 and adopts React 19's async rendering model. Here's what changed: -- **React 19+ required**: Minimum supported versions are React 19.0.0 and React Native 0.78+ -- **Async APIs by default**: `render`, `renderHook`, `fireEvent`, and `act` are now async -- **New renderer**: Switched from deprecated [React Test Renderer](https://reactjs.org/docs/test-renderer.html) to [Test Renderer](https://github.com/mdjastrzebski/test-renderer) -- **API cleanup**: Removed deprecated APIs (`update`, `getQueriesForElement`, `UNSAFE_root`, `concurrentRoot` option) -- **Safe `container` API**: Reintroduced `container` which is now safe to use +- React 19.0.0+ and React Native 0.78+ are now required +- `render`, `renderHook`, `fireEvent`, and `act` are now async +- Switched from deprecated [React Test Renderer](https://reactjs.org/docs/test-renderer.html) to [Test Renderer](https://github.com/mdjastrzebski/test-renderer) +- Removed deprecated APIs: `update`, `getQueriesForElement`, `UNSAFE_root`, `concurrentRoot` option +- Reintroduced `container` API, which is now safe to use :::info React 18 Users @@ -67,13 +67,13 @@ After running the codemods, review the changes and run your tests. ### Test Renderer replaces React Test Renderer -In v14, React Native Testing Library now uses [Test Renderer](https://github.com/mdjastrzebski/test-renderer) instead of the deprecated [React Test Renderer](https://reactjs.org/docs/test-renderer.html). Test Renderer is a modern, actively maintained alternative that provides better compatibility with React 19 and improved type safety. +In v14, React Native Testing Library uses [Test Renderer](https://github.com/mdjastrzebski/test-renderer) instead of the deprecated [React Test Renderer](https://reactjs.org/docs/test-renderer.html). Test Renderer works with React 19 and has better TypeScript support. **What changed:** -- The underlying renderer has been switched from React Test Renderer to Test Renderer -- This change is mostly internal and should not require code changes in most cases -- Type definitions have been updated to use [`HostElement`](https://github.com/mdjastrzebski/test-renderer#hostelement) from Test Renderer instead of `ReactTestInstance` +- The underlying renderer is now Test Renderer instead of React Test Renderer +- This is mostly an internal change; your tests should work without modifications in most cases +- Type definitions now use [`HostElement`](https://github.com/mdjastrzebski/test-renderer#hostelement) from Test Renderer instead of `ReactTestInstance` **Migration:** @@ -117,11 +117,11 @@ import type { HostElement } from 'test-renderer'; **Note:** Most users won't need to update type imports, as React Native Testing Library now exports the necessary types directly. -For more details, see the [Test Renderer documentation](https://github.com/mdjastrzebski/test-renderer). +See the [Test Renderer documentation](https://github.com/mdjastrzebski/test-renderer) for more. ### Async APIs by Default -With React 18 support dropped, RNTL v14 fully embraces React 19's async rendering model. The following functions are now async by default: +With React 18 support dropped, RNTL v14 uses React 19's async rendering model. The following functions are now async by default: - `render()` → returns `Promise` - `rerender()` and `unmount()` → return `Promise` @@ -131,13 +131,13 @@ With React 18 support dropped, RNTL v14 fully embraces React 19's async renderin :::tip Already using async APIs? -If you adopted the async APIs introduced in RNTL v13.3 (`renderAsync`, `fireEventAsync`, `renderHookAsync`), simply rename them to their non-async counterparts (`render`, `fireEvent`, `renderHook`). The async versions have been removed as the standard APIs are now async by default. +If you adopted the async APIs introduced in RNTL v13.3 (`renderAsync`, `fireEventAsync`, `renderHookAsync`), rename them to their non-async counterparts (`render`, `fireEvent`, `renderHook`). The async versions have been removed since the standard APIs are now async by default. ::: #### `render` is now async {#render-async-default} -In v14, `render` is now async by default and returns a Promise. This change enables proper support for async React features like `Suspense` boundary or `use()` hook. +In v14, `render` is async by default and returns a Promise. This allows proper support for `Suspense` boundaries and the `use()` hook. **Before (v13):** @@ -161,11 +161,11 @@ it('should render component', async () => { }); ``` -For more details, see the [`render` API documentation](/docs/api/render). +See the [`render` API documentation](/docs/api/render). #### `renderHook` is now async -In v14, `renderHook` is now async by default and returns a Promise. +In v14, `renderHook` is async by default and returns a Promise. **Before (v13):** @@ -193,11 +193,11 @@ it('should test hook', async () => { }); ``` -For more details, see the [`renderHook` API documentation](/docs/api/misc/render-hook). +See the [`renderHook` API documentation](/docs/api/misc/render-hook). #### `fireEvent` is now async -In v14, `fireEvent` and its helpers (`press`, `changeText`, `scroll`) are now async by default and return a Promise. +In v14, `fireEvent` and its helpers (`press`, `changeText`, `scroll`) are async by default and return a Promise. **Before (v13):** @@ -225,13 +225,12 @@ it('should press button', async () => { #### `act` is now async -In v14, `act` is now async by default and always returns a Promise. You should always `await` the result of `act()`. +In v14, `act` is async by default and always returns a Promise. You should always `await` the result of `act()`. **What changed:** -- `act` now always returns a `Promise` instead of `T | Thenable` +- `act` now always returns `Promise` instead of `T | Thenable` - `act` should always be awaited -- The API is more consistent and predictable :::note @@ -267,14 +266,11 @@ it('should update state', async () => { **Note**: Even if your callback is synchronous, you should still use `await act(...)` as `act` now always returns a Promise. -For more details, see the [`act` API documentation](/docs/api/misc/other#act). +See the [`act` API documentation](/docs/api/misc/other#act). -#### Benefits of Async APIs +#### Why async APIs? -- **Suspense support**: Properly handles `Suspense` boundaries and `use()` hook -- **Better timing**: Ensures all pending React updates are executed before assertions -- **Simpler mental model**: All rendering operations are consistently async -- **Future-proof**: Aligns with React's direction toward async rendering +The async APIs properly handle `Suspense` boundaries and the `use()` hook, and ensure all pending React updates complete before assertions run. This matches React 19's async rendering model. ### Removed APIs @@ -343,7 +339,7 @@ const input = screen.getByPlaceholderText('Enter text'); #### `concurrentRoot` option removed -The `concurrentRoot` option has been removed from both `render` options and `configure` function. In v14, concurrent rendering is always enabled by default, as it is the standard rendering mode for React 19 and React Native's New Architecture. +The `concurrentRoot` option has been removed from both `render` options and `configure` function. In v14, concurrent rendering is always enabled, since it's the standard rendering mode for React 19 and React Native's New Architecture. ```ts // Before (v13) @@ -355,11 +351,11 @@ configure({ concurrentRoot: false }); // Disable globally await render(); // Always uses concurrent rendering ``` -**Migration:** Simply remove any `concurrentRoot` options from your `render` calls and `configure` function. If you were explicitly setting `concurrentRoot: true`, no changes are needed beyond removing the option. If you were setting `concurrentRoot: false` to disable concurrent rendering, this is no longer supported in v14. +**Migration:** Remove any `concurrentRoot` options from your `render` calls and `configure` function. If you were setting `concurrentRoot: true`, just remove the option. If you were setting `concurrentRoot: false` to disable concurrent rendering, this is no longer supported in v14. ### `container` API reintroduced -In v14, the `container` API has been reintroduced and is now safe to use. Previously, `container` was renamed to `UNSAFE_root` in v12 due to behavioral differences from React Testing Library's `container`. In v14, `container` now returns a pseudo-element container whose children are the elements you asked to render, making it safe and consistent with React Testing Library's behavior. +In v14, the `container` API has been reintroduced and is now safe to use. Previously, `container` was renamed to `UNSAFE_root` in v12 due to behavioral differences from React Testing Library's `container`. Now `container` returns a pseudo-element container whose children are the elements you rendered, consistent with React Testing Library's behavior. **What changed:** @@ -394,11 +390,11 @@ it('should access container', async () => { }); ``` -For more details, see the [`screen` API documentation](/docs/api/screen#container). +See the [`screen` API documentation](/docs/api/screen#container). ### Text string validation enforced by default -In v14, Test Renderer automatically enforces React Native's requirement that text strings must be rendered within a `` component. This means the `unstable_validateStringsRenderedWithinText` option has been removed from `RenderOptions`, as this validation is now always enabled. +In v14, Test Renderer enforces React Native's requirement that text strings must be rendered within a `` component. The `unstable_validateStringsRenderedWithinText` option has been removed from `RenderOptions` since this validation is now always on. **What changed:** @@ -425,7 +421,7 @@ If you were relying on the previous behavior where strings could be rendered out ## Codemods -We provide two codemods to automate the migration. Both codemods are **safe to run multiple times** - they will only transform code that hasn't been migrated yet. +Two codemods are available to automate the migration. Both are safe to run multiple times - they only transform code that hasn't been migrated yet. ### `rntl-v14-update-deps` From 5a45abff2bf04e46ed4a3841296df6b0db56ce9f Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 22:28:10 +0100 Subject: [PATCH 03/11] render hook --- .../docs/14.x/docs/api/misc/render-hook.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/website/docs/14.x/docs/api/misc/render-hook.mdx b/website/docs/14.x/docs/api/misc/render-hook.mdx index 5a292b54..ab4104ca 100644 --- a/website/docs/14.x/docs/api/misc/render-hook.mdx +++ b/website/docs/14.x/docs/api/misc/render-hook.mdx @@ -9,9 +9,9 @@ async function renderHook( ): Promise>; ``` -Renders a test component that will call the provided `callback`, including any hooks it calls, every time it renders. Returns a Promise that resolves to a [`RenderHookResult`](#renderhookresult) object, which you can interact with. +Renders a test component that calls the provided `callback` (and any hooks it uses) on each render. Returns a Promise that resolves to a [`RenderHookResult`](#renderhookresult) object. -**This is the recommended default API** for testing hooks. It uses async `act` internally to ensure all pending React updates are executed during rendering, making it compatible with async React features like `Suspense` boundary or `use()` hook. +**This is the recommended default API** for testing hooks. It uses async `act` internally to ensure all pending React updates are executed during rendering. This makes it compatible with async React features like `Suspense` boundaries and the `use()` hook. - **Returns a Promise**: Should be awaited - **Async methods**: Both `rerender` and `unmount` return Promises and should be awaited @@ -47,13 +47,13 @@ export const useCount = () => { The `renderHook` function accepts the following arguments: -Callback is a function that is called each `render` of the test component. This function should call one or more hooks for testing. +**Callback**: A function called on 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. +The callback receives `props` from the `initialProps` option, or from a subsequent `rerender` call if provided. ### `options` -A `RenderHookOptions` object to modify the execution of the `callback` function, containing the following properties: +A `RenderHookOptions` object with the following properties: #### `initialProps` {#initial-props} @@ -61,7 +61,7 @@ The initial values to pass as `props` to the `callback` function of `renderHook` #### `wrapper` -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`. +A React component that wraps the test component. Use this to add context providers so hooks can access them with `useContext`. ### Result @@ -77,13 +77,13 @@ The `renderHook` function returns a Promise that resolves to an object with the #### `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. +The `current` value contains whatever the `callback` returned from `renderHook`. The `Result` type is determined by the type passed to or inferred by the `renderHook` call. **Note:** When using React Suspense, `result.current` will be `null` while the hook is suspended. #### `rerender` -An async 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. +An async function that rerenders the test component and recalculates hooks. 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. **Note**: This method returns a Promise and should be awaited. @@ -95,7 +95,7 @@ An async function to unmount the test component. This is commonly used to trigge ### Examples -Here we present some extra examples of using `renderHook` API. +Additional examples of using `renderHook`: #### With `initialProps` From ac25e60883b95d71865c4c93251ffcf3a08e5531 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 22:39:14 +0100 Subject: [PATCH 04/11] rest of the docs --- README-v13.md | 12 ++++---- README.md | 22 +++----------- .../docs/14.x/docs/advanced/testing-env.mdx | 28 ++++++++--------- .../14.x/docs/advanced/understanding-act.mdx | 16 +++++----- .../docs/14.x/docs/api/events/fire-event.mdx | 13 ++++---- .../docs/14.x/docs/api/events/user-event.mdx | 14 ++++----- website/docs/14.x/docs/api/jest-matchers.mdx | 30 +++++++++---------- website/docs/14.x/docs/api/misc/async.mdx | 10 +++---- website/docs/14.x/docs/api/misc/other.mdx | 2 +- website/docs/14.x/docs/api/queries.mdx | 8 ++--- website/docs/14.x/docs/api/screen.mdx | 12 ++++---- website/docs/14.x/docs/guides/faq.mdx | 24 +++++++-------- .../docs/14.x/docs/guides/how-to-query.mdx | 10 +++---- .../docs/14.x/docs/guides/troubleshooting.mdx | 8 ++--- website/docs/14.x/docs/start/quick-start.mdx | 6 ++-- 15 files changed, 99 insertions(+), 116 deletions(-) diff --git a/README-v13.md b/README-v13.md index 4f8e82c2..d4c633bc 100644 --- a/README-v13.md +++ b/README-v13.md @@ -14,11 +14,11 @@ ## 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 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. They should remain maintainable so refactors (changes to implementation but not functionality) don't break your tests and slow you and your team down. ## This solution -The React Native Testing Library (RNTL) is a comprehensive solution for testing React Native components. It provides React Native runtime simulation on top of `react-test-renderer`, in a way that encourages better testing practices. Its primary guiding principle is: +The React Native Testing Library (RNTL) tests React Native components. It simulates the React Native runtime on top of `react-test-renderer` and encourages better testing practices. Its primary guiding principle is: > The more your tests resemble the way your software is used, the more confidence they can give you. @@ -48,8 +48,8 @@ You can use the built-in Jest matchers automatically by having any import from ` import { render, screen, userEvent } from '@testing-library/react-native'; import { QuestionsBoard } from '../QuestionsBoard'; -// It is recommended to use userEvent with fake timers -// Some events involve duration so your tests may take a long time to run. +// Use userEvent with fake timers +// Some events involve duration, so tests may take a long time to run. jest.useFakeTimers(); test('form submits two answers', async () => { @@ -87,8 +87,8 @@ React Native Testing Library consists of following APIs: - Lifecycle methods: [`rerender`](https://callstack.github.io/react-native-testing-library/docs/api/screen#rerender), [`unmount`](https://callstack.github.io/react-native-testing-library/docs/api/screen#unmount) - Helpers: [`debug`](https://callstack.github.io/react-native-testing-library/docs/api/screen#debug), [`toJSON`](https://callstack.github.io/react-native-testing-library/docs/api/screen#tojson), [`root`](https://callstack.github.io/react-native-testing-library/docs/api/screen#root) - [Jest matchers](https://callstack.github.io/react-native-testing-library/docs/api/jest-matchers) - validate assumptions about your UI -- [User Event](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#type) in a realistic way -- [Fire Event](https://callstack.github.io/react-native-testing-library/docs/api/events/fire-event) - simulate any component event in a simplified way +- [User Event](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#type) +- [Fire Event](https://callstack.github.io/react-native-testing-library/docs/api/events/fire-event) - simulate any component event - [`renderHook` function](https://callstack.github.io/react-native-testing-library/docs/api/misc/render-hook) - render hooks for testing purposes - Miscellaneous APIs: - [Async utils](https://callstack.github.io/react-native-testing-library/docs/api/misc/async): `findBy*` queries, `waitFor`, `waitForElementToBeRemoved` diff --git a/README.md b/README.md index 3d885fbe..86d9631a 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ ## 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 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. They should remain maintainable so refactors (changes to implementation but not functionality) don't break your tests and slow you and your team down. ## This solution -The React Native Testing Library (RNTL) is a comprehensive solution for testing React Native components. It provides React Native runtime simulation on top of `test-renderer`, in a way that encourages better testing practices. Its primary guiding principle is: +The React Native Testing Library (RNTL) tests React Native components. It simulates the React Native runtime on top of [Test Renderer](https://github.com/mdjastrzebski/test-renderer) and encourages better testing practices. Its primary guiding principle is: > The more your tests resemble the way your software is used, the more confidence they can give you. @@ -34,20 +34,12 @@ This project is inspired by [React Testing Library](https://github.com/testing-l Open a Terminal in your project's folder and run: ```sh -# Yarn install: -yarn add --dev @testing-library/react-native@alpha - -# NPM install npm install --save-dev @testing-library/react-native@alpha ``` This library has a `peerDependencies` listing for [Test Renderer](https://github.com/mdjastrzebski/test-renderer). Make sure to install it as a dev dependency: ```sh -# Yarn install: -yarn add --dev test-renderer - -# NPM install npm install --save-dev test-renderer ``` @@ -61,10 +53,6 @@ You can use the built-in Jest matchers automatically by having any import from ` import { render, screen, userEvent } from '@testing-library/react-native'; import { QuestionsBoard } from '../QuestionsBoard'; -// It is recommended to use userEvent with fake timers -// Some events involve duration so your tests may take a long time to run. -jest.useFakeTimers(); - test('form submits two answers', async () => { const questions = ['q1', 'q2']; const onSubmit = jest.fn(); @@ -100,8 +88,8 @@ React Native Testing Library consists of following APIs: - Lifecycle methods: [`rerender`](https://callstack.github.io/react-native-testing-library/docs/api/screen#rerender), [`unmount`](https://callstack.github.io/react-native-testing-library/docs/api/screen#unmount) - Helpers: [`debug`](https://callstack.github.io/react-native-testing-library/docs/api/screen#debug), [`toJSON`](https://callstack.github.io/react-native-testing-library/docs/api/screen#tojson), [`root`](https://callstack.github.io/react-native-testing-library/docs/api/screen#root), [`container`](https://callstack.github.io/react-native-testing-library/docs/api/screen#container) - [Jest matchers](https://callstack.github.io/react-native-testing-library/docs/api/jest-matchers) - validate assumptions about your UI -- [User Event](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#type) in a realistic way -- [Fire Event](https://callstack.github.io/react-native-testing-library/docs/api/events/fire-event) - simulate any component event in a simplified way +- [User Event](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#type) +- [Fire Event](https://callstack.github.io/react-native-testing-library/docs/api/events/fire-event) - simulate any component event - [`renderHook` function](https://callstack.github.io/react-native-testing-library/docs/api/misc/render-hook) - render hooks for testing purposes - Miscellaneous APIs: - [Async utils](https://callstack.github.io/react-native-testing-library/docs/api/misc/async): `findBy*` queries, `waitFor`, `waitForElementToBeRemoved` @@ -112,8 +100,6 @@ React Native Testing Library consists of following APIs: ## Migration Guides - **[Migration to 14.0](https://callstack.github.io/react-native-testing-library/docs/migration/v14)** - Drops React 18, async APIs by default -- [Migration to 13.0](https://callstack.github.io/react-native-testing-library/docs/migration/v13) -- [Migration to built-in Jest Matchers](https://callstack.github.io/react-native-testing-library/docs/migration/jest-matchers) ## Troubleshooting diff --git a/website/docs/14.x/docs/advanced/testing-env.mdx b/website/docs/14.x/docs/advanced/testing-env.mdx index db6a3fd1..f6e27dc9 100644 --- a/website/docs/14.x/docs/advanced/testing-env.mdx +++ b/website/docs/14.x/docs/advanced/testing-env.mdx @@ -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 lets you write integration and component tests for your React Native app or library. While the JSX code in tests closely resembles your React Native app, the underlying environment differs. This document describes the key elements of our testing environment and highlights things to be aware of when writing advanced tests or diagnosing issues. ## React renderers @@ -20,21 +20,19 @@ When you run your tests in the React Native Testing Library, somewhat contrary t ## Test Renderer -Instead, RNTL uses [Test Renderer](https://github.com/mdjastrzebski/test-renderer), a modern, actively maintained renderer that allows rendering to pure JavaScript objects without access to mobile OS and can run in a Node.js environment using Jest (or any other JavaScript test runner). Test Renderer replaces the deprecated `react-test-renderer` package and provides better compatibility with React 19 and improved type safety. +Instead, RNTL uses [Test Renderer](https://github.com/mdjastrzebski/test-renderer), a modern, actively maintained renderer that renders to pure JavaScript objects without access to mobile OS and runs in a Node.js environment using Jest (or any other JavaScript test runner). Test Renderer replaces the deprecated `react-test-renderer` package and has better compatibility with React 19 and improved type safety. -Using Test Renderer has pros and cons. +Using Test Renderer has trade-offs: Benefits: - -- tests can run on most CIs (Linux, etc) and do not require a mobile device or emulator -- faster test execution -- light runtime environment - -Disadvantages: - -- Tests do not execute native code -- Tests are unaware of the view state that would be managed by native components, e.g., focus, unmanaged text boxes, etc. -- Assertions do not operate on native view hierarchy +- Tests run on most CIs (Linux, etc) without a mobile device or emulator +- Faster test execution +- Light runtime environment + +Limitations: +- Tests don't execute native code +- Tests are unaware of view state managed by native components, e.g., focus, unmanaged text boxes, etc. +- Assertions don't 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. @@ -90,13 +88,13 @@ Not all React Native components are organized this way, e.g., when you use `Pres ### Host-only element tree -In RNTL v14, [Test Renderer](https://github.com/mdjastrzebski/test-renderer) only exposes host elements in the element tree. Composite components are not visible in the tree - you only see their host element output. This is an intentional design choice that aligns with Testing Library's philosophy: tests should focus on what users can see and interact with (host elements), not on implementation details (composite components). +In RNTL v14, [Test Renderer](https://github.com/mdjastrzebski/test-renderer) only exposes host elements in the element tree. Composite components aren't visible in the tree—you only see their host element output. This aligns with Testing Library's philosophy: tests should focus on what users can see and interact with (host elements), not implementation details (composite components). For a `HostElement`, the `type` prop is always a string value representing the host component name, e.g., `"View"`, `"Text"`, `"TextInput"`. ## Tree nodes -RNTL v14 queries and the element tree only expose host elements. This aligns with Testing Library's philosophy: tests should assert on what users can see and interact with. Host elements represent the actual UI controls that users interact with, while composite components exist purely in the JavaScript domain. +RNTL v14 queries and the element tree only expose host elements. Tests assert on what users can see and interact with. Host elements represent the actual UI controls users interact with, while composite components exist purely in the JavaScript domain. ### Understanding props diff --git a/website/docs/14.x/docs/advanced/understanding-act.mdx b/website/docs/14.x/docs/advanced/understanding-act.mdx index d67cfdfc..94c1f1e3 100644 --- a/website/docs/14.x/docs/advanced/understanding-act.mdx +++ b/website/docs/14.x/docs/advanced/understanding-act.mdx @@ -1,6 +1,6 @@ # Understanding `act` function -When writing RNTL tests one of the things that confuses developers the most are cryptic [`act()`](https://react.dev/link/wrap-tests-with-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, cryptic [`act()`](https://react.dev/link/wrap-tests-with-act) function errors logged to console often confuse developers. This article explains the purpose and behavior of `act()` so you can write tests with more confidence. ## `act` warning @@ -28,7 +28,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. +Let's demonstrate this with a small experiment. First, define a function component that uses `useEffect`: ```jsx function TestComponent() { @@ -57,7 +57,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 `act` wrapping the render call, the assertion runs just after rendering but before `useEffect` effects are applied. This isn't what we expected. ```jsx import { createRoot } from 'test-renderer'; @@ -99,7 +99,7 @@ Note that `act` calls can be safely nested and internally form a stack of calls. The `act` implementation is defined in the [ReactAct.js source file](https://github.com/facebook/react/blob/main/packages/react/src/ReactAct.js) inside React repository. RNTL v14 requires React 19+, which provides the `act` function directly via `React.act`. -RNTL exports `act` for convenience of the users as defined in the [act.ts source file](https://github.com/callstack/react-native-testing-library/blob/main/src/act.ts). In v14, `act` is now async by default and always returns a Promise, making it compatible with async React features like `Suspense` boundary or `use()` hook. The underlying implementation wraps React's `act` function to ensure consistent async behavior. +RNTL exports `act` for convenience as defined in the [act.ts source file](https://github.com/callstack/react-native-testing-library/blob/main/src/act.ts). In v14, `act` is async by default and always returns a Promise. This works with async React features like `Suspense` boundaries and the `use()` hook. The underlying implementation wraps React's `act` function to ensure consistent async behavior. **Important**: You should always use `act` exported from `@testing-library/react-native` rather than the one from `react`. The RNTL version automatically ensures async behavior, whereas using `React.act` directly could still trigger synchronous act behavior if used improperly, leading to subtle test issues. @@ -111,7 +111,7 @@ In v14, `act` is always async and returns a Promise. While the callback you pass When the callback passed to `act` contains asynchronous operations, the Promise returned by `act` will resolve only after those operations complete. -Lets look at a simple example with component using `setTimeout` call to simulate asynchronous behaviour: +Here's a simple example with a component using `setTimeout` to simulate asynchronous behavior: ```jsx function TestAsyncComponent() { @@ -139,7 +139,7 @@ If we test our component in a native way without handling its asynchronous behav ### Solution with fake timers -First solution is to use Jest's fake timers inside out tests: +Use Jest's fake timers: ```jsx test('render with fake timers', async () => { @@ -159,7 +159,7 @@ That way we can wrap `jest.runAllTimers()` call which triggers the `setTimeout` ### Solution with real timers -If we wanted to stick with real timers then things get a bit more complex. Let's start by applying a crude solution of opening async `act()` call for the expected duration of components updates: +With real timers, things get more complex. Start with a simple solution: wrap an async `act()` call for the expected duration of component updates: ```jsx test('render with real timers - sleep', async () => { @@ -174,7 +174,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. -Let's try more elegant solution using `waitFor` that will wait for our desired state: +A better solution uses `waitFor` to wait for the desired state: ```jsx test('render with real timers - waitFor', async () => { diff --git a/website/docs/14.x/docs/api/events/fire-event.mdx b/website/docs/14.x/docs/api/events/fire-event.mdx index 5399b683..af70cc37 100644 --- a/website/docs/14.x/docs/api/events/fire-event.mdx +++ b/website/docs/14.x/docs/api/events/fire-event.mdx @@ -3,8 +3,7 @@ ## `fireEvent` {#fire-event} :::note -For common events like `press` or `type` it's recommended to use [User Event API](/docs/api/events/user-event) as it offers -more realistic event simulation by emitting a sequence of events with proper event objects that mimic React Native runtime behavior. +For common events like `press` or `type`, use the [User Event API](/docs/api/events/user-event). It simulates events more realistically by emitting a sequence of events with proper event objects that mimic React Native runtime behavior. Use Fire Event for cases not supported by User Event and for triggering event handlers on composite components. ::: @@ -13,11 +12,11 @@ Use Fire Event for cases not supported by User Event and for triggering event ha function fireEvent(element: HostElement, eventName: string, ...data: unknown[]): Promise; ``` -The `fireEvent` API allows you to trigger all kinds of event handlers on both host and composite components. It will try to invoke a single event handler traversing the component tree bottom-up from passed element and trying to find enabled event handler named `onXxx` when `xxx` is the name of the event passed. +The `fireEvent` API triggers event handlers on both host and composite components. It traverses the component tree bottom-up from the passed element to find an enabled event handler named `onXxx` where `xxx` is the event name. Unlike User Event, this API does not automatically pass event object to event handler, this is responsibility of the user to construct such object. -This function uses async `act` function internally to ensure all pending React updates are executed during event handling. +This function uses async `act` internally to execute all pending React updates during event handling. ```jsx import { render, screen, fireEvent } from '@testing-library/react-native'; @@ -62,7 +61,7 @@ FireEvent exposes convenience methods for common events like: `press`, `changeTe ### `fireEvent.press` {#press} :::note -It is recommended to use the User Event [`press()`](/docs/api/events/user-event#press) helper instead as it offers more realistic simulation of press interaction, including pressable support. +Use the User Event [`press()`](/docs/api/events/user-event#press) helper instead. It simulates press interactions more realistically, including pressable support. ::: ```tsx @@ -101,7 +100,7 @@ expect(onPressMock).toHaveBeenCalledWith(eventData); ### `fireEvent.changeText` {#change-text} :::note -It is recommended to use the User Event [`type()`](/docs/api/events/user-event#type) helper instead as it offers more realistic simulation of text change interaction, including key-by-key typing, element focus, and other editing events. +Use the User Event [`type()`](/docs/api/events/user-event#type) helper instead. It simulates text change interactions more realistically, including key-by-key typing, element focus, and other editing events. ::: ```tsx @@ -132,7 +131,7 @@ await fireEvent.changeText(screen.getByPlaceholderText('Enter data'), CHANGE_TEX ### `fireEvent.scroll` {#scroll} :::note -Prefer using [`user.scrollTo`](/docs/api/events/user-event#scrollto) over `fireEvent.scroll` for `ScrollView`, `FlatList`, and `SectionList` components. User Event provides a more realistic event simulation based on React Native runtime behavior. +Prefer [`user.scrollTo`](/docs/api/events/user-event#scrollto) over `fireEvent.scroll` for `ScrollView`, `FlatList`, and `SectionList` components. User Event simulates events more realistically based on React Native runtime behavior. ::: ```tsx diff --git a/website/docs/14.x/docs/api/events/user-event.mdx b/website/docs/14.x/docs/api/events/user-event.mdx index 0baa3d64..db7a2584 100644 --- a/website/docs/14.x/docs/api/events/user-event.mdx +++ b/website/docs/14.x/docs/api/events/user-event.mdx @@ -6,7 +6,7 @@ Fire Event is our original event simulation API. It can invoke **any event handl 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. -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. It makes tests more realistic and reliable. When User Event doesn't support the event or you need to invoke event handlers on composite elements, use Fire Event. ## `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`. +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. It 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 similarly to regular `press` action, e.g., by emitting `pressIn` and `pressOut` events. The press duration is customizable through the options, which is useful when using 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. @@ -94,7 +94,7 @@ const user = userEvent.setup(); 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. +Simulates 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. @@ -154,7 +154,7 @@ const user = userEvent.setup(); await user.clear(textInput); ``` -This helper simulates the user clearing the content of a `TextInput` element. +Simulates clearing the content of a `TextInput` element. This function supports only host `TextInput` elements. Passing other element types will result in throwing an error. @@ -198,7 +198,7 @@ const user = userEvent.setup(); await user.paste(textInput, 'Text to paste'); ``` -This helper simulates the user pasting given text to a `TextInput` element. +Simulates pasting text into a `TextInput` element. This function supports only host `TextInput` elements. Passing other element types will result in throwing an error. @@ -252,7 +252,7 @@ const user = userEvent.setup(); await user.scrollTo(scrollView, { y: 100, momentumY: 200 }); ``` -This helper simulates the user scrolling a host `ScrollView` element. +Simulates 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. diff --git a/website/docs/14.x/docs/api/jest-matchers.mdx b/website/docs/14.x/docs/api/jest-matchers.mdx index 73978547..46b93d71 100644 --- a/website/docs/14.x/docs/api/jest-matchers.mdx +++ b/website/docs/14.x/docs/api/jest-matchers.mdx @@ -14,7 +14,7 @@ There is no need to set up the built-in matchers; they are automatically availab expect(element).toBeOnTheScreen(); ``` -This allows you to assert whether an element is attached to the element tree or not. If you hold a reference to an element and it gets unmounted during the test it will no longer pass this assertion. +Asserts whether an element is attached to the element tree. If you hold a reference to an element and it gets unmounted during the test, it will no longer pass this assertion. ## Element Content @@ -30,7 +30,7 @@ expect(element).toHaveTextContent( ) ``` -This allows you to assert whether the given element has the given text content or not. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Asserts whether the given element has the given text content. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. ### `toContainElement()` @@ -40,7 +40,7 @@ expect(container).toContainElement( ) ``` -This allows you to assert whether the given container element does contain another host element. +Asserts whether the given container element contains another host element. ### `toBeEmptyElement()` @@ -48,7 +48,7 @@ This allows you to assert whether the given container element does contain anoth expect(element).toBeEmptyElement(); ``` -This allows you to assert whether the given element does not have any host child elements or text content. +Asserts whether the given element has no host child elements or text content. ## Checking element state @@ -64,7 +64,7 @@ expect(element).toHaveDisplayValue( ) ``` -This allows you to assert whether the given `TextInput` element has a specified display value. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Asserts whether the given `TextInput` element has a specified display value. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. ### `toHaveAccessibilityValue()` @@ -79,7 +79,7 @@ expect(element).toHaveAccessibilityValue( ) ``` -This allows you to assert whether the given element has a specified accessible value. +Asserts whether the given element has a specified accessible value. This matcher will assert accessibility value based on `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext` and `accessibilityValue` props. Only defined value entries will be used in the assertion, the element might have additional accessibility value entries and still be matched. @@ -92,7 +92,7 @@ expect(element).toBeEnabled(); expect(element).toBeDisabled(); ``` -These allow you to assert whether the given element is enabled or disabled from the user's perspective. It relies on the accessibility disabled state as set by `aria-disabled` or `accessibilityState.disabled` props. It will consider a given element disabled when it or any of its ancestors is disabled. +Asserts whether the given element is enabled or disabled from the user's perspective. It relies on the accessibility disabled state as set by `aria-disabled` or `accessibilityState.disabled` props. It considers an element disabled when it or any of its ancestors is disabled. :::note These matchers are the negation of each other, and both are provided to avoid double negations in your assertions. @@ -104,7 +104,7 @@ These matchers are the negation of each other, and both are provided to avoid do expect(element).toBeSelected(); ``` -This allows you to assert whether the given element is selected from the user's perspective. It relies on the accessibility selected state as set by `aria-selected` or `accessibilityState.selected` props. +Asserts whether the given element is selected from the user's perspective. It relies on the accessibility selected state as set by `aria-selected` or `accessibilityState.selected` props. ### `toBeChecked()` / `toBePartiallyChecked()` {#tobechecked} @@ -113,7 +113,7 @@ expect(element).toBeChecked(); expect(element).toBePartiallyChecked(); ``` -These allow you to assert whether the given element is checked or partially checked from the user's perspective. It relies on the accessibility checked state as set by `aria-checked` or `accessibilityState.checked` props. +Asserts whether the given element is checked or partially checked from the user's perspective. It relies on the accessibility checked state as set by `aria-checked` or `accessibilityState.checked` props. :::note @@ -129,7 +129,7 @@ expect(element).toBeExpanded(); expect(element).toBeCollapsed(); ``` -These allow you to assert whether the given element is expanded or collapsed from the user's perspective. It relies on the accessibility expanded state as set by `aria-expanded` or `accessibilityState.expanded` props. +Asserts whether the given element is expanded or collapsed from the user's perspective. It relies 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). @@ -141,7 +141,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 busy state as set by `aria-busy` or `accessibilityState.busy` props. +Asserts 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 @@ -151,7 +151,7 @@ This allows you to assert whether the given element is busy from the user's pers expect(element).toBeVisible(); ``` -This allows you to assert whether the given element is visible from the user's perspective. +Asserts whether the given element is visible from the user's perspective. The element is considered invisible when itself or any of its ancestors has `display: none` or `opacity: 0` styles, as well as when it's hidden from accessibility. @@ -163,7 +163,7 @@ expect(element).toHaveStyle( ) ``` -This allows you to assert whether the given element has given styles. +Asserts whether the given element has given styles. ## Other matchers @@ -179,7 +179,7 @@ expect(element).toHaveAccessibleName( ) ``` -This allows you to assert whether the given element has a specified accessible name. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Asserts whether the given element has a specified accessible name. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. The accessible name will be computed based on `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props. For `Image` elements, the `alt` prop will also be considered. In the absence of these props, the element text content will be used. @@ -194,7 +194,7 @@ expect(element).toHaveProp( ) ``` -This allows you to assert whether the given element has a given prop. When the `value` parameter is `undefined` it will only check for existence of the prop, and when `value` is defined it will check if the actual value matches passed value. +Asserts whether the given element has a given prop. When the `value` parameter is `undefined`, it only checks for prop existence. When `value` is defined, it checks if the actual value matches the passed value. :::note This matcher should be treated as an escape hatch to be used when all other matchers are not suitable. diff --git a/website/docs/14.x/docs/api/misc/async.mdx b/website/docs/14.x/docs/api/misc/async.mdx index 1992311a..be9d005d 100644 --- a/website/docs/14.x/docs/api/misc/async.mdx +++ b/website/docs/14.x/docs/api/misc/async.mdx @@ -17,13 +17,13 @@ function waitFor( ): Promise; ``` -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` runs the callback multiple 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, is treated as meeting the expectation, and the callback result is returned to the caller. ```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: 50 ms) until `timeout` (default: 1000 ms) is reached. Execution stops as soon as the callback doesn't throw an error, and the callback's return value is returned to the caller. If timeout is reached, `waitFor` re-throws the final error thrown by `expectation`. ```tsx // ❌ `waitFor` will return immediately because callback does not throw @@ -41,7 +41,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` runs the `expectation` callback multiple times, [avoid performing side effects](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#performing-side-effects-in-waitfor) in `waitFor`. ```jsx await waitFor(async () => { @@ -55,7 +55,7 @@ await waitFor(async () => { 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. +Use a [single assertion per `waitFor`](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#having-multiple-assertions-in-a-single-waitfor-callback) for consistency and faster failing tests. For multiple assertions, use separate `waitFor` calls. Often you won't need to wrap the second assertion in `waitFor` since the first one waits for the asynchronous change. `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: @@ -78,7 +78,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. With fake timers, the test doesn't depend on real time passing, making it faster and more reliable. We don't need to advance fake timers through Jest's API because `waitFor` handles this. ```tsx // in component diff --git a/website/docs/14.x/docs/api/misc/other.mdx b/website/docs/14.x/docs/api/misc/other.mdx index f9868a32..c76a1452 100644 --- a/website/docs/14.x/docs/api/misc/other.mdx +++ b/website/docs/14.x/docs/api/misc/other.mdx @@ -33,7 +33,7 @@ function act(callback: () => T | Promise): Promise; Wraps code that causes React state updates to ensure all updates are processed before assertions. By default any `render`, `rerender`, `fireEvent`, and `waitFor` calls are wrapped by this function, so there is no need to wrap it manually. -**In v14, `act` is now async by default and always returns a Promise**, making it compatible with async React features like `Suspense` boundary or `use()` hook. This ensures all pending React updates are executed before the Promise resolves. +**In v14, `act` is now async by default and always returns a Promise**. This works with async React features like `Suspense` boundaries and the `use()` hook. All pending React updates are executed before the Promise resolves. ```ts import { act } from '@testing-library/react-native'; diff --git a/website/docs/14.x/docs/api/queries.mdx b/website/docs/14.x/docs/api/queries.mdx index 5152dad9..22cf5bc4 100644 --- a/website/docs/14.x/docs/api/queries.mdx +++ b/website/docs/14.x/docs/api/queries.mdx @@ -18,7 +18,7 @@ test('accessing queries using "screen" object', async () => { }) ``` -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. +Use the `screen` object exported by `@testing-library/react-native` to access queries. This object contains all available query methods bound to the most recently rendered UI. ### Using `render` result @@ -31,7 +31,7 @@ test('accessing queries using "render" result', async () => { }) ``` -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. +You can also capture query functions from the `render` function return value. This provides the same query functions as the `screen` object. ## Query parts @@ -82,7 +82,7 @@ getAllByX(...): HostElement[] queryByX(...): HostElement | 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, or `null` if no elements match. Use these to assert that an element is not present. They throw if more than one match is found (use `queryAllBy` instead). ### `queryAllBy*` queries {#query-all-by} @@ -375,7 +375,7 @@ 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). +Following [the guiding principles](https://testing-library.com/docs/guiding-principles), use this only when other queries don't work for your use case. `testID` attributes don't resemble how your software is used and should be avoided when possible. They're useful for end-to-end testing on real devices, e.g. with Detox. 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 diff --git a/website/docs/14.x/docs/api/screen.mdx b/website/docs/14.x/docs/api/screen.mdx index 8b43045f..2d5ac29e 100644 --- a/website/docs/14.x/docs/api/screen.mdx +++ b/website/docs/14.x/docs/api/screen.mdx @@ -12,13 +12,13 @@ let screen: { }; ``` -The `screen` object offers a recommended way to access queries and utilities for the currently rendered UI. +The `screen` object provides access to queries and utilities for the currently rendered UI. This object is assigned after the `render` call and cleared after each test by calling [`cleanup`](/docs/api/misc/other#cleanup). If no `render` call has been made in a given test, then it holds a special object and throws a helpful error on each property and method access. ### `...queries` -The most important feature of `screen` is providing a set of helpful queries that allow you to find certain elements in the view hierarchy. +The main feature of `screen` is its queries for finding elements in the view hierarchy. See [Queries](/docs/api/queries) for a complete list. @@ -41,7 +41,7 @@ function rerender(element: React.Element): Promise; 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. -This method is async and uses async `act` function internally to ensure all pending React updates are executed during updating, making it compatible with async React features like `Suspense` boundary or `use()` hook. +This method is async and uses async `act` internally to execute all pending React updates during updating. This works with async React features like `Suspense` boundaries and the `use()` hook. ```jsx import { render, screen } from '@testing-library/react-native'; @@ -62,7 +62,7 @@ function unmount(): Promise; Unmount the in-memory tree, triggering the appropriate lifecycle events. -This method is async and uses async `act` function internally to ensure all pending React updates are executed during unmounting, making it compatible with async React features like `Suspense` boundary or `use()` hook. +This method is async and uses async `act` internally to execute all pending React updates during unmounting. This works with async React features like `Suspense` boundaries and the `use()` hook. :::note @@ -150,7 +150,7 @@ const container: HostElement; Returns a pseudo-element container whose children are the elements you asked to render. This is the root container element from [Test Renderer](https://github.com/mdjastrzebski/test-renderer). -The `container` is safe to use and provides access to the entire rendered tree. It's useful when you need to query or manipulate the entire rendered output, similar to how `container` works in [React Testing Library](https://testing-library.com/docs/react-testing-library/other#container-1). +The `container` provides access to the entire rendered tree. Use it to query or manipulate the rendered output, similar to how `container` works in [React Testing Library](https://testing-library.com/docs/react-testing-library/other#container-1). ```jsx import { render, screen } from '@testing-library/react-native'; @@ -171,7 +171,7 @@ const root: HostElement | null; Returns the rendered root [host element](/docs/advanced/testing-env#host-and-composite-components), or `null` if nothing was rendered. This is the first child of the `container`, which represents the actual root element you rendered. -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 useful for component tests where you need to access the root host view without using `*ByTestId` queries or similar methods. :::note diff --git a/website/docs/14.x/docs/guides/faq.mdx b/website/docs/14.x/docs/guides/faq.mdx index 33ff4834..d489e3de 100644 --- a/website/docs/14.x/docs/guides/faq.mdx +++ b/website/docs/14.x/docs/guides/faq.mdx @@ -13,27 +13,27 @@ and event APIs ([User Event](/docs/api/events/user-event), [Fire Event](/docs/ap You can learn more about our testing environment [here](/docs/advanced/testing-env). -This approach has specific benefits and shortfalls. On the positive side: +This approach has benefits and limitations: -- it allows testing most of the logic of regular React Native apps -- it allows running tests on any OS supported by Jest or other test runners, e.g., on CI -- it uses much less resources than full runtime simulation -- you can use Jest fake timers +Benefits: +- Tests most of the logic of regular React Native apps +- Runs tests on any OS supported by Jest or other test runners, e.g., on CI +- Uses fewer resources than full runtime simulation +- Works with Jest fake timers -On the negative side: +Limitations: +- Cannot test native features +- May not perfectly simulate certain JavaScript features, but we're working on it -- you cannot test native features -- it might not perfectly simulate certain JavaScript features, but we are working on it - -The [User Event interactions](/docs/api/events/user-event) solve some of the simulation issues, as they offer more realistic event handling than the basic [Fire Event API](/docs/api/events/fire-event). +The [User Event interactions](/docs/api/events/user-event) solve some simulation issues by handling events more realistically than the basic [Fire Event API](/docs/api/events/fire-event). ## Should I use/migrate to `screen` queries? There is no need to migrate existing test code to use `screen`-bases queries. You can still use queries and other functions returned by `render`. The `screen` object captures the latest `render` result. -For new code, you are encouraged to use `screen` as there are some good reasons for that, which are described in [this article](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen) by Kent C. Dodds. +For new code, use `screen`. [This article](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen) by Kent C. Dodds explains why. ## 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. +Migrate existing tests to use the [User Event interactions](/docs/api/events/user-event), which handle events more realistically than the basic [Fire Event API](/docs/api/events/fire-event). This provides more confidence in your code quality. diff --git a/website/docs/14.x/docs/guides/how-to-query.mdx b/website/docs/14.x/docs/guides/how-to-query.mdx index 73a347d8..1077cba4 100644 --- a/website/docs/14.x/docs/guides/how-to-query.mdx +++ b/website/docs/14.x/docs/guides/how-to-query.mdx @@ -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 tests. The number of queries can be confusing. This guide helps you pick the right queries for your test scenarios. ## Query parts @@ -58,13 +58,13 @@ 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 test 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 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: +Use query predicates in the following order of priority: ### 1. By Role query {#by-role-query} -The first and most versatile predicate is [`*ByRole`](/docs/api/queries#by-role), which starts with the semantic role of the element and can be further narrowed down with additional options. React Native has two role systems, the web/ARIA-compatible one based on [`role`](https://reactnative.dev/docs/accessibility#role) prop and the traditional one based on [`accessibilityRole`](https://reactnative.dev/docs/accessibility#accessibilityrole) prop, you can use either of these. +The [`*ByRole`](/docs/api/queries#by-role) predicate starts with the semantic role of the element and can be narrowed down with additional options. React Native has two role systems: the web/ARIA-compatible one based on [`role`](https://reactnative.dev/docs/accessibility#role) prop and the traditional one based on [`accessibilityRole`](https://reactnative.dev/docs/accessibility#accessibilityrole) prop. You can use either. In most cases, you need to set accessibility roles explicitly (or your component library can set some of them for you). These roles allow assistive technologies (like screen readers) and testing code to understand your view hierarchy better. @@ -122,4 +122,4 @@ These queries include: As a final predicate, you can use the `testID` prop to find relevant views. Using the [`*ByTestId`](/docs/api/queries#by-test-id) predicate offers the most flexibility, but at the same time, it does not represent the user experience, as users are not aware of test IDs. -Note that using test IDs is a widespread technique in end-to-end testing due to various issues with querying views through other means **in its specific context**. Nevertheless, we still encourage you to use recommended RNTL queries as it will make your integration and component test more reliable and resilient. +Note that using test IDs is common in end-to-end testing due to various issues with querying views through other means **in that specific context**. For integration and component tests, use the recommended RNTL queries to make tests more reliable and resilient. diff --git a/website/docs/14.x/docs/guides/troubleshooting.mdx b/website/docs/14.x/docs/guides/troubleshooting.mdx index c1aedd05..8278a383 100644 --- a/website/docs/14.x/docs/guides/troubleshooting.mdx +++ b/website/docs/14.x/docs/guides/troubleshooting.mdx @@ -4,9 +4,9 @@ This guide describes common issues found by users when integrating React Native ## Example repository -We maintain an [example repository](https://github.com/callstack/react-native-testing-library/tree/main/examples/basic) that showcases a modern React Native Testing Library setup with TypeScript, etc. +We maintain an [example repository](https://github.com/callstack/react-native-testing-library/tree/main/examples/basic) with a React Native Testing Library setup using TypeScript. -In case something does not work in your setup you can refer to this repository for recommended configuration. +If something doesn't work in your setup, check this repository for configuration examples. ## Undefined component error @@ -24,7 +24,7 @@ jest.mock('@react-navigation/native', () => { The above mock will mock `useNavigation` hook as intended, but at the same time all other exports from `@react-navigation/native` package are now `undefined`. If you want to use `NavigationContainer` component from the same package it will be `undefined` and result in the error above. -In order to mock only a part of given package you should re-export all other exports using `jest.requireActual` helper: +To mock only part of a package, re-export all other exports using `jest.requireActual`: ```ts jest.mock('@react-navigation/native', () => { @@ -41,7 +41,7 @@ Alternatively, you can use `jest.spyOn` to mock package exports selectively. ### Mocking React Native -In case of mocking `react-native` package you should not mock the whole package at once, as this approach has issues with `jest.requireActual` call. In this case it is recommended to mock particular library paths inside the package, e.g.: +When mocking the `react-native` package, don't mock the whole package at once, as this has issues with `jest.requireActual`. Mock specific library paths inside the package instead, e.g.: ```ts title=jest-setup.ts jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter'); diff --git a/website/docs/14.x/docs/start/quick-start.mdx b/website/docs/14.x/docs/start/quick-start.mdx index aa4c4770..0c3a4bb7 100644 --- a/website/docs/14.x/docs/start/quick-start.mdx +++ b/website/docs/14.x/docs/start/quick-start.mdx @@ -32,7 +32,7 @@ This library has a peer dependency on [Test Renderer](https://github.com/mdjastr }} /> -Test Renderer provides better compatibility with React 19 and improved type safety compared to the deprecated [React Test Renderer](https://reactjs.org/docs/test-renderer.html). +Test Renderer has better compatibility with React 19 and improved type safety compared to the deprecated [React Test Renderer](https://reactjs.org/docs/test-renderer.html). ### Jest matchers @@ -40,7 +40,7 @@ RNTL automatically extends Jest with React Native-specific matchers. The only th ### ESLint plugin -We recommend setting up [`eslint-plugin-testing-library`](https://github.com/testing-library/eslint-plugin-testing-library) package to help you avoid common Testing Library mistakes and bad practices. +Set up [`eslint-plugin-testing-library`](https://github.com/testing-library/eslint-plugin-testing-library) to avoid common Testing Library mistakes and bad practices. Install the plugin (assuming you already have `eslint` installed & configured): @@ -53,7 +53,7 @@ Install the plugin (assuming you already have `eslint` installed & configured): }} /> -Then, add relevant entry to your ESLint config (e.g., `.eslintrc.js`). We recommend extending the `react` plugin: +Then, add this to your ESLint config (e.g., `.eslintrc.js`). Extend the `react` plugin: ```js title=.eslintrc.js module.exports = { From 2e338c9fa075a621d0a19f44203298b3a8a73536 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 22:44:09 +0100 Subject: [PATCH 05/11] update docs base URL --- README-v13.md | 34 ++++++++++++------------ README.md | 32 +++++++++++------------ package.json | 5 ++-- src/matchers/types.ts | 36 +++++++++++++------------- src/queries/__tests__/find-by.test.tsx | 2 +- src/queries/make-queries.ts | 2 +- website/rspress.config.ts | 2 +- 7 files changed, 57 insertions(+), 56 deletions(-) diff --git a/README-v13.md b/README-v13.md index d4c633bc..f6b0708f 100644 --- a/README-v13.md +++ b/README-v13.md @@ -81,33 +81,33 @@ You can find the source of `QuestionsBoard` component and this example [here](ht React Native Testing Library consists of following APIs: -- [`render` function](https://callstack.github.io/react-native-testing-library/docs/api/render) - render your UI components for testing purposes -- [`screen` object](https://callstack.github.io/react-native-testing-library/docs/api/screen) - access rendered UI: - - [Queries](https://callstack.github.io/react-native-testing-library/docs/api/queries) - find rendered components by various predicates: role, text, test ids, etc - - Lifecycle methods: [`rerender`](https://callstack.github.io/react-native-testing-library/docs/api/screen#rerender), [`unmount`](https://callstack.github.io/react-native-testing-library/docs/api/screen#unmount) - - Helpers: [`debug`](https://callstack.github.io/react-native-testing-library/docs/api/screen#debug), [`toJSON`](https://callstack.github.io/react-native-testing-library/docs/api/screen#tojson), [`root`](https://callstack.github.io/react-native-testing-library/docs/api/screen#root) -- [Jest matchers](https://callstack.github.io/react-native-testing-library/docs/api/jest-matchers) - validate assumptions about your UI -- [User Event](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#type) -- [Fire Event](https://callstack.github.io/react-native-testing-library/docs/api/events/fire-event) - simulate any component event -- [`renderHook` function](https://callstack.github.io/react-native-testing-library/docs/api/misc/render-hook) - render hooks for testing purposes +- [`render` function](https://oss.callstack.com/react-native-testing-library/docs/api/render) - render your UI components for testing purposes +- [`screen` object](https://oss.callstack.com/react-native-testing-library/docs/api/screen) - access rendered UI: + - [Queries](https://oss.callstack.com/react-native-testing-library/docs/api/queries) - find rendered components by various predicates: role, text, test ids, etc + - Lifecycle methods: [`rerender`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#rerender), [`unmount`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#unmount) + - Helpers: [`debug`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#debug), [`toJSON`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#tojson), [`root`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#root) +- [Jest matchers](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers) - validate assumptions about your UI +- [User Event](https://oss.callstack.com/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://oss.callstack.com/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://oss.callstack.com/react-native-testing-library/docs/api/events/user-event#type) +- [Fire Event](https://oss.callstack.com/react-native-testing-library/docs/api/events/fire-event) - simulate any component event +- [`renderHook` function](https://oss.callstack.com/react-native-testing-library/docs/api/misc/render-hook) - render hooks for testing purposes - Miscellaneous APIs: - - [Async utils](https://callstack.github.io/react-native-testing-library/docs/api/misc/async): `findBy*` queries, `waitFor`, `waitForElementToBeRemoved` - - [Configuration](https://callstack.github.io/react-native-testing-library/docs/api/misc/config): `configure`, `resetToDefaults` - - [Accessibility](https://callstack.github.io/react-native-testing-library/docs/api/misc/accessibility): `isHiddenFromAccessibility` - - [Other](https://callstack.github.io/react-native-testing-library/docs/api/misc/other): `within`, `act`, `cleanup` + - [Async utils](https://oss.callstack.com/react-native-testing-library/docs/api/misc/async): `findBy*` queries, `waitFor`, `waitForElementToBeRemoved` + - [Configuration](https://oss.callstack.com/react-native-testing-library/docs/api/misc/config): `configure`, `resetToDefaults` + - [Accessibility](https://oss.callstack.com/react-native-testing-library/docs/api/misc/accessibility): `isHiddenFromAccessibility` + - [Other](https://oss.callstack.com/react-native-testing-library/docs/api/misc/other): `within`, `act`, `cleanup` ## Migration Guides -- [Migration to 13.0](https://callstack.github.io/react-native-testing-library/docs/migration/v13) -- [Migration to built-in Jest Matchers](https://callstack.github.io/react-native-testing-library/docs/migration/jest-matchers) +- [Migration to 13.0](https://oss.callstack.com/react-native-testing-library/docs/migration/v13) +- [Migration to built-in Jest Matchers](https://oss.callstack.com/react-native-testing-library/docs/migration/jest-matchers) ## Troubleshooting -- [Troubleshooting guide](https://callstack.github.io/react-native-testing-library/docs/guides/troubleshooting) +- [Troubleshooting guide](https://oss.callstack.com/react-native-testing-library/docs/guides/troubleshooting) ## Community Resources -Check out our list of [Community Resources about RNTL](https://callstack.github.io/react-native-testing-library/docs/guides/community-resources). +Check out our list of [Community Resources about RNTL](https://oss.callstack.com/react-native-testing-library/docs/guides/community-resources). ## Made with ❤️ at Callstack diff --git a/README.md b/README.md index 86d9631a..a3fb05ea 100644 --- a/README.md +++ b/README.md @@ -82,32 +82,32 @@ You can find the source of `QuestionsBoard` component and this example [here](ht React Native Testing Library consists of following APIs: -- [`render` function](https://callstack.github.io/react-native-testing-library/docs/api/render) - render your UI components for testing purposes -- [`screen` object](https://callstack.github.io/react-native-testing-library/docs/api/screen) - access rendered UI: - - [Queries](https://callstack.github.io/react-native-testing-library/docs/api/queries) - find rendered components by various predicates: role, text, test ids, etc - - Lifecycle methods: [`rerender`](https://callstack.github.io/react-native-testing-library/docs/api/screen#rerender), [`unmount`](https://callstack.github.io/react-native-testing-library/docs/api/screen#unmount) - - Helpers: [`debug`](https://callstack.github.io/react-native-testing-library/docs/api/screen#debug), [`toJSON`](https://callstack.github.io/react-native-testing-library/docs/api/screen#tojson), [`root`](https://callstack.github.io/react-native-testing-library/docs/api/screen#root), [`container`](https://callstack.github.io/react-native-testing-library/docs/api/screen#container) -- [Jest matchers](https://callstack.github.io/react-native-testing-library/docs/api/jest-matchers) - validate assumptions about your UI -- [User Event](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://callstack.github.io/react-native-testing-library/docs/api/events/user-event#type) -- [Fire Event](https://callstack.github.io/react-native-testing-library/docs/api/events/fire-event) - simulate any component event -- [`renderHook` function](https://callstack.github.io/react-native-testing-library/docs/api/misc/render-hook) - render hooks for testing purposes +- [`render` function](https://oss.callstack.com/react-native-testing-library/docs/api/render) - render your UI components for testing purposes +- [`screen` object](https://oss.callstack.com/react-native-testing-library/docs/api/screen) - access rendered UI: + - [Queries](https://oss.callstack.com/react-native-testing-library/docs/api/queries) - find rendered components by various predicates: role, text, test ids, etc + - Lifecycle methods: [`rerender`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#rerender), [`unmount`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#unmount) + - Helpers: [`debug`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#debug), [`toJSON`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#tojson), [`root`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#root), [`container`](https://oss.callstack.com/react-native-testing-library/docs/api/screen#container) +- [Jest matchers](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers) - validate assumptions about your UI +- [User Event](https://oss.callstack.com/react-native-testing-library/docs/api/events/user-event) - simulate common user interactions like [`press`](https://oss.callstack.com/react-native-testing-library/docs/api/events/user-event#press) or [`type`](https://oss.callstack.com/react-native-testing-library/docs/api/events/user-event#type) +- [Fire Event](https://oss.callstack.com/react-native-testing-library/docs/api/events/fire-event) - simulate any component event +- [`renderHook` function](https://oss.callstack.com/react-native-testing-library/docs/api/misc/render-hook) - render hooks for testing purposes - Miscellaneous APIs: - - [Async utils](https://callstack.github.io/react-native-testing-library/docs/api/misc/async): `findBy*` queries, `waitFor`, `waitForElementToBeRemoved` - - [Configuration](https://callstack.github.io/react-native-testing-library/docs/api/misc/config): `configure`, `resetToDefaults` - - [Accessibility](https://callstack.github.io/react-native-testing-library/docs/api/misc/accessibility): `isHiddenFromAccessibility` - - [Other](https://callstack.github.io/react-native-testing-library/docs/api/misc/other): `within`, `act`, `cleanup` + - [Async utils](https://oss.callstack.com/react-native-testing-library/docs/api/misc/async): `findBy*` queries, `waitFor`, `waitForElementToBeRemoved` + - [Configuration](https://oss.callstack.com/react-native-testing-library/docs/api/misc/config): `configure`, `resetToDefaults` + - [Accessibility](https://oss.callstack.com/react-native-testing-library/docs/api/misc/accessibility): `isHiddenFromAccessibility` + - [Other](https://oss.callstack.com/react-native-testing-library/docs/api/misc/other): `within`, `act`, `cleanup` ## Migration Guides -- **[Migration to 14.0](https://callstack.github.io/react-native-testing-library/docs/migration/v14)** - Drops React 18, async APIs by default +- **[Migration to 14.0](https://oss.callstack.com/react-native-testing-library/docs/migration/v14)** - Drops React 18, async APIs by default ## Troubleshooting -- [Troubleshooting guide](https://callstack.github.io/react-native-testing-library/docs/guides/troubleshooting) +- [Troubleshooting guide](https://oss.callstack.com/react-native-testing-library/docs/guides/troubleshooting) ## Community Resources -Check out our list of [Community Resources about RNTL](https://callstack.github.io/react-native-testing-library/docs/guides/community-resources). +Check out our list of [Community Resources about RNTL](https://oss.callstack.com/react-native-testing-library/docs/guides/community-resources). ## Made with ❤️ at Callstack diff --git a/package.json b/package.json index 34babcb7..7af0281b 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "type": "git", "url": "https://www.github.com/callstack/react-native-testing-library.git" }, - "homepage": "https://callstack.github.io/react-native-testing-library", + "homepage": "https://oss.callstack.com/react-native-testing-library", "author": "Michał Pierzchała (https://github.com/thymikee), Maciej Jastrzębski (https://github.com/mdjastrzebski)", "contributors": [ "Augustin Le Fèvre (https://github.com/AugustinLF)", @@ -39,7 +39,8 @@ "build": "yarn clean && yarn build:js && yarn build:ts", "release": "release-it", "release:rc": "release-it --preRelease=rc", - "release:beta": "release-it --preRelease=beta" + "release:beta": "release-it --preRelease=beta", + "release:codemods": "release-it --preRelease=alpha" }, "files": [ "build/", diff --git a/src/matchers/types.ts b/src/matchers/types.ts index d8241a93..2eaa7e16 100644 --- a/src/matchers/types.ts +++ b/src/matchers/types.ts @@ -10,7 +10,7 @@ export interface JestNativeMatchers { * Assert whether a host element is present in the element tree (screen) or not. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobeonthescreen) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobeonthescreen) * * @example * Hello @@ -24,7 +24,7 @@ export interface JestNativeMatchers { * Assert whether a host element is checked based on accessibility props. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobechecked) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobechecked) * * @see {@link toBePartiallyChecked} for a related matcher. * @@ -39,7 +39,7 @@ export interface JestNativeMatchers { * Assert whether a host element is collapsed based on accessibility props. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobeexpanded) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobeexpanded) * * @see {@link toBeExpanded} for an inverse matcher. * @@ -56,7 +56,7 @@ export interface JestNativeMatchers { * This matcher will check ancestor elements for their disabled state as well. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobeenabled) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobeenabled) * * @see {@link toBeEnabled} for an inverse matcher. * @@ -74,7 +74,7 @@ export interface JestNativeMatchers { * This matcher will check ancestor elements for their disabled state as well. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobebusy) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobebusy) * * @example * @@ -87,7 +87,7 @@ export interface JestNativeMatchers { * Assert whether a host element has no host children or text content. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobeemptyelement) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobeemptyelement) * * @example * @@ -105,7 +105,7 @@ export interface JestNativeMatchers { * This matcher will check ancestor elements for their disabled state as well. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobeenabled) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobeenabled) * * @see {@link toBeDisabled} for inverse matcher. * @@ -120,7 +120,7 @@ export interface JestNativeMatchers { * Assert whether a host element is expanded based on accessibility props. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobeexpanded) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobeexpanded) * * @see {@link toBeCollapsed} for inverse matcher. * @@ -135,7 +135,7 @@ export interface JestNativeMatchers { * Assert whether a host element is partially checked based on accessibility props. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobechecked) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobechecked) * * @see {@link toBeChecked} for related matcher. * @@ -150,7 +150,7 @@ export interface JestNativeMatchers { * Assert whether a host element is selected based on accessibility props. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobeselected) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobeselected) * * @example * @@ -165,7 +165,7 @@ export interface JestNativeMatchers { * This matcher will check ancestor elements for their visibility as well. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tobevisible) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tobevisible) * * @example * @@ -180,7 +180,7 @@ export interface JestNativeMatchers { * Assert whether a host element contains another host element. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tocontainelement) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tocontainelement) * * @example * @@ -195,7 +195,7 @@ export interface JestNativeMatchers { * Assert whether a host element has a given accessbility value. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tohaveaccessibilityvalue) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tohaveaccessibilityvalue) * * * @example @@ -209,7 +209,7 @@ export interface JestNativeMatchers { * Assert whether a host element has a given accessibile name based on the accessibility label or text content. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tohaveaccessiblename) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tohaveaccessiblename) * * @example * @@ -222,7 +222,7 @@ export interface JestNativeMatchers { * Assert whether a host `TextInput` element has a given display value based on `value` prop, unmanaged native state, and `defaultValue` prop. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tohavedisplayvalue) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tohavedisplayvalue) * * @example * @@ -235,7 +235,7 @@ export interface JestNativeMatchers { * Assert whether a host element has a given prop. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tohaveprop) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tohaveprop) * * @example * @@ -249,7 +249,7 @@ export interface JestNativeMatchers { * Assert whether a host element has a given style. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tohavestyle) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tohavestyle) * * @example * @@ -263,7 +263,7 @@ export interface JestNativeMatchers { * Assert whether a host element has a given text content. * * @see - * [Jest Matchers docs](https://callstack.github.io/react-native-testing-library/docs/jest-matchers#tohavetextcontent) + * [Jest Matchers docs](https://oss.callstack.com/react-native-testing-library/docs/api/jest-matchers#tohavetextcontent) * * @example * diff --git a/src/queries/__tests__/find-by.test.tsx b/src/queries/__tests__/find-by.test.tsx index e5e86b27..c25845f0 100644 --- a/src/queries/__tests__/find-by.test.tsx +++ b/src/queries/__tests__/find-by.test.tsx @@ -18,6 +18,6 @@ test('findByTestId detects screen being detached', async () => { Screen is no longer attached. Check your test for "findBy*" or "waitFor" calls that have not been awaited. We recommend enabling "eslint-plugin-testing-library" to catch these issues at build time: - https://callstack.github.io/react-native-testing-library/docs/start/quick-start#eslint-plugin" + https://oss.callstack.com/react-native-testing-library/docs/start/quick-start#eslint-plugin" `); }); diff --git a/src/queries/make-queries.ts b/src/queries/make-queries.ts index 7e0daf1b..c1e01bc6 100644 --- a/src/queries/make-queries.ts +++ b/src/queries/make-queries.ts @@ -88,7 +88,7 @@ function formatErrorMessage(message: string, printElementTree: boolean) { } if (screen.isDetached) { - return `${message}\n\nScreen is no longer attached. Check your test for "findBy*" or "waitFor" calls that have not been awaited.\n\nWe recommend enabling "eslint-plugin-testing-library" to catch these issues at build time:\nhttps://callstack.github.io/react-native-testing-library/docs/start/quick-start#eslint-plugin`; + return `${message}\n\nScreen is no longer attached. Check your test for "findBy*" or "waitFor" calls that have not been awaited.\n\nWe recommend enabling "eslint-plugin-testing-library" to catch these issues at build time:\nhttps://oss.callstack.com/react-native-testing-library/docs/start/quick-start#eslint-plugin`; } const json = screen.toJSON(); diff --git a/website/rspress.config.ts b/website/rspress.config.ts index 37c1a10d..b8a2381d 100644 --- a/website/rspress.config.ts +++ b/website/rspress.config.ts @@ -417,7 +417,7 @@ export default defineConfig({ pluginOpenGraph({ title: 'React Native Testing Library', type: 'website', - url: 'https://callstack.github.io/react-native-testing-library/', + url: 'https://oss.callstack.com/react-native-testing-library/', description: 'Helps you to write better tests with less effort.', }), ], From b4bca769390e42083b790ff529c461f464a0003b Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 22:45:07 +0100 Subject: [PATCH 06/11] jest matchers --- website/docs/14.x/docs/api/jest-matchers.mdx | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/website/docs/14.x/docs/api/jest-matchers.mdx b/website/docs/14.x/docs/api/jest-matchers.mdx index 46b93d71..4553f247 100644 --- a/website/docs/14.x/docs/api/jest-matchers.mdx +++ b/website/docs/14.x/docs/api/jest-matchers.mdx @@ -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 covers the built-in Jest matchers. These matchers make your tests easier to read and work better with accessibility features. ## Setup @@ -14,7 +14,7 @@ There is no need to set up the built-in matchers; they are automatically availab expect(element).toBeOnTheScreen(); ``` -Asserts whether an element is attached to the element tree. If you hold a reference to an element and it gets unmounted during the test, it will no longer pass this assertion. +Checks if an element is attached to the element tree. If you have a reference to an element and it gets unmounted during the test, this assertion will fail. ## Element Content @@ -30,7 +30,7 @@ expect(element).toHaveTextContent( ) ``` -Asserts whether the given element has the given text content. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if an element has the specified text content. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. ### `toContainElement()` @@ -40,7 +40,7 @@ expect(container).toContainElement( ) ``` -Asserts whether the given container element contains another host element. +Checks if a container element contains another host element. ### `toBeEmptyElement()` @@ -48,7 +48,7 @@ Asserts whether the given container element contains another host element. expect(element).toBeEmptyElement(); ``` -Asserts whether the given element has no host child elements or text content. +Checks if an element has no host child elements or text content. ## Checking element state @@ -64,7 +64,7 @@ expect(element).toHaveDisplayValue( ) ``` -Asserts whether the given `TextInput` element has a specified display value. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if a `TextInput` element has the specified display value. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. ### `toHaveAccessibilityValue()` @@ -79,11 +79,11 @@ expect(element).toHaveAccessibilityValue( ) ``` -Asserts whether the given element has a specified accessible value. +Checks if an element has the specified accessible value. -This matcher will assert accessibility value based on `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext` and `accessibilityValue` props. Only defined value entries will be used in the assertion, the element might have additional accessibility value entries and still be matched. +The matcher checks accessibility values from `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext`, and `accessibilityValue` props. It only checks the values you specify—the element can have other accessibility value entries and still match. -When querying by `text` entry a string or `RegExp` might be used. +For the `text` entry, you can use a string or `RegExp`. ### `toBeEnabled()` / `toBeDisabled` {#tobeenabled} @@ -92,10 +92,10 @@ expect(element).toBeEnabled(); expect(element).toBeDisabled(); ``` -Asserts whether the given element is enabled or disabled from the user's perspective. It relies on the accessibility disabled state as set by `aria-disabled` or `accessibilityState.disabled` props. It considers an element disabled when it or any of its ancestors is disabled. +Checks if an element is enabled or disabled. Uses the accessibility disabled state from `aria-disabled` or `accessibilityState.disabled` props. An element is considered disabled if it or any of its ancestors is disabled. :::note -These matchers are the negation of each other, and both are provided to avoid double negations in your assertions. +These matchers are opposites. Both are available so you can avoid double negations like `expect(element).not.toBeDisabled()`. ::: ### `toBeSelected()` @@ -104,7 +104,7 @@ These matchers are the negation of each other, and both are provided to avoid do expect(element).toBeSelected(); ``` -Asserts whether the given element is selected from the user's perspective. It relies on the accessibility selected state as set by `aria-selected` or `accessibilityState.selected` props. +Checks if an element is selected. Uses the accessibility selected state from `aria-selected` or `accessibilityState.selected` props. ### `toBeChecked()` / `toBePartiallyChecked()` {#tobechecked} @@ -113,12 +113,12 @@ expect(element).toBeChecked(); expect(element).toBePartiallyChecked(); ``` -Asserts whether the given element is checked or partially checked from the user's perspective. It relies on the accessibility checked state as set by `aria-checked` or `accessibilityState.checked` props. +Checks if an element is checked or partially checked. Uses the accessibility checked state from `aria-checked` or `accessibilityState.checked` props. :::note -- `toBeChecked()` matcher works only on `Switch` host elements and accessibility elements with `checkbox`, `radio` or `switch` role. -- `toBePartiallyChecked()` matcher works only on elements with `checkbox` role. +- `toBeChecked()` only works on `Switch` host elements and elements with `checkbox`, `radio`, or `switch` role. +- `toBePartiallyChecked()` only works on elements with `checkbox` role. ::: @@ -129,10 +129,10 @@ expect(element).toBeExpanded(); expect(element).toBeCollapsed(); ``` -Asserts whether the given element is expanded or collapsed from the user's perspective. It relies on the accessibility expanded state as set by `aria-expanded` or `accessibilityState.expanded` props. +Checks if an element is expanded or collapsed. Uses the accessibility expanded state from `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). +These matchers are opposites for expandable elements (those with explicit `aria-expanded` or `accessibilityState.expanded` props). For non-expandable elements, neither matcher will pass. ::: ### `toBeBusy()` @@ -141,7 +141,7 @@ These matchers are the negation of each other for expandable elements (elements expect(element).toBeBusy(); ``` -Asserts 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. +Checks if an element is busy. Uses the accessibility busy state from `aria-busy` or `accessibilityState.busy` props. ## Checking element style @@ -151,9 +151,9 @@ Asserts whether the given element is busy from the user's perspective. It relies expect(element).toBeVisible(); ``` -Asserts whether the given element is visible from the user's perspective. +Checks if an element is visible. -The element is considered invisible when itself or any of its ancestors has `display: none` or `opacity: 0` styles, as well as when it's hidden from accessibility. +An element is considered invisible if it or any of its ancestors has `display: none` or `opacity: 0` styles, or if it's hidden from accessibility. ### `toHaveStyle()` @@ -163,7 +163,7 @@ expect(element).toHaveStyle( ) ``` -Asserts whether the given element has given styles. +Checks if an element has the specified styles. ## Other matchers @@ -179,11 +179,11 @@ expect(element).toHaveAccessibleName( ) ``` -Asserts whether the given element has a specified accessible name. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if an element has the specified accessible name. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. -The accessible name will be computed based on `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props. For `Image` elements, the `alt` prop will also be considered. In the absence of these props, the element text content will be used. +The accessible name comes from `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props. For `Image` elements, the `alt` prop is also used. If none of these are present, the element's text content is used. -When the `name` parameter is `undefined` it will only check if the element has any accessible name. +If you don't pass a `name` parameter (or pass `undefined`), it only checks whether the element has any accessible name. ### `toHaveProp()` @@ -194,8 +194,8 @@ expect(element).toHaveProp( ) ``` -Asserts whether the given element has a given prop. When the `value` parameter is `undefined`, it only checks for prop existence. When `value` is defined, it checks if the actual value matches the passed value. +Checks if an element has a prop. If you don't pass a `value` (or pass `undefined`), it only checks if the prop exists. If you pass a `value`, it checks if the prop's value matches. :::note -This matcher should be treated as an escape hatch to be used when all other matchers are not suitable. +Use this matcher as a last resort when other matchers don't fit your needs. ::: From ab2b2c59638a136d4226bc4152879367bf45cfe0 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 22:56:30 +0100 Subject: [PATCH 07/11] humanize v13 docs --- .../cookbook/advanced/network-requests.md | 23 +++--- .../docs/13.x/docs/advanced/testing-env.mdx | 6 +- .../docs/advanced/third-party-integration.mdx | 2 +- .../13.x/docs/advanced/understanding-act.mdx | 32 ++++----- .../docs/13.x/docs/api/events/user-event.mdx | 18 ++--- website/docs/13.x/docs/api/jest-matchers.mdx | 6 +- .../docs/13.x/docs/api/misc/accessibility.mdx | 4 +- website/docs/13.x/docs/api/misc/async.mdx | 20 +++--- website/docs/13.x/docs/api/misc/config.mdx | 8 +-- website/docs/13.x/docs/api/misc/other.mdx | 12 ++-- .../docs/13.x/docs/api/misc/render-hook.mdx | 10 +-- website/docs/13.x/docs/api/queries.mdx | 70 +++++++++---------- website/docs/13.x/docs/api/render.mdx | 4 +- website/docs/13.x/docs/api/screen.mdx | 16 ++--- website/docs/13.x/docs/guides/faq.mdx | 2 +- .../docs/13.x/docs/guides/how-to-query.mdx | 4 +- website/docs/13.x/docs/guides/react-19.mdx | 2 +- .../docs/13.x/docs/migration/previous/v9.mdx | 2 +- website/docs/13.x/docs/start/intro.md | 2 +- 19 files changed, 121 insertions(+), 122 deletions(-) diff --git a/website/docs/13.x/cookbook/advanced/network-requests.md b/website/docs/13.x/cookbook/advanced/network-requests.md index 31a31d6c..9d6bba1b 100644 --- a/website/docs/13.x/cookbook/advanced/network-requests.md +++ b/website/docs/13.x/cookbook/advanced/network-requests.md @@ -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 diff --git a/website/docs/13.x/docs/advanced/testing-env.mdx b/website/docs/13.x/docs/advanced/testing-env.mdx index 41292a3f..95b9177e 100644 --- a/website/docs/13.x/docs/advanced/testing-env.mdx +++ b/website/docs/13.x/docs/advanced/testing-env.mdx @@ -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 diff --git a/website/docs/13.x/docs/advanced/third-party-integration.mdx b/website/docs/13.x/docs/advanced/third-party-integration.mdx index 4cf9ba02..cf7c7a2a 100644 --- a/website/docs/13.x/docs/advanced/third-party-integration.mdx +++ b/website/docs/13.x/docs/advanced/third-party-integration.mdx @@ -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 diff --git a/website/docs/13.x/docs/advanced/understanding-act.mdx b/website/docs/13.x/docs/advanced/understanding-act.mdx index a6dfd519..e973e7dc 100644 --- a/website/docs/13.x/docs/advanced/understanding-act.mdx +++ b/website/docs/13.x/docs/advanced/understanding-act.mdx @@ -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 diff --git a/website/docs/13.x/docs/api/events/user-event.mdx b/website/docs/13.x/docs/api/events/user-event.mdx index 4684faeb..4d472230 100644 --- a/website/docs/13.x/docs/api/events/user-event.mdx +++ b/website/docs/13.x/docs/api/events/user-event.mdx @@ -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: diff --git a/website/docs/13.x/docs/api/jest-matchers.mdx b/website/docs/13.x/docs/api/jest-matchers.mdx index f1576848..7740a1bc 100644 --- a/website/docs/13.x/docs/api/jest-matchers.mdx +++ b/website/docs/13.x/docs/api/jest-matchers.mdx @@ -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 diff --git a/website/docs/13.x/docs/api/misc/accessibility.mdx b/website/docs/13.x/docs/api/misc/accessibility.mdx index 6e7aab47..7b971988 100644 --- a/website/docs/13.x/docs/api/misc/accessibility.mdx +++ b/website/docs/13.x/docs/api/misc/accessibility.mdx @@ -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: diff --git a/website/docs/13.x/docs/api/misc/async.mdx b/website/docs/13.x/docs/api/misc/async.mdx index 7db4fcff..f26d7ea3 100644 --- a/website/docs/13.x/docs/api/misc/async.mdx +++ b/website/docs/13.x/docs/api/misc/async.mdx @@ -13,20 +13,20 @@ function waitFor( ): Promise; ``` -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( ): Promise; ``` -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. diff --git a/website/docs/13.x/docs/api/misc/config.mdx b/website/docs/13.x/docs/api/misc/config.mdx index e942007e..342359bd 100644 --- a/website/docs/13.x/docs/api/misc/config.mdx +++ b/website/docs/13.x/docs/api/misc/config.mdx @@ -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 diff --git a/website/docs/13.x/docs/api/misc/other.mdx b/website/docs/13.x/docs/api/misc/other.mdx index a82941fb..a24228e3 100644 --- a/website/docs/13.x/docs/api/misc/other.mdx +++ b/website/docs/13.x/docs/api/misc/other.mdx @@ -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). diff --git a/website/docs/13.x/docs/api/misc/render-hook.mdx b/website/docs/13.x/docs/api/misc/render-hook.mdx index a581ad12..1a024410 100644 --- a/website/docs/13.x/docs/api/misc/render-hook.mdx +++ b/website/docs/13.x/docs/api/misc/render-hook.mdx @@ -9,7 +9,7 @@ function renderHook( ): RenderHookResult; ``` -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 { } ``` -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. diff --git a/website/docs/13.x/docs/api/queries.mdx b/website/docs/13.x/docs/api/queries.mdx index 480e7356..6d79dd18 100644 --- a/website/docs/13.x/docs/api/queries.mdx +++ b/website/docs/13.x/docs/api/queries.mdx @@ -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` | Yes | | [`findAllBy*`](/docs/api/queries#find-all-by) | At least one matching element | `Promise>` | 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 ``` -`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 ``` -`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 `` 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 `` 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. ::: diff --git a/website/docs/13.x/docs/api/render.mdx b/website/docs/13.x/docs/api/render.mdx index fbc2f597..9f014b99 100644 --- a/website/docs/13.x/docs/api/render.mdx +++ b/website/docs/13.x/docs/api/render.mdx @@ -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 diff --git a/website/docs/13.x/docs/api/screen.mdx b/website/docs/13.x/docs/api/screen.mdx index 99d63aaf..8cf33290 100644 --- a/website/docs/13.x/docs/api/screen.mdx +++ b/website/docs/13.x/docs/api/screen.mdx @@ -39,7 +39,7 @@ _Also available under `update` alias_ function rerender(element: React.Element): 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): Promise; ``` -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; ``` -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(); @@ -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`. ::: diff --git a/website/docs/13.x/docs/guides/faq.mdx b/website/docs/13.x/docs/guides/faq.mdx index 4c6098ac..2b65213a 100644 --- a/website/docs/13.x/docs/guides/faq.mdx +++ b/website/docs/13.x/docs/guides/faq.mdx @@ -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. diff --git a/website/docs/13.x/docs/guides/how-to-query.mdx b/website/docs/13.x/docs/guides/how-to-query.mdx index 11c977de..8764bd3a 100644 --- a/website/docs/13.x/docs/guides/how-to-query.mdx +++ b/website/docs/13.x/docs/guides/how-to-query.mdx @@ -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: diff --git a/website/docs/13.x/docs/guides/react-19.mdx b/website/docs/13.x/docs/guides/react-19.mdx index 598e83a6..2fc21fbd 100644 --- a/website/docs/13.x/docs/guides/react-19.mdx +++ b/website/docs/13.x/docs/guides/react-19.mdx @@ -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. diff --git a/website/docs/13.x/docs/migration/previous/v9.mdx b/website/docs/13.x/docs/migration/previous/v9.mdx index 60557c56..5a914fad 100644 --- a/website/docs/13.x/docs/migration/previous/v9.mdx +++ b/website/docs/13.x/docs/migration/previous/v9.mdx @@ -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. diff --git a/website/docs/13.x/docs/start/intro.md b/website/docs/13.x/docs/start/intro.md index 9da2bc17..5cd5c759 100644 --- a/website/docs/13.x/docs/start/intro.md +++ b/website/docs/13.x/docs/start/intro.md @@ -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 From 518b016ee6777fb8fddda4eb3808fc3df2d19c85 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 23:18:05 +0100 Subject: [PATCH 08/11] tweaks --- website/docs/13.x/docs/api/jest-matchers.mdx | 32 ++++++++++---------- website/docs/13.x/docs/api/queries.mdx | 27 ++++++++--------- website/docs/14.x/docs/api/jest-matchers.mdx | 4 +-- website/docs/14.x/docs/api/queries.mdx | 4 +-- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/website/docs/13.x/docs/api/jest-matchers.mdx b/website/docs/13.x/docs/api/jest-matchers.mdx index 7740a1bc..e4fa79f0 100644 --- a/website/docs/13.x/docs/api/jest-matchers.mdx +++ b/website/docs/13.x/docs/api/jest-matchers.mdx @@ -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. These matchers provide readable assertions with accessibility support. ## Setup @@ -18,7 +18,7 @@ If you are already using legacy Jest Native matchers we have a [migration guide] expect(element).toBeOnTheScreen(); ``` -This allows you to assert whether an element is attached to the element tree or not. If you hold a reference to an element and it gets unmounted during the test it will no longer pass this assertion. +Checks if an element is attached to the element tree. If you hold a reference to an element and it gets unmounted during the test, it will no longer pass this assertion. ## Element Content @@ -34,7 +34,7 @@ expect(element).toHaveTextContent( ) ``` -This allows you to assert whether the given element has the given text content or not. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if the element has the specified text content. Accepts `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. ### `toContainElement()` @@ -44,7 +44,7 @@ expect(container).toContainElement( ) ``` -This allows you to assert whether the given container element does contain another host element. +Checks if the container element contains another host element. ### `toBeEmptyElement()` @@ -52,7 +52,7 @@ This allows you to assert whether the given container element does contain anoth expect(element).toBeEmptyElement(); ``` -This allows you to assert whether the given element does not have any host child elements or text content. +Checks if the element has no host child elements or text content. ## Checking element state @@ -68,7 +68,7 @@ expect(element).toHaveDisplayValue( ) ``` -This allows you to assert whether the given `TextInput` element has a specified display value. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if the `TextInput` element has the specified display value. Accepts `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. ### `toHaveAccessibilityValue()` @@ -83,7 +83,7 @@ expect(element).toHaveAccessibilityValue( ) ``` -This allows you to assert whether the given element has a specified accessible value. +Checks if the element has a specified accessible value. This matcher will assert accessibility value based on `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext` and `accessibilityValue` props. Only defined value entries will be used in the assertion, the element might have additional accessibility value entries and still be matched. @@ -96,7 +96,7 @@ expect(element).toBeEnabled(); expect(element).toBeDisabled(); ``` -These allow you to assert whether the given element is enabled or disabled from the user's perspective. It relies on the accessibility disabled state as set by `aria-disabled` or `accessibilityState.disabled` props. It will consider a given element disabled when it or any of its ancestors is disabled. +Checks if the element is enabled or disabled from the user's perspective. These rely on the accessibility disabled state set by `aria-disabled` or `accessibilityState.disabled` props. An element is considered disabled when it or any of its ancestors is disabled. :::note These matchers are the negation of each other, and both are provided to avoid double negations in your assertions. @@ -108,7 +108,7 @@ These matchers are the negation of each other, and both are provided to avoid do expect(element).toBeSelected(); ``` -This allows you to assert whether the given element is selected from the user's perspective. It relies on the accessibility selected state as set by `aria-selected` or `accessibilityState.selected` props. +Checks if the element is selected from the user's perspective. Relies on the accessibility selected state set by `aria-selected` or `accessibilityState.selected` props. ### `toBeChecked()` / `toBePartiallyChecked()` {#tobechecked} @@ -117,7 +117,7 @@ expect(element).toBeChecked(); expect(element).toBePartiallyChecked(); ``` -These allow you to assert whether the given element is checked or partially checked from the user's perspective. It relies on the accessibility checked state as set by `aria-checked` or `accessibilityState.checked` props. +Checks if the element is checked or partially checked from the user's perspective. These rely on the accessibility checked state set by `aria-checked` or `accessibilityState.checked` props. :::note @@ -133,7 +133,7 @@ expect(element).toBeExpanded(); expect(element).toBeCollapsed(); ``` -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. +Checks if the element is expanded or collapsed from the user's perspective. These rely on the accessibility expanded state 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 busy state as set by `aria-busy` or `accessibilityState.busy` props. +Checks if the element is busy from the user's perspective. Relies on the accessibility busy state set by `aria-busy` or `accessibilityState.busy` props. ## Checking element style @@ -155,7 +155,7 @@ This allows you to assert whether the given element is busy from the user's pers expect(element).toBeVisible(); ``` -This allows you to assert whether the given element is visible from the user's perspective. +Checks if the element is visible from the user's perspective. The element is considered invisible when itself or any of its ancestors has `display: none` or `opacity: 0` styles, as well as when it's hidden from accessibility. @@ -167,7 +167,7 @@ expect(element).toHaveStyle( ) ``` -This allows you to assert whether the given element has given styles. +Checks if the element has the specified styles. ## Other matchers @@ -183,7 +183,7 @@ expect(element).toHaveAccessibleName( ) ``` -This allows you to assert whether the given element has a specified accessible name. It accepts either `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if the element has the specified accessible name. Accepts `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. The accessible name will be computed based on `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props, in the absence of these props, the element text content will be used. @@ -198,7 +198,7 @@ expect(element).toHaveProp( ) ``` -This allows you to assert whether the given element has a given prop. When the `value` parameter is `undefined` it will only check for existence of the prop, and when `value` is defined it will check if the actual value matches passed value. +Checks if the element has the specified prop. When `value` is `undefined`, it only checks for existence of the prop. When `value` is defined, it checks if the actual value matches. :::note This matcher should be treated as an escape hatch to be used when all other matchers are not suitable. diff --git a/website/docs/13.x/docs/api/queries.mdx b/website/docs/13.x/docs/api/queries.mdx index 6d79dd18..2ecb4d7f 100644 --- a/website/docs/13.x/docs/api/queries.mdx +++ b/website/docs/13.x/docs/api/queries.mdx @@ -1,6 +1,6 @@ # Queries -Queries are one of the main building blocks for the React Native Testing Library. They enable you to find relevant elements in the element tree, which represents your application's user interface when running under tests. +Queries are one of the main building blocks of React Native Testing Library. They let you find elements in the element tree, which represents your application's user interface when running under tests. ## Accessing queries @@ -18,7 +18,7 @@ test('accessing queries using "screen" object', () => { }) ``` -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. +The recommended way to access queries is to use the `screen` object exported by `@testing-library/react-native`. It contains methods for all available queries bound to the most recently rendered UI. ### Using `render` result @@ -35,19 +35,16 @@ The classic way is to capture query functions returned from the `render` functio ## Query parts -Each query is composed of two parts: variant and predicate, which are separated by the `by` word in the middle of the name. +Each query is composed of two parts: variant and predicate, separated by the word `by` in the middle. -Consider the following query: +Consider the query `getByRole()`: -``` -getByRole() -``` - -For this query, `getBy*` is the query variant, and `*ByRole` is the predicate. +- `getBy*` is the query variant +- `*ByRole` is the predicate ## Query variant -The query variants describe the expected number (and timing) of matching elements, so they differ in their return type. +The query variants describe the expected number (and timing) of matching elements, so they differ in return type. | Variant | Assertion | Return type | Is Async? | | ----------------------------------------------- | ----------------------------- | ------------------------------------------ | --------- | @@ -130,7 +127,7 @@ When your `findBy*` and `findAllBy*` queries throw because they can't find match ## Query predicates -_Note: most methods like this one return a [`ReactTestInstance`](https://reactjs.org/docs/test-renderer.html#testinstance) with following properties that you may be interested in:_ +_Note: most methods like this one return a [`ReactTestInstance`](https://reactjs.org/docs/test-renderer.html#testinstance) with the following properties that you may be interested in:_ ```typescript type ReactTestInstance = { @@ -169,7 +166,7 @@ getByRole( Returns a `ReactTestInstance` with matching `role` or `accessibilityRole` prop. :::info -In order for `*ByRole` queries to match an element it needs to be considered an accessibility element: +For `*ByRole` queries to match an element, it needs to be considered an accessibility element: 1. `Text`, `TextInput` and `Switch` host elements are these by default. 2. `View` host elements need an explicit [`accessible`](https://reactnative.dev/docs/accessibility#accessible) prop set to `true` @@ -236,7 +233,7 @@ getByLabelText( Returns a `ReactTestInstance` with matching label: - either by matching [`aria-label`](https://reactnative.dev/docs/accessibility#aria-label)/[`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) prop -- or by matching text content of view referenced by [`aria-labelledby`](https://reactnative.dev/docs/accessibility#aria-labelledby-android)/[`accessibilityLabelledBy`](https://reactnative.dev/docs/accessibility#accessibilitylabelledby-android) prop +- or by matching the text content of the view referenced by [`aria-labelledby`](https://reactnative.dev/docs/accessibility#aria-labelledby-android)/[`accessibilityLabelledBy`](https://reactnative.dev/docs/accessibility#accessibilitylabelledby-android) prop ```jsx import { render, screen } from '@testing-library/react-native'; @@ -284,7 +281,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. The value can be a string or regular expression. ```jsx import { render, screen } from '@testing-library/react-native'; @@ -308,7 +305,7 @@ getByText( ): ReactTestInstance; ``` -Returns a `ReactTestInstance` with matching text—may be a string or regular expression. +Returns a `ReactTestInstance` with matching text. The text can be a string or regular expression. This method joins `` 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. diff --git a/website/docs/14.x/docs/api/jest-matchers.mdx b/website/docs/14.x/docs/api/jest-matchers.mdx index 4553f247..fc37e170 100644 --- a/website/docs/14.x/docs/api/jest-matchers.mdx +++ b/website/docs/14.x/docs/api/jest-matchers.mdx @@ -40,7 +40,7 @@ expect(container).toContainElement( ) ``` -Checks if a container element contains another host element. +Checks if the container element contains another host element. ### `toBeEmptyElement()` @@ -64,7 +64,7 @@ expect(element).toHaveDisplayValue( ) ``` -Checks if a `TextInput` element has the specified display value. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. +Checks if the `TextInput` element has the specified display value. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. ### `toHaveAccessibilityValue()` diff --git a/website/docs/14.x/docs/api/queries.mdx b/website/docs/14.x/docs/api/queries.mdx index 22cf5bc4..fdfb0267 100644 --- a/website/docs/14.x/docs/api/queries.mdx +++ b/website/docs/14.x/docs/api/queries.mdx @@ -171,8 +171,8 @@ Returns a `HostElement` with matching `role` or `accessibilityRole` prop. :::info In order for `*ByRole` queries to match an element it needs to be considered an accessibility element: -1. `Text`, `TextInput` and `Switch` host elements are these by default. -2. `View` host elements need an explicit [`accessible`](https://reactnative.dev/docs/accessibility#accessible) prop set to `true` +1. `Text`, `TextInput` and `Switch` elements are these by default. +2. `View` elements need an explicit [`accessible`](https://reactnative.dev/docs/accessibility#accessible) prop set to `true` 3. Some React Native composite components like `Pressable` & `TouchableOpacity` render host `View` element with `accessible` prop already set. ::: From 521b56a88bc3ef97c67a36d02c00e65dfe31926f Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 23:18:13 +0100 Subject: [PATCH 09/11] enable llms.txt --- website/rspress.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/website/rspress.config.ts b/website/rspress.config.ts index b8a2381d..05bf15d6 100644 --- a/website/rspress.config.ts +++ b/website/rspress.config.ts @@ -383,6 +383,7 @@ export default defineConfig({ search: { versioned: true, }, + llms: true, themeConfig: { enableContentAnimation: true, enableScrollToTop: true, From bf4e88d10af239a24a9b2b7169d2b2f6e24a87db Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 23:25:56 +0100 Subject: [PATCH 10/11] . --- website/docs/13.x/docs/api/jest-matchers.mdx | 54 ++++++++++---------- website/docs/14.x/docs/api/jest-matchers.mdx | 34 ++++++------ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/website/docs/13.x/docs/api/jest-matchers.mdx b/website/docs/13.x/docs/api/jest-matchers.mdx index e4fa79f0..ea902299 100644 --- a/website/docs/13.x/docs/api/jest-matchers.mdx +++ b/website/docs/13.x/docs/api/jest-matchers.mdx @@ -4,11 +4,11 @@ This guide describes built-in Jest matchers. These matchers provide readable ass ## Setup -There is no need to set up the built-in matchers; they are automatically available in your tests when you import anything from `@testing-library/react-native`, e.g., `render`. +No setup needed. Matchers are available when you import from `@testing-library/react-native`. -## Migration from legacy Jest Native matchers. +## Migration from legacy Jest Native matchers -If you are already using legacy Jest Native matchers we have a [migration guide](/docs/migration/jest-matchers) for moving to the built-in matchers. +If you use legacy Jest Native matchers, see the [migration guide](/docs/migration/jest-matchers). ## Checking element existence @@ -18,7 +18,7 @@ If you are already using legacy Jest Native matchers we have a [migration guide] expect(element).toBeOnTheScreen(); ``` -Checks if an element is attached to the element tree. If you hold a reference to an element and it gets unmounted during the test, it will no longer pass this assertion. +Checks if an element is attached to the element tree. If a referenced element gets unmounted during the test, this assertion fails. ## Element Content @@ -34,7 +34,7 @@ expect(element).toHaveTextContent( ) ``` -Checks if the element has the specified text content. Accepts `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if the element has the specified text content. Accepts `string` or `RegExp`, with optional [text match options](/docs/api/queries#text-match-options) `exact` and `normalizer`. ### `toContainElement()` @@ -44,7 +44,7 @@ expect(container).toContainElement( ) ``` -Checks if the container element contains another host element. +Checks if a container element contains another element. ### `toBeEmptyElement()` @@ -52,7 +52,7 @@ Checks if the container element contains another host element. expect(element).toBeEmptyElement(); ``` -Checks if the element has no host child elements or text content. +Checks if the element has no child elements or text content. ## Checking element state @@ -68,7 +68,7 @@ expect(element).toHaveDisplayValue( ) ``` -Checks if the `TextInput` element has the specified display value. Accepts `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if a `TextInput` has the specified display value. Accepts `string` or `RegExp`, with optional [text match options](/docs/api/queries#text-match-options) `exact` and `normalizer`. ### `toHaveAccessibilityValue()` @@ -85,9 +85,9 @@ expect(element).toHaveAccessibilityValue( Checks if the element has a specified accessible value. -This matcher will assert accessibility value based on `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext` and `accessibilityValue` props. Only defined value entries will be used in the assertion, the element might have additional accessibility value entries and still be matched. +Reads from `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext`, and `accessibilityValue` props. Only the values you specify are checked, so the element can have other accessibility value entries and still match. -When querying by `text` entry a string or `RegExp` might be used. +For the `text` entry, you can use `string` or `RegExp`. ### `toBeEnabled()` / `toBeDisabled` {#tobeenabled} @@ -96,10 +96,10 @@ expect(element).toBeEnabled(); expect(element).toBeDisabled(); ``` -Checks if the element is enabled or disabled from the user's perspective. These rely on the accessibility disabled state set by `aria-disabled` or `accessibilityState.disabled` props. An element is considered disabled when it or any of its ancestors is disabled. +Checks if the element is enabled or disabled based on `aria-disabled` or `accessibilityState.disabled` props. An element is disabled when it or any ancestor is disabled. :::note -These matchers are the negation of each other, and both are provided to avoid double negations in your assertions. +These matchers are opposites. Both are provided to avoid double negations in assertions. ::: ### `toBeSelected()` @@ -108,7 +108,7 @@ These matchers are the negation of each other, and both are provided to avoid do expect(element).toBeSelected(); ``` -Checks if the element is selected from the user's perspective. Relies on the accessibility selected state set by `aria-selected` or `accessibilityState.selected` props. +Checks if the element is selected based on `aria-selected` or `accessibilityState.selected` props. ### `toBeChecked()` / `toBePartiallyChecked()` {#tobechecked} @@ -117,12 +117,12 @@ expect(element).toBeChecked(); expect(element).toBePartiallyChecked(); ``` -Checks if the element is checked or partially checked from the user's perspective. These rely on the accessibility checked state set by `aria-checked` or `accessibilityState.checked` props. +Checks if the element is checked or partially checked based on `aria-checked` or `accessibilityState.checked` props. :::note -- `toBeChecked()` matcher works only on `Switch` host elements and accessibility elements with `checkbox`, `radio` or `switch` role. -- `toBePartiallyChecked()` matcher works only on elements with `checkbox` role. +- `toBeChecked()` works only on `Switch` elements and elements with `checkbox`, `radio`, or `switch` role. +- `toBePartiallyChecked()` works only on elements with `checkbox` role. ::: @@ -133,10 +133,10 @@ expect(element).toBeExpanded(); expect(element).toBeCollapsed(); ``` -Checks if the element is expanded or collapsed from the user's perspective. These rely on the accessibility expanded state set by `aria-expanded` or `accessibilityState.expanded` props. +Checks if the element is expanded or collapsed based on `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). +These matchers are opposites for expandable elements (those with explicit `aria-expanded` or `accessibilityState.expanded` props). For non-expandable elements, neither matcher passes. ::: ### `toBeBusy()` @@ -145,7 +145,7 @@ These matchers are the negation of each other for expandable elements (elements expect(element).toBeBusy(); ``` -Checks if the element is busy from the user's perspective. Relies on the accessibility busy state set by `aria-busy` or `accessibilityState.busy` props. +Checks if the element is busy based on `aria-busy` or `accessibilityState.busy` props. ## Checking element style @@ -155,9 +155,9 @@ Checks if the element is busy from the user's perspective. Relies on the accessi expect(element).toBeVisible(); ``` -Checks if the element is visible from the user's perspective. +Checks if the element is visible. -The element is considered invisible when itself or any of its ancestors has `display: none` or `opacity: 0` styles, as well as when it's hidden from accessibility. +An element is invisible when it or any ancestor has `display: none` or `opacity: 0` styles, or when it's hidden from accessibility. ### `toHaveStyle()` @@ -167,7 +167,7 @@ expect(element).toHaveStyle( ) ``` -Checks if the element has the specified styles. +Checks if the element has specific styles. ## Other matchers @@ -183,11 +183,11 @@ expect(element).toHaveAccessibleName( ) ``` -Checks if the element has the specified accessible name. Accepts `string` or `RegExp` matchers, as well as [text match options](/docs/api/queries#text-match-options) of `exact` and `normalizer`. +Checks if the element has the specified accessible name. Accepts `string` or `RegExp`, with optional [text match options](/docs/api/queries#text-match-options) `exact` and `normalizer`. -The accessible name will be computed based on `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props, in the absence of these props, the element text content will be used. +The accessible name comes from `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props. If none are present, the element's text content is used. -When the `name` parameter is `undefined` it will only check if the element has any accessible name. +Without a `name` parameter (or with `undefined`), it only checks if the element has any accessible name. ### `toHaveProp()` @@ -198,8 +198,8 @@ expect(element).toHaveProp( ) ``` -Checks if the element has the specified prop. When `value` is `undefined`, it only checks for existence of the prop. When `value` is defined, it checks if the actual value matches. +Checks if the element has a prop. Without a `value` (or with `undefined`), it only checks if the prop exists. With a `value`, it checks if the prop's value matches. :::note -This matcher should be treated as an escape hatch to be used when all other matchers are not suitable. +Use this matcher as a last resort when other matchers don't fit your needs. ::: diff --git a/website/docs/14.x/docs/api/jest-matchers.mdx b/website/docs/14.x/docs/api/jest-matchers.mdx index fc37e170..0f030216 100644 --- a/website/docs/14.x/docs/api/jest-matchers.mdx +++ b/website/docs/14.x/docs/api/jest-matchers.mdx @@ -4,7 +4,7 @@ This guide covers the built-in Jest matchers. These matchers make your tests eas ## Setup -There is no need to set up the built-in matchers; they are automatically available in your tests when you import anything from `@testing-library/react-native`, e.g., `render`. +No setup needed. Matchers are available when you import from `@testing-library/react-native`. ## Checking element existence @@ -30,7 +30,7 @@ expect(element).toHaveTextContent( ) ``` -Checks if an element has the specified text content. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. +Checks if an element has the specified text content. Accepts `string` or `RegExp`, with optional [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. ### `toContainElement()` @@ -40,7 +40,7 @@ expect(container).toContainElement( ) ``` -Checks if the container element contains another host element. +Checks if a container element contains another element. ### `toBeEmptyElement()` @@ -48,7 +48,7 @@ Checks if the container element contains another host element. expect(element).toBeEmptyElement(); ``` -Checks if an element has no host child elements or text content. +Checks if an element has no child elements or text content. ## Checking element state @@ -64,7 +64,7 @@ expect(element).toHaveDisplayValue( ) ``` -Checks if the `TextInput` element has the specified display value. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. +Checks if a `TextInput` has the specified display value. Accepts `string` or `RegExp`, with optional [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. ### `toHaveAccessibilityValue()` @@ -81,7 +81,7 @@ expect(element).toHaveAccessibilityValue( Checks if an element has the specified accessible value. -The matcher checks accessibility values from `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext`, and `accessibilityValue` props. It only checks the values you specify—the element can have other accessibility value entries and still match. +The matcher reads accessibility values from `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-valuetext`, and `accessibilityValue` props. It only checks the values you specify, so the element can have other accessibility value entries and still match. For the `text` entry, you can use a string or `RegExp`. @@ -92,7 +92,7 @@ expect(element).toBeEnabled(); expect(element).toBeDisabled(); ``` -Checks if an element is enabled or disabled. Uses the accessibility disabled state from `aria-disabled` or `accessibilityState.disabled` props. An element is considered disabled if it or any of its ancestors is disabled. +Checks if an element is enabled or disabled from `aria-disabled` or `accessibilityState.disabled` props. An element is disabled if it or any ancestor is disabled. :::note These matchers are opposites. Both are available so you can avoid double negations like `expect(element).not.toBeDisabled()`. @@ -104,7 +104,7 @@ These matchers are opposites. Both are available so you can avoid double negatio expect(element).toBeSelected(); ``` -Checks if an element is selected. Uses the accessibility selected state from `aria-selected` or `accessibilityState.selected` props. +Checks if an element is selected from `aria-selected` or `accessibilityState.selected` props. ### `toBeChecked()` / `toBePartiallyChecked()` {#tobechecked} @@ -113,7 +113,7 @@ expect(element).toBeChecked(); expect(element).toBePartiallyChecked(); ``` -Checks if an element is checked or partially checked. Uses the accessibility checked state from `aria-checked` or `accessibilityState.checked` props. +Checks if an element is checked or partially checked from `aria-checked` or `accessibilityState.checked` props. :::note @@ -129,7 +129,7 @@ expect(element).toBeExpanded(); expect(element).toBeCollapsed(); ``` -Checks if an element is expanded or collapsed. Uses the accessibility expanded state from `aria-expanded` or `accessibilityState.expanded` props. +Checks if an element is expanded or collapsed from `aria-expanded` or `accessibilityState.expanded` props. :::note These matchers are opposites for expandable elements (those with explicit `aria-expanded` or `accessibilityState.expanded` props). For non-expandable elements, neither matcher will pass. @@ -141,7 +141,7 @@ These matchers are opposites for expandable elements (those with explicit `aria- expect(element).toBeBusy(); ``` -Checks if an element is busy. Uses the accessibility busy state from `aria-busy` or `accessibilityState.busy` props. +Checks if an element is busy from `aria-busy` or `accessibilityState.busy` props. ## Checking element style @@ -153,7 +153,7 @@ expect(element).toBeVisible(); Checks if an element is visible. -An element is considered invisible if it or any of its ancestors has `display: none` or `opacity: 0` styles, or if it's hidden from accessibility. +An element is invisible if it or any ancestor has `display: none` or `opacity: 0` styles, or if it's hidden from accessibility. ### `toHaveStyle()` @@ -163,7 +163,7 @@ expect(element).toHaveStyle( ) ``` -Checks if an element has the specified styles. +Checks if an element has specific styles. ## Other matchers @@ -179,11 +179,11 @@ expect(element).toHaveAccessibleName( ) ``` -Checks if an element has the specified accessible name. You can pass a `string` or `RegExp`, plus [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. +Checks if an element has the specified accessible name. Accepts `string` or `RegExp`, with optional [text match options](/docs/api/queries#text-match-options) like `exact` and `normalizer`. -The accessible name comes from `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props. For `Image` elements, the `alt` prop is also used. If none of these are present, the element's text content is used. +The accessible name comes from `aria-labelledby`, `accessibilityLabelledBy`, `aria-label`, and `accessibilityLabel` props. For `Image` elements, the `alt` prop is also used. If none are present, the element's text content is used. -If you don't pass a `name` parameter (or pass `undefined`), it only checks whether the element has any accessible name. +Without a `name` parameter (or with `undefined`), it only checks whether the element has any accessible name. ### `toHaveProp()` @@ -194,7 +194,7 @@ expect(element).toHaveProp( ) ``` -Checks if an element has a prop. If you don't pass a `value` (or pass `undefined`), it only checks if the prop exists. If you pass a `value`, it checks if the prop's value matches. +Checks if an element has a prop. Without a `value` (or with `undefined`), it only checks if the prop exists. With a `value`, it checks if the prop's value matches. :::note Use this matcher as a last resort when other matchers don't fit your needs. From 40c38685f23b49c21a9ed381473a3ce08b7bec76 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 20 Jan 2026 23:26:59 +0100 Subject: [PATCH 11/11] . --- website/docs/14.x/docs/advanced/testing-env.mdx | 2 ++ website/docs/14.x/docs/guides/faq.mdx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/website/docs/14.x/docs/advanced/testing-env.mdx b/website/docs/14.x/docs/advanced/testing-env.mdx index f6e27dc9..338c63e6 100644 --- a/website/docs/14.x/docs/advanced/testing-env.mdx +++ b/website/docs/14.x/docs/advanced/testing-env.mdx @@ -25,11 +25,13 @@ Instead, RNTL uses [Test Renderer](https://github.com/mdjastrzebski/test-rendere Using Test Renderer has trade-offs: Benefits: + - Tests run on most CIs (Linux, etc) without a mobile device or emulator - Faster test execution - Light runtime environment Limitations: + - Tests don't execute native code - Tests are unaware of view state managed by native components, e.g., focus, unmanaged text boxes, etc. - Assertions don't operate on native view hierarchy diff --git a/website/docs/14.x/docs/guides/faq.mdx b/website/docs/14.x/docs/guides/faq.mdx index d489e3de..2724a1ef 100644 --- a/website/docs/14.x/docs/guides/faq.mdx +++ b/website/docs/14.x/docs/guides/faq.mdx @@ -16,12 +16,14 @@ You can learn more about our testing environment [here](/docs/advanced/testing-e This approach has benefits and limitations: Benefits: + - Tests most of the logic of regular React Native apps - Runs tests on any OS supported by Jest or other test runners, e.g., on CI - Uses fewer resources than full runtime simulation - Works with Jest fake timers Limitations: + - Cannot test native features - May not perfectly simulate certain JavaScript features, but we're working on it