or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-testing.mdasync.mdcomponent-rendering.mdconfiguration.mdelement-queries.mdevent-simulation.mdevents.mdhook-testing.mdhooks.mdindex.mdqueries.mdquick-reference.mdrendering.md

element-queries.mddocs/

0

# Element Queries

1

2

Complete set of query methods for finding elements using accessibility-focused selectors. React Testing Library re-exports all query methods from DOM Testing Library, providing three query variants (get*, query*, find*) for each selector type.

3

4

## Query Types

5

6

### Get Queries

7

8

Queries that throw an error if no element is found. Use for elements that should always be present.

9

10

```typescript { .api }

11

/**

12

* Find element by accessible role

13

* @param role - ARIA role or HTML element role

14

* @param options - Additional filtering options

15

* @returns HTMLElement (throws if not found)

16

*/

17

function getByRole(role: string, options?: ByRoleOptions): HTMLElement;

18

19

/**

20

* Find element by associated label text

21

* @param text - Label text content

22

* @param options - Text matching options

23

* @returns HTMLElement (throws if not found)

24

*/

25

function getByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement;

26

27

/**

28

* Find input element by placeholder text

29

* @param text - Placeholder text content

30

* @param options - Text matching options

31

* @returns HTMLElement (throws if not found)

32

*/

33

function getByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement;

34

35

/**

36

* Find element by text content

37

* @param text - Text content to search for

38

* @param options - Text matching and selector options

39

* @returns HTMLElement (throws if not found)

40

*/

41

function getByText(text: string, options?: SelectorMatcherOptions): HTMLElement;

42

43

/**

44

* Find form element by current display value

45

* @param value - Current input/select/textarea value

46

* @param options - Text matching options

47

* @returns HTMLElement (throws if not found)

48

*/

49

function getByDisplayValue(value: string, options?: MatcherOptions): HTMLElement;

50

51

/**

52

* Find img element by alt text

53

* @param text - Alt attribute content

54

* @param options - Text matching options

55

* @returns HTMLElement (throws if not found)

56

*/

57

function getByAltText(text: string, options?: MatcherOptions): HTMLElement;

58

59

/**

60

* Find element by title attribute

61

* @param title - Title attribute content

62

* @param options - Text matching options

63

* @returns HTMLElement (throws if not found)

64

*/

65

function getByTitle(title: string, options?: MatcherOptions): HTMLElement;

66

67

/**

68

* Find element by test ID attribute

69

* @param testId - Test ID attribute value

70

* @param options - Text matching options

71

* @returns HTMLElement (throws if not found)

72

*/

73

function getByTestId(testId: string, options?: MatcherOptions): HTMLElement;

74

```

75

76

### Query Queries

77

78

Queries that return `null` if no element is found. Use for elements that may or may not be present.

79

80

```typescript { .api }

81

/**

82

* Find element by accessible role, returns null if not found

83

*/

84

function queryByRole(role: string, options?: ByRoleOptions): HTMLElement | null;

85

86

/**

87

* Find element by associated label text, returns null if not found

88

*/

89

function queryByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement | null;

90

91

/**

92

* Find input element by placeholder text, returns null if not found

93

*/

94

function queryByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement | null;

95

96

/**

97

* Find element by text content, returns null if not found

98

*/

99

function queryByText(text: string, options?: SelectorMatcherOptions): HTMLElement | null;

100

101

/**

102

* Find form element by current display value, returns null if not found

103

*/

104

function queryByDisplayValue(value: string, options?: MatcherOptions): HTMLElement | null;

105

106

/**

107

* Find img element by alt text, returns null if not found

108

*/

109

function queryByAltText(text: string, options?: MatcherOptions): HTMLElement | null;

110

111

/**

112

* Find element by title attribute, returns null if not found

113

*/

114

function queryByTitle(title: string, options?: MatcherOptions): HTMLElement | null;

115

116

/**

117

* Find element by test ID attribute, returns null if not found

118

*/

119

function queryByTestId(testId: string, options?: MatcherOptions): HTMLElement | null;

120

```

