Skip to content

Commit c1704ee

Browse files
committed
tweaks
1 parent b494f1a commit c1704ee

File tree

2 files changed

+31
-66
lines changed

2 files changed

+31
-66
lines changed

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

Lines changed: 30 additions & 66 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-
**Importance: high**
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

@@ -48,9 +48,9 @@ test('finds input by label', async () => {
4848
});
4949
```
5050

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

53-
**Importance: high**
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

@@ -88,11 +88,11 @@ Common roles in React Native include:
8888
- `radio` - radio buttons
8989
- And more...
9090

91-
Note: React Native supports both ARIA-compatible (`role`) and traditional (`accessibilityRole`) props. Prefer `role` for consistency with web standards.
91+
Note: React Native supports both ARIA-compatible (`role`) and legacy (`accessibilityRole`) props. Prefer `role` for consistency with web standards.
9292

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

95-
**Importance: high**
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

@@ -125,9 +125,9 @@ Common matchers include:
125125
- `toHaveAccessibleName()` - checks accessible name
126126
- And more...
127127

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

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

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

@@ -154,9 +154,9 @@ test('checks non-existence', async () => {
154154
});
155155
```
156156

157-
## Using `waitFor` to wait for elements that can be queried with `find\*` {#using-waitfor-to-wait-for-elements-that-can-be-queried-with-find}
157+
## 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-
**Importance: high**
159+
<span style={{color: '#a94442', fontWeight: 'bold'}}>Importance: high</span>
160160

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

@@ -188,45 +188,9 @@ test('waits for element', async () => {
188188
});
189189
```
190190

191-
## Adding `aria-*`, `role`, and other accessibility attributes incorrectly {#adding-aria-role-and-other-accessibility-attributes-incorrectly}
192-
193-
**Importance: high**
194-
195-
React Native supports ARIA-compatible attributes. Use them correctly:
196-
197-
```tsx
198-
import { Pressable, Text } from 'react-native';
199-
import { render, screen } from '@testing-library/react-native';
200-
201-
test('uses accessibility attributes correctly', async () => {
202-
await render(
203-
<Pressable role="button" aria-label="Submit" aria-disabled>
204-
<Text>Submit</Text>
205-
</Pressable>
206-
);
207-
208-
// ✅ Good - uses ARIA attributes
209-
const button = screen.getByRole('button', { name: 'Submit' });
210-
expect(button).toBeDisabled();
211-
});
212-
```
213-
214-
**Prefer ARIA attributes:**
215-
216-
- `role` instead of `accessibilityRole`
217-
- `aria-label` instead of `accessibilityLabel`
218-
- `aria-labelledby` instead of `accessibilityLabelledBy`
219-
- `aria-disabled` instead of `accessibilityState={{ disabled: true }}`
220-
- `aria-checked` instead of `accessibilityState={{ checked: true }}`
221-
- `aria-selected` instead of `accessibilityState={{ selected: true }}`
222-
- `aria-expanded` instead of `accessibilityState={{ expanded: true }}`
223-
- `aria-busy` instead of `accessibilityState={{ busy: true }}`
224-
225-
Both ARIA-compatible and traditional props are supported, but ARIA attributes are preferred for consistency with web standards.
226-
227191
## Performing side-effects in `waitFor` {#performing-side-effects-in-waitfor}
228192

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

231195
Don't perform side-effects in `waitFor` callbacks:
232196

@@ -267,9 +231,9 @@ test('avoids side effects in waitFor', async () => {
267231

268232
## Using `container` to query for elements {#using-container-to-query-for-elements}
269233

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

272-
React Native doesn't have a DOM, so there's no `container.querySelector()`. Instead, React Native Testing Library provides a `container` object that has a `queryAll` method, but you should avoid using it directly:
236+
React Native Testing Library provides a `container` object that has a `queryAll` method, but you should avoid using it directly:
273237

274238
```tsx
275239
import { View, Text } from 'react-native';
@@ -294,7 +258,7 @@ Instead, use the proper query methods from `screen` or the `render` result. The
294258

295259
## Passing an empty callback to `waitFor` {#passing-an-empty-callback-to-waitfor}
296260

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

299263
Don't pass an empty callback to `waitFor`:
300264

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

318282
## Not using `screen` {#not-using-screen}
319283

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

322286
You can get all the queries from the `render` result:
323287

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

361325
## Wrapping things in `act` unnecessarily {#wrapping-things-in-act-unnecessarily}
362326

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

365329
React Native Testing Library's `render`, `renderHook`, `userEvent`, and `fireEvent` are already wrapped in `act`, so you don't need to wrap them yourself:
366330

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

399363
## Not using User Event API
400364

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

403367
`userEvent` provides a more realistic way to simulate user interactions:
404368

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

447411
## Not querying by text {#not-querying-by-text}
448412

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

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

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

472436
## Not using Testing Library ESLint plugins {#not-using-testing-library-eslint-plugins}
473437

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

476440
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.
477441

@@ -481,19 +445,21 @@ You can install it with:
481445
yarn add --dev eslint-plugin-testing-library
482446
```
483447

484-
And configure it in your ESLint config:
448+
And configure it in your `eslint.config.js` (flat config):
485449

486-
```json
487-
{
488-
"extends": ["plugin:testing-library/react"]
489-
}
450+
```js
451+
import testingLibrary from 'eslint-plugin-testing-library';
452+
453+
export default [
454+
testingLibrary.configs['flat/react'],
455+
];
490456
```
491457

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

494460
## Using `cleanup` {#using-cleanup}
495461

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

498464
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).
499465

@@ -511,9 +477,9 @@ test('does not cleanup', async () => {
511477

512478
But in most cases, you don't need to worry about cleanup at all - it's handled automatically.
513479

514-
## Using `get\*` variants as assertions {#using-get-variants-as-assertions}
480+
## Using `get*` variants as assertions {#using-get-variants-as-assertions}
515481

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

518484
`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:
519485

@@ -543,7 +509,7 @@ test('uses getBy as assertion', async () => {
543509

544510
## Having multiple assertions in a single `waitFor` callback {#having-multiple-assertions-in-a-single-waitfor-callback}
545511

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

548514
Keep `waitFor` callbacks focused on a single assertion:
549515

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

587553
## Using `wrapper` as the variable name {#using-wrapper-as-the-variable-name}
588554

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

591557
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`:
592558

@@ -620,6 +586,4 @@ The key principles to remember:
620586
5. **Follow accessibility best practices** - Prefer ARIA attributes (`role`, `aria-label`) over `accessibility*` props
621587
6. **Organize code well** - Use `screen` over destructuring, prefer `userEvent` over `fireEvent`, and don't use `cleanup()`
622588

623-
For detailed guidelines and examples, see the [LLM Guidelines](llm-guidelines) document.
624-
625589
By following these principles, your tests will be more maintainable, accessible, and reliable.

website/rspress.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ const sidebar14x = {
230230
items: [
231231
{ text: 'How to Query', link: '/14.x/docs/guides/how-to-query' },
232232
{ text: 'Common Mistakes', link: '/14.x/docs/guides/common-mistakes' },
233+
{ text: 'LLM Guidelines', link: '/14.x/docs/guides/llm-guidelines' },
233234
{ text: 'Troubleshooting', link: '/14.x/docs/guides/troubleshooting' },
234235
{ text: 'FAQ', link: '/14.x/docs/guides/faq' },
235236
{ text: 'Community Resources', link: '/14.x/docs/guides/community-resources' },

0 commit comments

Comments
 (0)