or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-testing.mdconfiguration.mdhooks.mdindex.mdinteractions.mdmatchers.mdqueries.mdrendering.md

configuration.mddocs/

0

# Configuration and Setup

1

2

Global configuration options and setup utilities for customizing React Native Testing Library behavior across your test suite, including async timeouts, debugging options, and rendering modes.

3

4

## Capabilities

5

6

### Global Configuration

7

8

Configure library-wide settings that affect all tests in your suite.

9

10

```typescript { .api }

11

/**

12

* Configure global options for React Native Testing Library

13

* @param options - Configuration options to apply

14

*/

15

function configure(options: Partial<Config & ConfigAliasOptions>): void;

16

17

/**

18

* Reset all configuration to default values

19

*/

20

function resetToDefaults(): void;

21

22

/**

23

* Get current configuration settings

24

* @returns Current configuration object

25

*/

26

function getConfig(): Config;

27

28

interface Config {

29

/** Default timeout in milliseconds for waitFor and findBy queries */

30

asyncUtilTimeout: number;

31

32

/** Default value for includeHiddenElements query option */

33

defaultIncludeHiddenElements: boolean;

34

35

/** Default options for debug helper function */

36

defaultDebugOptions?: Partial<DebugOptions>;

37

38

/** Enable/disable concurrent rendering by default */

39

concurrentRoot: boolean;

40

}

41

42

interface ConfigAliasOptions {

43

/** Alias for defaultIncludeHiddenElements (RTL compatibility) */

44

defaultHidden: boolean;

45

}

46

47

interface DebugOptions {

48

/** Function to transform props before displaying */

49

mapProps?: (props: Record<string, any>) => Record<string, any>;

50

51

/** Maximum length of debug output */

52

maxLength?: number;

53

}

54

```

55

56

**Usage Examples:**

57

58

```typescript

59

import { configure, resetToDefaults, getConfig } from "@testing-library/react-native";

60

61

describe("configuration examples", () => {

62

afterEach(() => {

63

// Reset to defaults after each test

64

resetToDefaults();

65

});

66

67

test("async timeout configuration", async () => {

68

// Set longer timeout for slow components

69

configure({ asyncUtilTimeout: 5000 });

70

71

const SlowComponent = () => {

72

const [loaded, setLoaded] = useState(false);

73

74

useEffect(() => {

75

setTimeout(() => setLoaded(true), 3000);

76

}, []);

77

78

return loaded ? <Text>Loaded</Text> : <Text>Loading...</Text>;

79

};

80

81

render(<SlowComponent />);

82

83

// This will use the configured 5 second timeout

84

await screen.findByText("Loaded");

85

86

// Verify configuration was applied

87

expect(getConfig().asyncUtilTimeout).toBe(5000);

88

});

89

90

test("hidden elements configuration", () => {

91

// Include hidden elements by default

92

configure({ defaultIncludeHiddenElements: true });

93

94

render(

95

<View>

96

<Text>Visible text</Text>

97

<Text style={{ opacity: 0 }}>Hidden text</Text>

98

<View accessibilityElementsHidden>

99

<Text>Accessibility hidden</Text>

100

</View>

101

</View>

102

);

103

104

// These queries will now include hidden elements by default

105

const allTexts = screen.getAllByText(/text/);

106

expect(allTexts.length).toBeGreaterThan(1);

107

108

// Can still override per query

109

const visibleOnly = screen.getAllByText(/text/, {

110

includeHiddenElements: false

111

});

112

expect(visibleOnly.length).toBeLessThan(allTexts.length);

113

});

114

115

test("debug options configuration", () => {

116

// Configure debug output

117

configure({

118

defaultDebugOptions: {

119

maxLength: 500,

120

mapProps: (props) => ({

121

...props,

122

// Hide functions in debug output

123

onPress: props.onPress ? "[Function]" : undefined,

124

style: "[Style Object]"

125

})

126

}

127

});

128

129

const MyComponent = () => (

130

<Pressable

131

onPress={() => {}}

132

style={{ backgroundColor: "blue" }}

133

>

134

<Text>Debug me</Text>

135

</Pressable>

136

);

137

138

const { debug } = render(<MyComponent />);

139

140

// Debug will use configured options

141

debug(); // Output will show "[Function]" instead of actual function

142

});

143

144

test("concurrent rendering configuration", () => {

145

// Disable concurrent rendering globally

146

configure({ concurrentRoot: false });

147

148

const AsyncComponent = () => {

149

const [value, setValue] = useState("initial");

150

151

useEffect(() => {

152

setValue("updated");

153

}, []);

154

155

return <Text>{value}</Text>;

156

};

157

158

// This will use legacy rendering mode

159

render(<AsyncComponent />);

160

161

expect(screen.getByText("updated")).toBeOnTheScreen();

162

expect(getConfig().concurrentRoot).toBe(false);

163

});

164

165

test("RTL compatibility aliases", () => {

166

// Using RTL-style alias

167

configure({ defaultHidden: true });

168

169

// Should set defaultIncludeHiddenElements

170

expect(getConfig().defaultIncludeHiddenElements).toBe(true);

171

});

172

});

173

```