121

122

### Find Queries

123

124

Async queries that wait for elements to appear in the DOM. Use for elements that appear after asynchronous operations.

125

126

```typescript { .api }

127

/**

128

* Wait for element with accessible role to appear

129

* @param role - ARIA role or HTML element role

130

* @param options - Role filtering options

131

* @param waitForOptions - Wait timing configuration

132

* @returns Promise<HTMLElement> (rejects if not found within timeout)

133

*/

134

function findByRole(

135

role: string,

136

options?: ByRoleOptions,

137

waitForOptions?: WaitForOptions

138

): Promise<HTMLElement>;

139

140

/**

141

* Wait for element with associated label text to appear

142

*/

143

function findByLabelText(

144

text: string,

145

options?: SelectorMatcherOptions,

146

waitForOptions?: WaitForOptions

147

): Promise<HTMLElement>;

148

149

/**

150

* Wait for input element with placeholder text to appear

151

*/

152

function findByPlaceholderText(

153

text: string,

154

options?: MatcherOptions,

155

waitForOptions?: WaitForOptions

156

): Promise<HTMLElement>;

157

158

/**

159

* Wait for element with text content to appear

160

*/

161

function findByText(

162

text: string,

163

options?: SelectorMatcherOptions,

164

waitForOptions?: WaitForOptions

165

): Promise<HTMLElement>;

166

167

/**

168

* Wait for form element with display value to appear

169

*/

170

function findByDisplayValue(

171

value: string,

172

options?: MatcherOptions,

173

waitForOptions?: WaitForOptions

174

): Promise<HTMLElement>;

175

176

/**

177

* Wait for img element with alt text to appear

178

*/

179

function findByAltText(

180

text: string,

181

options?: MatcherOptions,

182

waitForOptions?: WaitForOptions

183

): Promise<HTMLElement>;

184

185

/**

186

* Wait for element with title attribute to appear

187

*/

188

function findByTitle(

189

title: string,

190

options?: MatcherOptions,

191

waitForOptions?: WaitForOptions

192

): Promise<HTMLElement>;

193

194

/**

195

* Wait for element with test ID attribute to appear

196

*/

197

function findByTestId(

198

testId: string,

199

options?: MatcherOptions,

200

waitForOptions?: WaitForOptions

201

): Promise<HTMLElement>;

202

```

203

204

### Multiple Element Queries

205

206

Queries that return arrays of elements instead of single elements.

207

208

```typescript { .api }

209

// Get All queries - throw if none found

210

function getAllByRole(role: string, options?: ByRoleOptions): HTMLElement[];

211

function getAllByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement[];

212

function getAllByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement[];

213

function getAllByText(text: string, options?: SelectorMatcherOptions): HTMLElement[];

214

function getAllByDisplayValue(value: string, options?: MatcherOptions): HTMLElement[];

215

function getAllByAltText(text: string, options?: MatcherOptions): HTMLElement[];

216

function getAllByTitle(title: string, options?: MatcherOptions): HTMLElement[];

217

function getAllByTestId(testId: string, options?: MatcherOptions): HTMLElement[];

218

219

// Query All queries - return empty array if none found

220

function queryAllByRole(role: string, options?: ByRoleOptions): HTMLElement[];

221

function queryAllByLabelText(text: string, options?: SelectorMatcherOptions): HTMLElement[];

222

function queryAllByPlaceholderText(text: string, options?: MatcherOptions): HTMLElement[];

223

function queryAllByText(text: string, options?: SelectorMatcherOptions): HTMLElement[];

224

function queryAllByDisplayValue(value: string, options?: MatcherOptions): HTMLElement[];

225

function queryAllByAltText(text: string, options?: MatcherOptions): HTMLElement[];

226

function queryAllByTitle(title: string, options?: MatcherOptions): HTMLElement[];

227

function queryAllByTestId(testId: string, options?: MatcherOptions): HTMLElement[];

228

229

// Find All queries - wait for elements to appear

230

function findAllByRole(role: string, options?: ByRoleOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

231

function findAllByLabelText(text: string, options?: SelectorMatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

232

function findAllByPlaceholderText(text: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

233

function findAllByText(text: string, options?: SelectorMatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

234

function findAllByDisplayValue(value: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

235

function findAllByAltText(text: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

236

function findAllByTitle(title: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

237

function findAllByTestId(testId: string, options?: MatcherOptions, waitForOptions?: WaitForOptions): Promise<HTMLElement[]>;

238

```

