0
# Quick Reference
1
2
Fast lookup for common React Testing Library patterns.
3
4
## Setup
5
6
```typescript
7
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
8
```
9
10
## Essential Pattern
11
12
```typescript
13
render(<Component />);
14
const element = screen.getByRole('button', { name: /submit/i });
15
fireEvent.click(element);
16
expect(screen.getByText(/success/i)).toBeInTheDocument();
17
```
18
19
## Query Cheat Sheet
20
21
```typescript
22
// Sync queries
23
screen.getByRole('button') // Throws if not found
24
screen.queryByRole('button') // Returns null if not found
25
screen.getAllByRole('button') // Returns array
26
27
// Async queries
28
await screen.findByRole('button') // Waits then returns
29
await screen.findAllByRole('button') // Waits then returns array
30
31
// Common roles
32
screen.getByRole('button', { name: /text/i })
33
screen.getByRole('textbox') // input[type=text], textarea
34
screen.getByRole('checkbox')
35
screen.getByRole('heading', { level: 1 }) // h1
36
screen.getByRole('link')
37
screen.getByRole('img')
38
39
// Form elements
40
screen.getByLabelText('Email')
41
screen.getByPlaceholderText('Enter email')
42
43
// Text content
44
screen.getByText(/hello world/i)
45
46
// Scoped queries
47
within(element).getByRole('button')
48
```
49
50
## Events Cheat Sheet
51
52
```typescript
53
// Click
54
fireEvent.click(element)
55
56
// Input
57
fireEvent.change(input, { target: { value: 'text' } })
58
59
// Keyboard
60
fireEvent.keyDown(element, { key: 'Enter', code: 'Enter' })
61
62
// Focus
63
fireEvent.focus(element)
64
fireEvent.blur(element)
65
66
// Hover
67
fireEvent.mouseEnter(element)
68
fireEvent.mouseLeave(element)
69
70
// Submit
71
fireEvent.submit(form)
72
```
73
74
## Async Cheat Sheet
75
76
```typescript
77
// Wait for element
78
await screen.findByText(/loaded/i)
79
80
// Wait for condition
81
await waitFor(() => {
82
expect(screen.getByText(/done/i)).toBeInTheDocument()
83
})
84
85
// Wait for removal
86
await waitForElementToBeRemoved(() => screen.getByText(/loading/i))
87
88
// Custom timeout
89
await screen.findByText('text', {}, { timeout: 5000 })
90
```
91
92
## Hook Testing
93
94
```typescript
95
const { result } = renderHook(() => useCustomHook())
96
97
act(() => result.current.action())
98
99
expect(result.current.value).toBe(expected)
100
101
// With context
102
renderHook(() => useHook(), {
103
wrapper: ({ children }) => <Provider>{children}</Provider>
104
})
105
```
106
107
## Common Test Patterns
108
109
### Button Click
110
```typescript
111
test('clicks button', () => {
112
render(<Component />)
113
fireEvent.click(screen.getByRole('button', { name: /click me/i }))
114
expect(screen.getByText(/clicked/i)).toBeInTheDocument()
115
})
116
```
117
118
### Form Input
119
```typescript
120
test('fills form', () => {
121
render(<Form />)
122
fireEvent.change(screen.getByLabelText(/email/i), {
123
target: { value: 'test@example.com' }
124
})
125
fireEvent.click(screen.getByRole('button', { name: /submit/i }))
126
expect(screen.getByText(/success/i)).toBeInTheDocument()
127
})
128
```
129
130
### Async Loading
131
```typescript
132
test('loads data', async () => {
133
render(<AsyncComponent />)
134
expect(screen.getByText(/loading/i)).toBeInTheDocument()
135
136
const data = await screen.findByText(/loaded/i)
137
expect(data).toBeInTheDocument()
138
expect(screen.queryByText(/loading/i)).not.toBeInTheDocument()
139
})
140
```
141
142
### Modal
143
```typescript
144
test('opens modal', async () => {
145
render(<App />)
146
fireEvent.click(screen.getByRole('button', { name: /open/i }))
147
148
const modal = await screen.findByRole('dialog')
149
expect(modal).toBeInTheDocument()
150
151
fireEvent.click(within(modal).getByRole('button', { name: /close/i }))
152
await waitForElementToBeRemoved(modal)
153
})
154
```
155
156
### Negative Assertion
157
```typescript
158
test('element not present', () => {
159
render(<Component />)
160
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
161
})
162
```
163
164
## Assertions
165
166
```typescript
167
// Presence
168
expect(element).toBeInTheDocument()
169
expect(element).not.toBeInTheDocument()
170
171
// Text
172
expect(element).toHaveTextContent('text')
173
expect(element).toHaveTextContent(/pattern/i)
174
175
// Value
176
expect(input).toHaveValue('value')
177
178
// Attributes
179
expect(element).toHaveAttribute('attr', 'value')
180
expect(element).toHaveClass('className')
181
182
// State
183
expect(button).toBeEnabled()
184
expect(button).toBeDisabled()
185
expect(checkbox).toBeChecked()
186
expect(input).toHaveFocus()
187
188
// Visibility
189
expect(element).toBeVisible()
190
expect(element).not.toBeVisible()
191
```
192
193
## Custom Render Utility
194
195
```typescript
196
// test-utils.tsx
197
export function renderWithProviders(
198
ui: React.ReactElement,
199
options?: RenderOptions
200
) {
201
return render(ui, {
202
wrapper: ({ children }) => (
203
<Provider>{children}</Provider>
204
),
205
...options
206
})
207
}
208
```
209
210
## Configuration
211
212
```typescript
213
// test-setup.js
214
import { configure } from '@testing-library/react'
215
216
configure({
217
reactStrictMode: true,
218
asyncUtilTimeout: 2000,
219
})
220
```
221
222
## Debugging
223
224
```typescript
225
screen.debug() // Print DOM
226
screen.debug(element) // Print specific element
227
logRoles(container) // Print available roles
228
```
229
230
## Best Practices
231
232
- ✅ Use `screen.getByRole()` as primary query
233
- ✅ Use `findBy*` for async elements
234
- ✅ Use `queryBy*` only for negative assertions
235
- ✅ Use `within()` to scope queries
236
- ✅ Wrap state updates in `act()`
237
- ❌ Don't use `await` with synchronous operations
238
- ❌ Don't destructure `result.current` in hooks
239
- ❌ Avoid `getByTestId` unless necessary
240