174

175

### Test Environment Setup

176

177

Configuration patterns for different test environments and frameworks.

178

179

```typescript { .api }

180

/**

181

* Environment-specific setup utilities

182

*/

183

```

184

185

**Usage Examples:**

186

187

```typescript

188

// jest.config.js or test setup file

189

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

190

191

// Global test suite configuration

192

configure({

193

// Longer timeout for integration tests

194

asyncUtilTimeout: 2000,

195

196

// Include hidden elements for comprehensive testing

197

defaultIncludeHiddenElements: false,

198

199

// Enable concurrent rendering for modern React features

200

concurrentRoot: true,

201

202

// Clean debug output

203

defaultDebugOptions: {

204

maxLength: 1000,

205

mapProps: (props) => {

206

const cleaned = { ...props };

207

208

// Hide complex objects for cleaner output

209

Object.keys(cleaned).forEach(key => {

210

if (typeof cleaned[key] === "function") {

211

cleaned[key] = "[Function]";

212

} else if (key === "style" && typeof cleaned[key] === "object") {

213

cleaned[key] = "[Style]";

214

}

215

});

216

217

return cleaned;

218

}

219

}

220

});

221

222

// Project-specific setup

223

test("project configuration", () => {

224

// Configuration for React Native Paper components

225

configure({

226

defaultDebugOptions: {

227

mapProps: (props) => ({

228

...props,

229

// Paper-specific props cleanup

230

theme: props.theme ? "[Theme]" : undefined,

231

contentStyle: props.contentStyle ? "[Style]" : undefined

232

})

233

}

234

});

235

236

const PaperButton = () => (

237

<Button mode="contained" onPress={() => {}}>

238

Paper Button

239

</Button>

240

);

241

242

const { debug } = render(<PaperButton />);

243

debug(); // Clean output without theme object details

244

});

245

```

246

247

### Auto-Cleanup Configuration

248

249

Configuration for automatic test cleanup behavior.

250

251

```typescript { .api }

252

/**

253

* Auto-cleanup configuration via environment variables and imports

254

*/

255

256

// Standard import with auto-cleanup

257

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

258

259

// Pure import without auto-cleanup

260

import { render } from "@testing-library/react-native/pure";

261

262

// Environment variable to disable auto-cleanup

263

// Set RNTL_SKIP_AUTO_CLEANUP=true to disable automatic cleanup

264

```

265

266

**Usage Examples:**

267

268

```typescript

269

// Standard usage with auto-cleanup (default)

270

describe("auto-cleanup enabled", () => {

271

test("first test", () => {

272

render(<Text>First test</Text>);

273

expect(screen.getByText("First test")).toBeOnTheScreen();

274

// Automatic cleanup happens after this test

275

});

276

277

test("second test", () => {

278

// Screen is clean from previous test

279

render(<Text>Second test</Text>);

280

expect(screen.getByText("Second test")).toBeOnTheScreen();

281

expect(screen.queryByText("First test")).not.toBeOnTheScreen();

282

});

283

});

284

285

// Manual cleanup control

286

describe("manual cleanup control", () => {

287

// Import pure version

288

const { render, cleanup } = require("@testing-library/react-native/pure");

289

290

afterEach(() => {

291

// Manual cleanup after each test

292

cleanup();

293

});

294

295

test("controlled cleanup", () => {

296

render(<Text>Controlled test</Text>);

297

expect(screen.getByText("Controlled test")).toBeOnTheScreen();

298

299

// Could do additional cleanup here if needed

300

cleanup();

301

302

// Screen is now clean

303

expect(screen.queryByText("Controlled test")).not.toBeOnTheScreen();

304

});

305

});

306

307

// Environment variable configuration

308

describe("environment-based cleanup", () => {

309

const originalEnv = process.env.RNTL_SKIP_AUTO_CLEANUP;

310

311

afterAll(() => {

312

// Restore original environment

313

if (originalEnv !== undefined) {

314

process.env.RNTL_SKIP_AUTO_CLEANUP = originalEnv;

315

} else {

316

delete process.env.RNTL_SKIP_AUTO_CLEANUP;

317

}

318

});

319

320

test("disable auto-cleanup via environment", () => {

321

// This would typically be set in test environment configuration

322

process.env.RNTL_SKIP_AUTO_CLEANUP = "true";

323

324

// Re-import would be needed to pick up env change

325

// In practice, this is set before importing the library

326

327

render(<Text>No auto cleanup</Text>);

328

// Manual cleanup required when env var is set

329

});

330

});

331

```

