Skip to content

Commit e89f094

Browse files
committed
format
1 parent 8a90ebd commit e89f094

File tree

4 files changed

+158
-180
lines changed

4 files changed

+158
-180
lines changed

website/docs/13.x/docs/guides/common-mistakes.mdx

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This guide outlines some common mistakes people make when using React Native Tes
1010

1111
## Using the wrong query {#using-the-wrong-query}
1212

13-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
13+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
1414

1515
React Native Testing Library provides several query types. Here's the priority order:
1616

@@ -50,7 +50,7 @@ test('finds input by label', () => {
5050

5151
## Not using `*ByRole` query most of the time {#not-using-byrole-most-of-the-time}
5252

53-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
53+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
5454

5555
`getByRole` is the most accessible query and should be your first choice. It queries elements by their semantic role:
5656

@@ -92,7 +92,7 @@ Note: React Native supports both ARIA-compatible (`role`) and legacy (`accessibi
9292

9393
## Using the wrong assertion {#using-the-wrong-assertion}
9494

95-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
95+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
9696

9797
React Native Testing Library provides built-in Jest matchers. Make sure you're using the right ones:
9898

@@ -127,7 +127,7 @@ Common matchers include:
127127

128128
## Using `query*` variants for anything except checking for non-existence {#using-query-variants-for-anything-except-checking-for-non-existence}
129129

130-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
130+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
131131

132132
Use `queryBy*` only when checking that an element doesn't exist:
133133

@@ -156,7 +156,7 @@ test('checks non-existence', () => {
156156

157157
## Using `waitFor` to wait for elements that can be queried with `find*` {#using-waitfor-to-wait-for-elements-that-can-be-queried-with-find}
158158

159-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
159+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
160160

161161
Use `findBy*` queries instead of `waitFor` + `getBy*`:
162162

@@ -190,7 +190,7 @@ test('waits for element', async () => {
190190

191191
## Performing side-effects in `waitFor` {#performing-side-effects-in-waitfor}
192192

193-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
193+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
194194

195195
Don't perform side-effects in `waitFor` callbacks:
196196

@@ -231,7 +231,7 @@ test('avoids side effects in waitFor', async () => {
231231

232232
## Using `UNSAFE_root` to query for elements {#using-unsafe-root-to-query-for-elements}
233233

234-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
234+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
235235

236236
React Native Testing Library provides an `UNSAFE_root` object that gives access to the root element, but you should avoid using it directly:
237237

@@ -258,7 +258,7 @@ Instead, use the proper query methods from `screen` or the `render` result. The
258258

259259
## Passing an empty callback to `waitFor` {#passing-an-empty-callback-to-waitfor}
260260

261-
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
261+
<span style={{ color: '#a94442', fontWeight: 'bold' }}>Importance: high</span>
262262

263263
Don't pass an empty callback to `waitFor`:
264264

@@ -281,7 +281,7 @@ test('waits correctly', async () => {
281281

282282
## Not using `screen` {#not-using-screen}
283283

284-
<span style={{color: '#8a6d3b', fontWeight: 'bold'}}>Importance: medium</span>
284+
<span style={{ color: '#8a6d3b', fontWeight: 'bold' }}>Importance: medium</span>
285285

286286
You can get all the queries from the `render` result:
287287

@@ -324,7 +324,7 @@ Using `screen` has several benefits:
324324

325325
## Wrapping things in `act` unnecessarily {#wrapping-things-in-act-unnecessarily}
326326

327-
<span style={{color: '#8a6d3b', fontWeight: 'bold'}}>Importance: medium</span>
327+
<span style={{ color: '#8a6d3b', fontWeight: 'bold' }}>Importance: medium</span>
328328

329329
React Native Testing Library's `userEvent` methods are already wrapped in `act`, so you don't need to wrap them yourself:
330330

@@ -362,7 +362,7 @@ test('updates on press', () => {
362362

363363
## Not using User Event API
364364

365-
<span style={{color: '#8a6d3b', fontWeight: 'bold'}}>Importance: medium</span>
365+
<span style={{ color: '#8a6d3b', fontWeight: 'bold' }}>Importance: medium</span>
366366

367367
`userEvent` provides a more realistic way to simulate user interactions:
368368

@@ -410,7 +410,7 @@ test('uses userEvent', async () => {
410410

411411
## Not querying by text {#not-querying-by-text}
412412

413-
<span style={{color: '#8a6d3b', fontWeight: 'bold'}}>Importance: medium</span>
413+
<span style={{ color: '#8a6d3b', fontWeight: 'bold' }}>Importance: medium</span>
414414

415415
In React Native, text is rendered in `<Text>` components. You should query by the text content that users see:
416416

@@ -435,7 +435,7 @@ test('finds text correctly', () => {
435435

436436
## Not using Testing Library ESLint plugins {#not-using-testing-library-eslint-plugins}
437437

438-
<span style={{color: '#8a6d3b', fontWeight: 'bold'}}>Importance: medium</span>
438+
<span style={{ color: '#8a6d3b', fontWeight: 'bold' }}>Importance: medium</span>
439439

440440
There's an ESLint plugin for Testing Library: [`eslint-plugin-testing-library`](https://github.com/testing-library/eslint-plugin-testing-library). This plugin can help you avoid common mistakes and will automatically fix your code in many cases.
441441

@@ -450,16 +450,14 @@ And configure it in your `eslint.config.js` (flat config):
450450
```js
451451
import testingLibrary from 'eslint-plugin-testing-library';
452452

453-
export default [
454-
testingLibrary.configs['flat/react'],
455-
];
453+
export default [testingLibrary.configs['flat/react']];
456454
```
457455

458456
Note: Unlike React Testing Library, React Native Testing Library has built-in Jest matchers, so you don't need `eslint-plugin-jest-dom`.
459457

460458
## Using `cleanup` {#using-cleanup}
461459

462-
<span style={{color: '#8a6d3b', fontWeight: 'bold'}}>Importance: medium</span>
460+
<span style={{ color: '#8a6d3b', fontWeight: 'bold' }}>Importance: medium</span>
463461

464462
React Native Testing Library automatically cleans up after each test. You don't need to call `cleanup()` manually unless you're using the `pure` export (which doesn't include automatic cleanup).
465463

@@ -479,7 +477,7 @@ But in most cases, you don't need to worry about cleanup at all - it's handled a
479477

480478
## Using `get*` variants as assertions {#using-get-variants-as-assertions}
481479

482-
<span style={{color: '#3c763d', fontWeight: 'bold'}}>Importance: low</span>
480+
<span style={{ color: '#3c763d', fontWeight: 'bold' }}>Importance: low</span>
483481

484482
`getBy*` queries throw errors when elements aren't found, so they work as assertions. However, for better error messages, you might want to combine them with explicit matchers:
485483

@@ -509,7 +507,7 @@ test('uses getBy as assertion', () => {
509507

510508
## Having multiple assertions in a single `waitFor` callback {#having-multiple-assertions-in-a-single-waitfor-callback}
511509

512-
<span style={{color: '#3c763d', fontWeight: 'bold'}}>Importance: low</span>
510+
<span style={{ color: '#3c763d', fontWeight: 'bold' }}>Importance: low</span>
513511

514512
Keep `waitFor` callbacks focused on a single assertion:
515513

@@ -552,7 +550,7 @@ test('waits with single assertion', async () => {
552550

553551
## Using `wrapper` as the variable name {#using-wrapper-as-the-variable-name}
554552

555-
<span style={{color: '#3c763d', fontWeight: 'bold'}}>Importance: low</span>
553+
<span style={{ color: '#3c763d', fontWeight: 'bold' }}>Importance: low</span>
556554

557555
This is not really a "mistake" per se, but it's a common pattern that can be improved. When you use the `wrapper` option in `render`, you might be tempted to name your wrapper component `Wrapper`:
558556

website/docs/13.x/docs/guides/llm-guidelines.mdx

Lines changed: 58 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,26 @@ Actionable guidelines for writing tests with React Native Testing Library (RNTL)
1010
const result = render(<Component />, options?); // Sync in v13
1111
```
1212
13-
| Option | Description |
14-
|--------|-------------|
15-
| `wrapper` | React component to wrap the rendered component (e.g., providers) |
16-
| `createNodeMock` | Function to create mock refs |
17-
18-
| Return | Description |
19-
|--------|-------------|
20-
| `rerender(component)` | Re-render with a new component |
21-
| `unmount()` | Unmount the rendered component |
22-
| `toJSON()` | Get JSON representation for snapshots |
23-
| `debug(options?)` | Print the component tree to console |
24-
| `root` | Root element of the rendered component |
13+
| Option | Description |
14+
| ---------------- | ---------------------------------------------------------------- |
15+
| `wrapper` | React component to wrap the rendered component (e.g., providers) |
16+
| `createNodeMock` | Function to create mock refs |
17+
18+
| Return | Description |
19+
| --------------------- | -------------------------------------- |
20+
| `rerender(component)` | Re-render with a new component |
21+
| `unmount()` | Unmount the rendered component |
22+
| `toJSON()` | Get JSON representation for snapshots |
23+
| `debug(options?)` | Print the component tree to console |
24+
| `root` | Root element of the rendered component |
2525
2626
### screen
2727
2828
**Prefer `screen`** over destructuring from `render()`. Provides all query methods after `render()` is called.
2929
3030
```tsx
3131
render(<Component />);
32-
screen.getByRole('button'); // Access queries via screen
32+
screen.getByRole('button'); // Access queries via screen
3333
```
3434
3535
### renderHook
@@ -38,16 +38,16 @@ screen.getByRole('button'); // Access queries via screen
3838
const { result, rerender, unmount } = renderHook(() => useMyHook(), options?); // Sync in v13
3939
```
4040
41-
| Option | Description |
42-
|--------|-------------|
43-
| `initialProps` | Initial props passed to the hook |
44-
| `wrapper` | React component to wrap the hook (e.g., providers) |
41+
| Option | Description |
42+
| -------------- | -------------------------------------------------- |
43+
| `initialProps` | Initial props passed to the hook |
44+
| `wrapper` | React component to wrap the hook (e.g., providers) |
4545
46-
| Return | Description |
47-
|--------|-------------|
48-
| `result.current` | Current return value of the hook |
49-
| `rerender(props?)` | Re-render hook with new props |
50-
| `unmount()` | Unmount the hook |
46+
| Return | Description |
47+
| ------------------ | -------------------------------- |
48+
| `result.current` | Current return value of the hook |
49+
| `rerender(props?)` | Re-render hook with new props |
50+
| `unmount()` | Unmount the hook |
5151
5252
## Query Selection
5353
@@ -67,26 +67,26 @@ const { result, rerender, unmount } = renderHook(() => useMyHook(), options?);
6767
6868
## Jest Matchers Reference
6969
70-
| Matcher | Description |
71-
|---------|-------------|
72-
| `toBeOnTheScreen()` | Element is present in the element tree |
73-
| `toBeVisible()` | Element is visible (checks style, `aria-hidden`, `accessibilityElementsHidden`, ancestors) |
74-
| `toBeEmptyElement()` | Element has no children or text content |
75-
| `toContainElement(element)` | Element contains another element |
76-
| `toBeEnabled()` | Element is not disabled (checks `aria-disabled`, `accessibilityState`, ancestors) |
77-
| `toBeDisabled()` | Element has `aria-disabled` or `accessibilityState={{ disabled: true }}` (checks ancestors) |
78-
| `toBeBusy()` | Element has `aria-busy` or `accessibilityState={{ busy: true }}` |
79-
| `toBeChecked()` | Element has `aria-checked` or `accessibilityState={{ checked: true }}` |
80-
| `toBePartiallyChecked()` | Element has `aria-checked="mixed"` or `accessibilityState={{ checked: 'mixed' }}` |
81-
| `toBeSelected()` | Element has `aria-selected` or `accessibilityState={{ selected: true }}` |
82-
| `toBeExpanded()` | Element has `aria-expanded` or `accessibilityState={{ expanded: true }}` |
83-
| `toBeCollapsed()` | Element has `aria-expanded={false}` or `accessibilityState={{ expanded: false }}` |
84-
| `toHaveTextContent(text)` | Element has matching text content |
85-
| `toHaveDisplayValue(value)` | TextInput has matching display value |
86-
| `toHaveAccessibleName(name?)` | Element has matching `aria-label`, `accessibilityLabel`, or text content |
87-
| `toHaveAccessibilityValue(value)` | Element has matching `aria-value*` or `accessibilityValue` |
88-
| `toHaveStyle(style)` | Element has matching style |
89-
| `toHaveProp(name, value?)` | Element has prop (use semantic matchers when possible) |
70+
| Matcher | Description |
71+
| --------------------------------- | ------------------------------------------------------------------------------------------- |
72+
| `toBeOnTheScreen()` | Element is present in the element tree |
73+
| `toBeVisible()` | Element is visible (checks style, `aria-hidden`, `accessibilityElementsHidden`, ancestors) |
74+
| `toBeEmptyElement()` | Element has no children or text content |
75+
| `toContainElement(element)` | Element contains another element |
76+
| `toBeEnabled()` | Element is not disabled (checks `aria-disabled`, `accessibilityState`, ancestors) |
77+
| `toBeDisabled()` | Element has `aria-disabled` or `accessibilityState={{ disabled: true }}` (checks ancestors) |
78+
| `toBeBusy()` | Element has `aria-busy` or `accessibilityState={{ busy: true }}` |
79+
| `toBeChecked()` | Element has `aria-checked` or `accessibilityState={{ checked: true }}` |
80+
| `toBePartiallyChecked()` | Element has `aria-checked="mixed"` or `accessibilityState={{ checked: 'mixed' }}` |
81+
| `toBeSelected()` | Element has `aria-selected` or `accessibilityState={{ selected: true }}` |
82+
| `toBeExpanded()` | Element has `aria-expanded` or `accessibilityState={{ expanded: true }}` |
83+
| `toBeCollapsed()` | Element has `aria-expanded={false}` or `accessibilityState={{ expanded: false }}` |
84+
| `toHaveTextContent(text)` | Element has matching text content |
85+
| `toHaveDisplayValue(value)` | TextInput has matching display value |
86+
| `toHaveAccessibleName(name?)` | Element has matching `aria-label`, `accessibilityLabel`, or text content |
87+
| `toHaveAccessibilityValue(value)` | Element has matching `aria-value*` or `accessibilityValue` |
88+
| `toHaveStyle(style)` | Element has matching style |
89+
| `toHaveProp(name, value?)` | Element has prop (use semantic matchers when possible) |
9090
9191
## User Interactions
9292
@@ -98,25 +98,25 @@ const { result, rerender, unmount } = renderHook(() => useMyHook(), options?);
9898
const user = userEvent.setup();
9999
```
100100
101-
| Method | Description |
102-
|--------|-------------|
103-
| `await user.press(element)` | Press an element (triggers `pressIn`, `pressOut`, `press`) |
104-
| `await user.longPress(element, options?)` | Long press with optional `{ duration }` |
101+
| Method | Description |
102+
| ------------------------------------------ | ----------------------------------------------------------------------------------- |
103+
| `await user.press(element)` | Press an element (triggers `pressIn`, `pressOut`, `press`) |
104+
| `await user.longPress(element, options?)` | Long press with optional `{ duration }` |
105105
| `await user.type(element, text, options?)` | Type into TextInput (triggers `focus`, `keyPress`, `change`, `changeText` per char) |
106-
| `await user.clear(element)` | Clear TextInput (select all + backspace) |
107-
| `await user.paste(element, text)` | Paste text into TextInput |
108-
| `await user.scrollTo(element, options)` | Scroll a ScrollView with `{ y }` or `{ x }` offset |
106+
| `await user.clear(element)` | Clear TextInput (select all + backspace) |
107+
| `await user.paste(element, text)` | Paste text into TextInput |
108+
| `await user.scrollTo(element, options)` | Scroll a ScrollView with `{ y }` or `{ x }` offset |
109109
110110
### fireEvent (Low-level, Sync in v13)
111111
112112
Use only when `userEvent` doesn't support the event or when you need direct control.
113113
114-
| Method | Description |
115-
|--------|-------------|
116-
| `fireEvent(element, eventName, ...data)` | Fire any event by name |
117-
| `fireEvent.press(element)` | Fire `onPress` only (no `pressIn`/`pressOut`) |
118-
| `fireEvent.changeText(element, text)` | Fire `onChangeText` directly |
119-
| `fireEvent.scroll(element, eventData)` | Fire `onScroll` with event data |
114+
| Method | Description |
115+
| ---------------------------------------- | --------------------------------------------- |
116+
| `fireEvent(element, eventName, ...data)` | Fire any event by name |
117+
| `fireEvent.press(element)` | Fire `onPress` only (no `pressIn`/`pressOut`) |
118+
| `fireEvent.changeText(element, text)` | Fire `onChangeText` directly |
119+
| `fireEvent.scroll(element, eventData)` | Fire `onScroll` with event data |
120120
121121
## Sync vs Async APIs (v13)
122122
@@ -167,17 +167,8 @@ test('user can submit form', async () => {
167167

168168
return (
169169
<View>
170-
<TextInput
171-
role="textbox"
172-
aria-label="Name"
173-
value={name}
174-
onChangeText={setName}
175-
/>
176-
<Pressable
177-
role="button"
178-
aria-label="Submit"
179-
onPress={() => setSubmitted(true)}
180-
>
170+
<TextInput role="textbox" aria-label="Name" value={name} onChangeText={setName} />
171+
<Pressable role="button" aria-label="Submit" onPress={() => setSubmitted(true)}>
181172
<Text>Submit</Text>
182173
</Pressable>
183174
{submitted && <Text role="alert">Form submitted!</Text>}
@@ -222,7 +213,7 @@ await waitFor(async () => {
222213
});
223214

224215
// accessibility* props instead of ARIA
225-
<Pressable accessibilityRole="button" accessibilityLabel="Submit" />
216+
<Pressable accessibilityRole="button" accessibilityLabel="Submit" />;
226217

227218
// Destructuring from render
228219
const { getByText } = render(<Component />);

0 commit comments

Comments
 (0)