test-renderer 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  A lightweight, JS-only building block for creating Testing Library-style libraries.
4
4
 
5
- This library is used by [React Native Testing Library](https://github.com/callstack/react-native-testing-library) but is written generically to support different React variants and custom renderers.
5
+ This library is used by [React Native Testing Library](https://github.com/callstack/react-native-testing-library) but should work with any React variant.
6
6
 
7
- This library also serves as a replacement for the deprecated React Test Renderer. It is built using [React Reconciler](https://github.com/facebook/react/tree/main/packages/react-reconciler) to provide a custom renderer that operates on host elements by default, with proper escape hatches when needed. Most React Reconciler options are exposed for maximum flexibility.
7
+ This library replaces the deprecated React Test Renderer. It uses [React Reconciler](https://github.com/facebook/react/tree/main/packages/react-reconciler) to build a custom renderer that operates on host elements by default, and provides escape hatches for complex use-cases. Most React Reconciler options are exposed through `RootOptions`.
8
+
9
+ For release and compatibility policy, see [docs/versioning.md](./docs/versioning.md).
8
10
 
9
11
  ## Installation
10
12
 
@@ -36,6 +38,34 @@ test("renders a component", async () => {
36
38
  });
37
39
  ```
38
40
 
41
+ ## Supported React Features
42
+
43
+ This library supports all modern React features including:
44
+
45
+ - Concurrent rendering
46
+ - Error boundaries
47
+ - Suspense boundaries
48
+
49
+ ## Test Output Tree
50
+
51
+ Instead of producing a DOM tree or a native view hierarchy, the renderer builds an in-memory **Test Output Tree**:
52
+
53
+ - Composed of **`TestNode`s**, where each node is either:
54
+ - A **`TestInstance`** — represents a host element such as `div` or `View`
55
+ - A plain **`string`** — represents a text node
56
+ - The root is accessible via `root.container`, a `TestInstance` whose `type` is an empty string
57
+ - `TestInstance` nodes are traversable and queryable — see the [`TestInstance`](#testelement) API below
58
+
59
+ ## JSON Output Tree
60
+
61
+ Calling `toJSON()` on a `TestInstance` produces a **JSON Output Tree** — a static, plain-object snapshot of the Test Output Tree at that point in time:
62
+
63
+ - Composed of **`JsonNode`s**, where each node is either:
64
+ - A **`JsonElement`** — a plain object with `type`, `props`, and `children`
65
+ - A plain **`string`** — a text node
66
+ - Contains no live references, making it safe to serialize
67
+ - Ideal for snapshot testing
68
+
39
69
  ## API Reference
40
70
 
41
71
  ### `createRoot(options?)`
@@ -50,7 +80,7 @@ Creates a new test renderer root instance.
50
80
 
51
81
  - `render(element: ReactElement)`: Renders a React element into the root. Must be called within `act()`.
52
82
  - `unmount()`: Unmounts the root and cleans up. Must be called within `act()`.
53
- - `container`: A `HostElement` wrapper that contains the rendered element(s). Use this to query and inspect the rendered tree.
83
+ - `container`: A `TestInstance` wrapper that contains the rendered element(s). Use this to query and inspect the rendered tree.
54
84
 
55
85
  **Example:**
56
86
 
@@ -65,33 +95,33 @@ await act(async () => {
65
95
 
66
96
  Configuration options for the test renderer. Many of these options correspond to React Reconciler configuration options. For detailed information about reconciler-specific options, refer to the [React Reconciler source code](https://github.com/facebook/react/tree/main/packages/react-reconciler).
67
97
 
68
- | Option | Type | Description |
69
- | -------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
- | `textComponentTypes` | `string[]` | Types of host components that are allowed to contain text nodes. Trying to render text outside of these components will throw an error. Useful for simulating React Native's text rendering rules. |
71
- | `publicTextComponentTypes` | `string[]` | Host component types to display to users in error messages when they try to render text outside of `textComponentTypes`. Defaults to `textComponentTypes` if not provided. |
72
- | `createNodeMock` | `(element: ReactElement) => object` | Function to create mock objects for refs. Called once per element that has a ref. Defaults to returning an empty object. |
73
- | `identifierPrefix` | `string` | A string prefix React uses for IDs generated by `useId()`. Useful to avoid conflicts when using multiple roots. |
74
- | `isStrictMode` | `boolean` | Enable React Strict Mode. When enabled, components render twice and effects run twice in development. |
75
- | `onCaughtError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when React catches an error in an Error Boundary. Called with the error caught by the Error Boundary and an errorInfo object containing the component stack. |
76
- | `onUncaughtError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when an error is thrown and not caught by an Error Boundary. Called with the error that was thrown and an errorInfo object containing the component stack. |
77
- | `onRecoverableError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when React automatically recovers from errors. Called with an error React throws and an errorInfo object containing the component stack. Some recoverable errors may include the original error cause as `error.cause`. |
98
+ | Option | Type | Description |
99
+ | ------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
100
+ | `textComponentTypes` | `string[]` | Types of host components that are allowed to contain text nodes. Trying to render text outside of these components will throw an error. Useful for simulating React Native's text rendering rules. |
101
+ | `publicTextComponentTypes` | `string[]` | Host component types to display to users in error messages when they try to render text outside of `textComponentTypes`. Defaults to `textComponentTypes` if not provided. |
102
+ | `transformHiddenInstanceProps` | `({ props, type }: { props: Record<string, unknown>; type: string }) => Record<string, unknown>` | Transforms host instance props when React marks an instance as hidden (for example, while Suspense fallback is shown). Return a new props object instead of mutating the provided one. When provided, hidden instances stay visible in `children` and `toJSON()` output using transformed props. |
103
+ | `identifierPrefix` | `string` | A string prefix React uses for IDs generated by `useId()`. Useful to avoid conflicts when using multiple roots. |
104
+ | `isStrictMode` | `boolean` | Enable React Strict Mode. When enabled, components render twice and effects run twice in development. |
105
+ | `onCaughtError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when React catches an error in an Error Boundary. Called with the error caught by the Error Boundary and an errorInfo object containing the component stack. |
106
+ | `onUncaughtError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when an error is thrown and not caught by an Error Boundary. Called with the error that was thrown and an errorInfo object containing the component stack. |
107
+ | `onRecoverableError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when React automatically recovers from errors. Called with an error React throws and an errorInfo object containing the component stack. Some recoverable errors may include the original error cause as `error.cause`. |
78
108
 
79
- ### `HostElement`
109
+ ### `TestInstance` {#test-instance}
80
110
 
81
- A wrapper around rendered host elements that provides a DOM-like API for querying and inspecting the rendered tree.
111
+ A wrapper around rendered host elements with a DOM-like API for querying and inspecting the rendered tree.
82
112
 
83
113
  **Properties:**
84
114
 
85
115
  - `type: string`: The element type (e.g., `"View"`, `"div"`). Returns an empty string for the container element.
86
- - `props: HostElementProps`: The element's props object.
87
- - `children: HostNode[]`: Array of child nodes (elements and text strings). Hidden children are excluded.
88
- - `parent: HostElement | null`: The parent element, or `null` if this is the root container.
116
+ - `props: Record<string, all>`: The element's props object.
117
+ - `children: HostNode[]`: Array of child nodes (elements and text strings). Hidden children are excluded by default, but are included when `transformHiddenInstanceProps` is configured.
118
+ - `parent: TestInstance | null`: The parent element, or `null` if this is the root container.
89
119
  - `unstable_fiber: Fiber | null`: Access to the underlying React Fiber node. **Warning:** This is an unstable API that exposes internal React Reconciler structures which may change without warning in future React versions. Use with caution and only when absolutely necessary.
90
120
 
91
121
  **Methods:**
92
122
 
93
- - `toJSON(): JsonElement | null`: Converts this element to a JSON representation suitable for snapshots. Returns `null` if the element is hidden.
94
- - `queryAll(predicate: (element: HostElement) => boolean, options?: QueryOptions): HostElement[]`: Finds all descendant elements matching the predicate. See [Query Options](#query-options) below.
123
+ - `toJSON(): JsonElement | null`: Converts this element to a JSON representation suitable for snapshots. Returns `null` for hidden elements only when `transformHiddenInstanceProps` is not configured.
124
+ - `queryAll(predicate: (instance: TestInstance) => boolean, options?: QueryOptions): TestInstance[]`: Finds all descendant elements matching the predicate. See [Query Options](#query-options) below.
95
125
 
96
126
  **Example:**
97
127
 
@@ -101,7 +131,7 @@ await act(async () => {
101
131
  renderer.render(<div className="container">Hello</div>);
102
132
  });
103
133
 
104
- const root = renderer.container.children[0] as HostElement;
134
+ const root = renderer.container.children[0] as TestInstance;
105
135
  expect(root.type).toBe("div");
106
136
  expect(root.props.className).toBe("container");
107
137
  expect(root.children).toContain("Hello");
@@ -131,11 +161,11 @@ const includingSelf = container.queryAll((el) => el.type === "div", { includeSel
131
161
 
132
162
  ## Migration from React Test Renderer
133
163
 
134
- This library serves as a replacement for the deprecated React Test Renderer. The main differences are:
164
+ This library replaces the deprecated React Test Renderer. The main differences:
135
165
 
136
- - **Host element focus**: This library operates on host components by default, while React Test Renderer worked with a mix of host and composite components. You can access the underlying fiber via `unstable_fiber` if needed.
137
- - **Built on React Reconciler**: This library is built using React Reconciler, providing a custom renderer implementation.
138
- - **Exposed reconciler options**: Most React Reconciler configuration options are exposed through `RootOptions` for maximum flexibility.
166
+ - **Host element focus**: Operates on host components by default, while React Test Renderer worked with a mix of host and composite components. Access the underlying fiber via `unstable_fiber` if needed.
167
+ - **Built on React Reconciler**: Uses React Reconciler to implement a custom renderer.
168
+ - **Exposed reconciler options**: Most React Reconciler configuration options are available through `RootOptions`.
139
169
 
140
170
  For most use cases, the migration is straightforward:
141
171
 
@@ -144,7 +174,7 @@ For most use cases, the migration is straightforward:
144
174
  import TestRenderer from "react-test-renderer";
145
175
  const tree = TestRenderer.create(<MyComponent />);
146
176
 
147
- // After (test-renderer)
177
+ // After (Test Renderer)
148
178
  import { createRoot } from "test-renderer";
149
179
  const root = createRoot();
150
180
  await act(async () => {
@@ -153,13 +183,23 @@ await act(async () => {
153
183
  const tree = root.container;
154
184
  ```
155
185
 
156
- ## Supported React Features
186
+ ## Performance Metrics
157
187
 
158
- This library supports all modern React features including:
188
+ The library includes optional performance instrumentation using the [Performance API](https://developer.mozilla.org/en-US/docs/Web/API/Performance). All marks and measures are prefixed with `test-renderer/` for easy filtering.
159
189
 
160
- - Concurrent rendering
161
- - Error boundaries
162
- - Suspense boundaries
190
+ ```tsx
191
+ globalThis.TEST_RENDERER_ENABLE_PROFILING = true;
192
+
193
+ // Run your tests, then query metrics:
194
+ const marks = performance
195
+ .getEntriesByType("mark")
196
+ .filter((m) => m.name.startsWith("test-renderer/"));
197
+ const measures = performance
198
+ .getEntriesByType("measure")
199
+ .filter((m) => m.name.startsWith("test-renderer/"));
200
+ ```
201
+
202
+ **Note:** The specific marks and measures emitted are unstable and may change between versions. Performance metrics are disabled by default.
163
203
 
164
204
  ## License
165
205