332

333

### Debug Configuration

334

335

Advanced debugging configuration for test development and troubleshooting.

336

337

```typescript { .api }

338

/**

339

* Debug configuration options

340

*/

341

interface DebugOptions {

342

/** Transform props before displaying */

343

mapProps?: (props: Record<string, any>) => Record<string, any>;

344

345

/** Maximum length of debug output */

346

maxLength?: number;

347

}

348

349

/**

350

* Debug function type

351

*/

352

interface DebugFunction {

353

(element?: ReactTestInstance, maxLength?: number, options?: DebugOptions): void;

354

}

355

```

356

357

**Usage Examples:**

358

359

```typescript

360

test("debug configuration examples", () => {

361

// Component with complex props

362

const ComplexComponent = () => (

363

<View>

364

<Pressable

365

onPress={() => console.log("pressed")}

366

style={{

367

backgroundColor: "blue",

368

padding: 10,

369

borderRadius: 5

370

}}

371

testID="complex-button"

372

>

373

<Text>Complex Button</Text>

374

</Pressable>

375

<FlatList

376

data={[1, 2, 3]}

377

renderItem={({ item }) => <Text key={item}>Item {item}</Text>}

378

keyExtractor={(item) => item.toString()}

379

/>

380

</View>

381

);

382

383

const { debug } = render(<ComplexComponent />);

384

385

// Default debug output (might be verbose)

386

debug();

387

388

// Limited length debug

389

debug(undefined, 200);

390

391

// Custom props mapping

392

debug(undefined, undefined, {

393

mapProps: (props) => ({

394

...props,

395

// Simplify complex props

396

onPress: props.onPress ? "[Function]" : undefined,

397

style: props.style ? "[Style Object]" : undefined,

398

data: props.data ? `[Array of ${props.data.length}]` : undefined,

399

renderItem: props.renderItem ? "[Render Function]" : undefined

400

})

401

});

402

403

// Debug specific element

404

const button = screen.getByTestId("complex-button");

405

debug(button, 500, {

406

mapProps: (props) => ({

407

testID: props.testID,

408

onPress: "[Function]",

409

style: "[Simplified]"

410

})

411

});

412

});

413

414

test("debug configuration per test suite", () => {

415

// Suite-specific debug configuration

416

const originalConfig = getConfig();

417

418

configure({

419

defaultDebugOptions: {

420

maxLength: 300,

421

mapProps: (props) => {

422

// Project-specific prop cleaning

423

return Object.keys(props).reduce((clean, key) => {

424

if (key.startsWith("accessibility")) {

425

clean[key] = props[key];

426

} else if (typeof props[key] === "function") {

427

clean[key] = `[${key}Function]`;

428

} else if (key === "children" && Array.isArray(props[key])) {

429

clean[key] = `[${props[key].length} children]`;

430

} else {

431

clean[key] = props[key];

432

}

433

return clean;

434

}, {});

435

}

436

}

437

});

438

439

const TestComponent = () => (

440

<View accessibilityLabel="Test container">

441

<Text>Child 1</Text>

442

<Text>Child 2</Text>

443

<Pressable onPress={() => {}} accessibilityRole="button">

444

<Text>Button</Text>

445

</Pressable>

446

</View>

447

);

448

449

const { debug } = render(<TestComponent />);

450

451

// Uses configured debug options

452

debug();

453

454

// Restore original config

455

configure(originalConfig);

456

});

457

```

458

459

### Performance Configuration

460

461

Configuration options for optimizing test performance.

462

463

```typescript { .api }

464

/**

465

* Performance-related configuration

466

*/

467

```

468

469

**Usage Examples:**

470

471