239

240

## Query Options

241

242

### Basic Matcher Options

243

244

```typescript { .api }

245

interface MatcherOptions {

246

/** Whether to match exact text or allow partial matches */

247

exact?: boolean;

248

/** Function to normalize text before matching */

249

normalizer?: (text: string) => string;

250

}

251

```

252

253

### Selector Matcher Options

254

255

```typescript { .api }

256

interface SelectorMatcherOptions extends MatcherOptions {

257

/** CSS selector to limit search scope */

258

selector?: string;

259

}

260

```

261

262

### By Role Options

263

264

```typescript { .api }

265

interface ByRoleOptions extends MatcherOptions {

266

/** Filter by checked state for checkboxes/radios */

267

checked?: boolean;

268

/** Filter by aria-current attribute */

269

current?: boolean | string;

270

/** Filter by expanded state */

271

expanded?: boolean;

272

/** Include elements hidden from accessibility tree */

273

hidden?: boolean;

274

/** Filter by heading level */

275

level?: number;

276

/** Filter by accessible name */

277

name?: string | RegExp;

278

/** Filter by pressed state */

279

pressed?: boolean;

280

/** Filter by selected state */

281

selected?: boolean;

282

}

283

```

284

285

### Wait For Options

286

287

```typescript { .api }

288

interface WaitForOptions {

289

/** Element container to search within */

290

container?: HTMLElement;

291

/** Timeout in milliseconds (default: 1000) */

292

timeout?: number;

293

/** Polling interval in milliseconds (default: 50) */

294

interval?: number;

295

/** Custom error message on timeout */

296

onTimeout?: (error: Error) => Error;

297

}

298

```

299

300

## Usage Examples

301

302

### Basic Query Usage

303

304

```typescript

305

import { render, screen } from "@testing-library/react";

306

307

function LoginForm() {

308

return (

309

<form>

310

<label htmlFor="username">Username</label>

311

<input id="username" placeholder="Enter username" />

312

313

<label htmlFor="password">Password</label>

314

<input id="password" type="password" />

315

316

<button type="submit">Log In</button>

317

</form>

318

);

319

}

320

321

render(<LoginForm />);

322

323

// Find by role (most preferred)

324

const submitButton = screen.getByRole('button', { name: 'Log In' });

325

326

// Find by label text

327

const usernameInput = screen.getByLabelText('Username');

328

329

// Find by placeholder

330

const usernameByPlaceholder = screen.getByPlaceholderText('Enter username');

331

332

// Find by text content

333

const loginButton = screen.getByText('Log In');

334

```

335

336

### Conditional Queries

337

338

```typescript

339

function ConditionalComponent({ showMessage }: { showMessage: boolean }) {

340

return (

341

<div>

342

<h1>App Title</h1>

343

{showMessage && <p>Welcome message</p>}

344

</div>

345

);

346

}

347

348

render(<ConditionalComponent showMessage={false} />);

349

350

// Element that should always be present

351

const title = screen.getByText('App Title');

352

353

// Element that may not be present

354

const message = screen.queryByText('Welcome message');

355

expect(message).toBe(null);

356

357

// Rerender with message

358

rerender(<ConditionalComponent showMessage={true} />);

359

const welcomeMessage = screen.getByText('Welcome message');

360

expect(welcomeMessage).toBeInTheDocument();

361

```

362

363

### Async Queries

364

365