```typescript

472

describe("performance configuration", () => {

473

test("optimized for fast tests", () => {

474

configure({

475

// Shorter timeout for unit tests

476

asyncUtilTimeout: 500,

477

478

// Disable concurrent rendering for predictable timing

479

concurrentRoot: false,

480

481

// Minimal debug output

482

defaultDebugOptions: {

483

maxLength: 100,

484

mapProps: (props) => ({ testID: props.testID })

485

}

486

});

487

488

const FastComponent = () => {

489

const [value, setValue] = useState("initial");

490

491

useEffect(() => {

492

// Fast update

493

setTimeout(() => setValue("updated"), 10);

494

}, []);

495

496

return <Text testID="fast-text">{value}</Text>;

497

};

498

499

render(<FastComponent />);

500

501

// Fast assertion with short timeout

502

return screen.findByText("updated");

503

});

504

505

test("optimized for integration tests", () => {

506

configure({

507

// Longer timeout for complex interactions

508

asyncUtilTimeout: 10000,

509

510

// Enable concurrent rendering for realistic testing

511

concurrentRoot: true,

512

513

// Include hidden elements for comprehensive testing

514

defaultIncludeHiddenElements: true,

515

516

// Detailed debug output for troubleshooting

517

defaultDebugOptions: {

518

maxLength: 2000

519

}

520

});

521

522

const IntegrationComponent = () => {

523

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

524

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

525

526

useEffect(() => {

527

// Simulate slow API call

528

setTimeout(() => {

529

setData("Integration data");

530

setLoading(false);

531

}, 1000);

532

}, []);

533

534

return loading ? (

535

<Text>Loading integration test...</Text>

536

) : (

537

<Text testID="integration-result">{data}</Text>

538

);

539

};

540

541

render(<IntegrationComponent />);

542

543

// Long timeout for integration test

544

return screen.findByTestId("integration-result");

545

});

546

547

test("memory-conscious configuration", () => {

548

configure({

549

// Compact debug output to reduce memory usage

550

defaultDebugOptions: {

551

maxLength: 50,

552

mapProps: () => ({ "[props]": "..." }) // Minimal prop display

553

}

554

});

555

556

// Large component tree

557

const LargeComponent = () => (

558

<View>

559

{Array.from({ length: 100 }, (_, i) => (

560

<Text key={i} testID={`item-${i}`}>

561

Item {i}

562

</Text>

563

))}

564

</View>

565

);

566

567

const { debug } = render(<LargeComponent />);

568

569

// Compact debug output

570

debug();

571

572

// Test still works normally

573

expect(screen.getByTestId("item-0")).toBeOnTheScreen();

574

expect(screen.getByTestId("item-99")).toBeOnTheScreen();

575

});

576

});

577

```

578

579

### Environment Detection and Adaptation

580

581

Configuration that adapts to different testing environments.

582

583

```typescript { .api }

584

/**

585

* Environment-aware configuration

586

*/

587

```

588

589

**Usage Examples:**

590

591

```typescript

592

// Test environment detection and configuration

593

describe("environment-aware configuration", () => {

594

test("CI environment configuration", () => {

595

const isCI = process.env.CI === "true";

596

597

configure({

598

// Longer timeouts in CI environments

599

asyncUtilTimeout: isCI ? 10000 : 2000,

600

601

// Disable concurrent rendering in CI for stability

602

concurrentRoot: !isCI,

603

604

// More verbose debugging in CI

605

defaultDebugOptions: {

606

maxLength: isCI ? 5000 : 1000

607

}

608

});

609

610

const EnvironmentComponent = () => {

611

const [env, setEnv] = useState("unknown");

612

613

useEffect(() => {

614

// Simulate environment detection

615

setTimeout(() => {

616

setEnv(isCI ? "CI" : "local");

617

}, isCI ? 500 : 100);

618

}, []);

619

620

return <Text testID="env-indicator">Environment: {env}</Text>;

621

};

622

623

render(<EnvironmentComponent />);

624

625

// Timeout will be appropriate for environment

626

return screen.findByText(/Environment: (CI|local)/);

627

});

628

629

test("jest environment configuration", () => {

630

const isJest = typeof jest !== "undefined";

631

632

if (isJest) {

633

configure({

634

defaultDebugOptions: {

635

mapProps: (props) => ({

636

...props,

637

// Jest-specific prop handling

638

onPress: props.onPress ? "[Jest Mock Function]" : undefined

639

})

640

}

641

});

642

}

643

644

const JestComponent = () => {

645

const mockFn = isJest ? jest.fn() : () => {};

646

647

return (

648

<Pressable onPress={mockFn} testID="jest-button">

649

<Text>Jest Button</Text>

650

</Pressable>

651

);

652

};

653

654

const { debug } = render(<JestComponent />);

655

656

if (isJest) {

657

debug(); // Will show "[Jest Mock Function]"

658

}

659

660

expect(screen.getByTestId("jest-button")).toBeOnTheScreen();

661

});

662

663

test("development vs production configuration", () => {

664

const isDev = process.env.NODE_ENV !== "production";

665

666

configure({

667

defaultDebugOptions: {

668

maxLength: isDev ? 2000 : 500,

669

mapProps: isDev

670

? undefined // Full props in development

671

: (props) => ({ testID: props.testID }) // Minimal in production

672

}

673

});

674

675

const DevComponent = () => (

676

<View

677

testID="dev-component"

678

style={{ padding: 10 }}

679

accessibilityLabel="Development component"

680

>

681

<Text>Development Component</Text>

682

</View>

683

);

684

685

const { debug } = render(<DevComponent />);

686

687

// Debug verbosity depends on environment

688

debug();

689

690

expect(screen.getByTestId("dev-component")).toBeOnTheScreen();

691

});

692

});

693

```