```typescript

366

function AsyncComponent() {

367

const [loading, setLoading] = useState(true);

368

const [data, setData] = useState(null);

369

370

useEffect(() => {

371

setTimeout(() => {

372

setData('Loaded data');

373

setLoading(false);

374

}, 1000);

375

}, []);

376

377

return (

378

<div>

379

{loading ? (

380

<p>Loading...</p>

381

) : (

382

<p>Data: {data}</p>

383

)}

384

</div>

385

);

386

}

387

388

render(<AsyncComponent />);

389

390

// Initially shows loading

391

expect(screen.getByText('Loading...')).toBeInTheDocument();

392

393

// Wait for data to load

394

const dataElement = await screen.findByText('Data: Loaded data');

395

expect(dataElement).toBeInTheDocument();

396

397

// Loading message should be gone

398

expect(screen.queryByText('Loading...')).toBe(null);

399

```

400

401

### Multiple Element Queries

402

403

```typescript

404

function TodoList({ todos }: { todos: string[] }) {

405

return (

406

<ul>

407

{todos.map((todo, index) => (

408

<li key={index}>

409

<span>{todo}</span>

410

<button>Delete</button>

411

</li>

412

))}

413

</ul>

414

);

415

}

416

417

const todos = ['Buy milk', 'Walk dog', 'Write code'];

418

render(<TodoList todos={todos} />);

419

420

// Get all todo items

421

const todoItems = screen.getAllByRole('listitem');

422

expect(todoItems).toHaveLength(3);

423

424

// Get all delete buttons

425

const deleteButtons = screen.getAllByText('Delete');

426

expect(deleteButtons).toHaveLength(3);

427

428

// Get specific todo

429

const milkTodo = screen.getByText('Buy milk');

430

```

431

432

### Advanced Role Queries

433

434

```typescript

435

function DataTable() {

436

return (

437

<table>

438

<thead>

439

<tr>

440

<th>Name</th>

441

<th>Age</th>

442

<th>Active</th>

443

</tr>

444

</thead>

445

<tbody>

446

<tr>

447

<td>John</td>

448

<td>25</td>

449

<td>

450

<input type="checkbox" checked aria-label="John is active" />

451

</td>

452

</tr>

453

<tr>

454

<td>Jane</td>

455

<td>30</td>

456

<td>

457

<input type="checkbox" aria-label="Jane is active" />

458

</td>

459

</tr>

460

</tbody>

461

</table>

462

);

463

}

464

465

render(<DataTable />);

466

467

// Find table

468

const table = screen.getByRole('table');

469

470

// Find column headers

471

const nameHeader = screen.getByRole('columnheader', { name: 'Name' });

472

473

// Find checkboxes by state

474

const checkedBox = screen.getByRole('checkbox', {

475

checked: true,

476

name: 'John is active'

477

});

478

479

const uncheckedBox = screen.getByRole('checkbox', {

480

checked: false,

481

name: 'Jane is active'

482

});

483

```

484

485

### Scoped Queries with within

486

487

```typescript

488

import { within } from "@testing-library/react";

489

490

function UserCard({ user }: { user: { name: string; email: string; role: string } }) {

491

return (

492

<div data-testid="user-card">

493

<h3>{user.name}</h3>

494

<p>{user.email}</p>

495

<span>{user.role}</span>

496

<button>Edit</button>

497

<button>Delete</button>

498

</div>

499

);

500

}

501

502

function UserList({ users }) {

503

return (

504

<div>

505

{users.map(user => (

506

<UserCard key={user.id} user={user} />

507

))}

508

</div>

509

);

510

}

511

512

const users = [

513

{ id: 1, name: 'John', email: 'john@example.com', role: 'Admin' },

514

{ id: 2, name: 'Jane', email: 'jane@example.com', role: 'User' }

515

];

516

517

render(<UserList users={users} />);

518

519

// Get all user cards

520

const userCards = screen.getAllByTestId('user-card');

521

522

// Query within specific card

523

const johnCard = userCards[0];

524

const johnName = within(johnCard).getByText('John');

525

const johnEditButton = within(johnCard).getByText('Edit');

526

527

// Find specific user's card and interact with it

528

const janeCard = screen.getByText('Jane').closest('[data-testid="user-card"]');

529

const janeDeleteButton = within(janeCard).getByText('Delete');

530

```