or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-utilities.mdasync.mdconfig.mdconfiguration.mddebugging.mdevents.mdindex.mdqueries.mdquery-helpers.mdrole-utilities.mdscreen.mdutilities.mdwithin.md

configuration.mddocs/

0

# Configuration

1

2

Configuration system for customizing DOM Testing Library behavior, timeouts, error handling, and debugging features. Allows global configuration of library defaults and behavior patterns.

3

4

## Capabilities

5

6

### Configuration Management

7

8

Configure global library behavior and settings.

9

10

```typescript { .api }

11

function configure(configDelta: ConfigFn | Partial<Config>): void;

12

13

function getConfig(): Config;

14

15

interface Config {

16

/** Attribute name for test IDs (default: "data-testid") */

17

testIdAttribute: string;

18

19

/** Wrapper function for async utilities */

20

asyncWrapper(cb: (...args: any[]) => any): Promise<any>;

21

22

/** Wrapper function for event handlers */

23

eventWrapper(cb: (...args: any[]) => any): void;

24

25

/** Default timeout for async utilities in milliseconds (default: 1000) */

26

asyncUtilTimeout: number;

27

28

/** Whether computed styles support pseudo-elements (default: false) */

29

computedStyleSupportsPseudoElements: boolean;

30

31

/** Default value for hidden option in queries (default: false) */

32

defaultHidden: boolean;

33

34

/** Default value for ignore option in ByText queries */

35

defaultIgnore: string;

36

37

/** Whether to show original stack traces in errors (default: false) */

38

showOriginalStackTrace: boolean;

39

40

/** Whether to throw suggestion errors (default: false) */

41

throwSuggestions: boolean;

42

43

/** Custom error generator for element not found errors */

44

getElementError: (message: string | null, container: Element) => Error;

45

46

/** UNSTABLE: Wrapper for timer advancement in fake timer scenarios */

47

unstable_advanceTimersWrapper(cb: (...args: unknown[]) => unknown): unknown;

48

}

49

50

type ConfigFn = (existingConfig: Config) => Partial<Config>;

51

```

52

53

**Usage Examples:**

54

55

```typescript

56

import { configure, getConfig } from "@testing-library/dom";

57

58

// Basic configuration

59

configure({

60

testIdAttribute: 'data-cy', // Use Cypress convention

61

asyncUtilTimeout: 5000, // Increase default timeout

62

defaultHidden: true, // Include hidden elements by default

63

});

64

65

// Function-based configuration

66

configure((existingConfig) => ({

67

asyncUtilTimeout: existingConfig.asyncUtilTimeout * 2, // Double current timeout

68

defaultIgnore: 'script, style, svg', // Ignore more elements

69

}));

70

71

// Get current configuration

72

const currentConfig = getConfig();

73

console.log('Current testId attribute:', currentConfig.testIdAttribute);

74

console.log('Current timeout:', currentConfig.asyncUtilTimeout);

75

76

// Custom async wrapper for testing framework integration

77

configure({

78

asyncWrapper: async (cb) => {

79

// Add custom async handling, logging, etc.

80

console.log('Starting async operation');

81

try {

82

const result = await cb();

83

console.log('Async operation completed');

84

return result;

85

} catch (error) {

86

console.log('Async operation failed:', error);

87

throw error;

88

}

89

},

90

});

91

92

// Custom event wrapper

93

configure({

94

eventWrapper: (cb) => {

95

// Wrap all event handlers

96

try {

97

cb();

98

} catch (error) {

99

console.log('Event handler error:', error);

100

throw error;

101

}

102

},

103

});

104

105

// Enhanced error reporting

106

configure({

107

showOriginalStackTrace: true,

108

getElementError: (message, container) => {

109

// Custom error with additional context

110

const error = new Error(message || 'Element not found');

111

error.name = 'TestingLibraryElementError';

112

113

// Add container information

114

if (container) {

115

error.container = container;

116

error.containerHTML = container.innerHTML;

117

}

118

119

return error;

120

},

121

});

122

123

// Framework-specific configuration

124

// For Jest

125

configure({

126

asyncWrapper: async (cb) => {

127

// Integrate with Jest's async handling

128

return cb();

129

},

130

});

131

132

// For testing with fake timers

133

configure({

134

unstable_advanceTimersWrapper: (cb) => {

135

const originalSetTimeout = global.setTimeout;

136

// Custom timer handling logic

137

return cb();

138

},

139

});

140

```

141

142

### Test ID Configuration

143

144

Customize the attribute used for test IDs.

145

146

```typescript

147

// Default configuration (data-testid)

148

const element = getByTestId(container, 'submit-button');

149

// Looks for: <button data-testid="submit-button">

150

151

// Configure for Cypress convention

152

configure({ testIdAttribute: 'data-cy' });

153

const element = getByTestId(container, 'submit-button');

154

// Now looks for: <button data-cy="submit-button">

155

156

// Configure for custom attribute

157

configure({ testIdAttribute: 'test-id' });

158

const element = getByTestId(container, 'submit-button');

159

// Now looks for: <button test-id="submit-button">

160

161

// Multiple environment setup

162

if (process.env.E2E_FRAMEWORK === 'cypress') {

163

configure({ testIdAttribute: 'data-cy' });

164

} else if (process.env.E2E_FRAMEWORK === 'playwright') {

165

configure({ testIdAttribute: 'data-pw' });

166

} else {

167

configure({ testIdAttribute: 'data-testid' });

168

}

169

```

170

171

### Timeout Configuration

172

173

Adjust default timeouts for async operations.

174

175

```typescript

176

// Increase timeout for slower CI environments

177

if (process.env.CI) {

178

configure({ asyncUtilTimeout: 10000 }); // 10 seconds

179

} else {

180

configure({ asyncUtilTimeout: 3000 }); // 3 seconds for local

181

}

182

183

// Per-test timeout override

184

await waitFor(() => {

185

expect(getByText(container, "Slow operation complete")).toBeInTheDocument();

186

}, { timeout: 15000 }); // Override global setting

187

188

// Get current timeout

189

const config = getConfig();

190

console.log(`Current timeout: ${config.asyncUtilTimeout}ms`);

191

```

192

193

### Debug Configuration

194

195

Control debugging and error reporting behavior.

196

197

```typescript

198

// Enable detailed error messages

199

configure({

200

showOriginalStackTrace: true,

201

throwSuggestions: true, // Throw errors for better queries

202

});

203

204

// Custom error handling

205

configure({

206

getElementError: (message, container) => {

207

const error = new Error(message);

208

209

// Add debugging information

210

if (container) {

211

error.debugInfo = {

212

containerTag: container.tagName,

213

containerClass: container.className,

214

containerChildren: container.children.length,

215

availableText: container.textContent?.slice(0, 100),

216

};

217

}

218

219

return error;

220

},

221

});

222

223

// Development vs production configuration

224

if (process.env.NODE_ENV === 'development') {

225

configure({

226

showOriginalStackTrace: true,

227

throwSuggestions: true,

228

});

229

} else {

230

configure({

231

showOriginalStackTrace: false,

232

throwSuggestions: false,

233

});

234

}

235

```

236

237

### Framework Integration

238

239

Configure for specific testing frameworks and environments.

240

241

```typescript

242

// React Testing Library integration

243

configure({

244

asyncWrapper: async (cb) => {

245

// React-specific async handling

246

return cb();

247

},

248

eventWrapper: (cb) => {

249

// React event handling

250

act(() => {

251

cb();

252

});

253

},

254

});

255

256

// Vue Testing Library integration

257

configure({

258

asyncWrapper: async (cb) => {

259

await nextTick();

260

return cb();

261

},

262

});

263

264

// Angular Testing Library integration

265

configure({

266

asyncWrapper: async (cb) => {

267

await fixture.whenStable();

268

return cb();

269

},

270

});

271

272

// JSDOM environment configuration

273

configure({

274

computedStyleSupportsPseudoElements: false, // JSDOM limitation

275

});

276

277

// Real browser environment

278

configure({

279

computedStyleSupportsPseudoElements: true,

280

});

281

```

282

283

### Accessibility Configuration

284

285

Configure accessibility-related behavior.

286

287

```typescript

288

// Include hidden elements by default for accessibility testing

289

configure({

290

defaultHidden: true,

291

});

292

293

// Now queries include hidden elements unless explicitly excluded

294

const hiddenButton = getByRole(container, 'button'); // Includes hidden buttons

295

const visibleButton = getByRole(container, 'button', { hidden: false }); // Explicit override

296

297

// Configure text matching to ignore certain elements

298

configure({

299

defaultIgnore: 'script, style, svg, [aria-hidden="true"]',

300

});

301

302

// Text queries now ignore these elements by default

303

const text = getByText(container, 'Content'); // Ignores text in <script>, <style>, etc.

304

```

305

306

### Advanced Configuration

307

308

Complex configuration patterns for specific use cases.

309

310

```typescript

311

// Multi-environment configuration

312

const configureForEnvironment = () => {

313

const baseConfig = {

314

showOriginalStackTrace: process.env.NODE_ENV === 'development',

315

throwSuggestions: process.env.NODE_ENV === 'development',

316

};

317

318

if (process.env.TEST_ENV === 'ci') {

319

return {

320

...baseConfig,

321

asyncUtilTimeout: 10000,

322

defaultIgnore: 'script, style, svg, noscript',

323

};

324

}

325

326

if (process.env.TEST_ENV === 'accessibility') {

327

return {

328

...baseConfig,

329

defaultHidden: true,

330

throwSuggestions: true,

331

};

332

}

333

334

return baseConfig;

335

};

336

337

configure(configureForEnvironment());

338

339

// Conditional configuration

340

configure((existingConfig) => {

341

const updates = {};

342

343

// Increase timeout for slow tests

344

if (process.env.SLOW_TESTS) {

345

updates.asyncUtilTimeout = existingConfig.asyncUtilTimeout * 3;

346

}

347

348

// Custom test ID for specific test suites

349

if (process.env.TEST_SUITE === 'e2e') {

350

updates.testIdAttribute = 'data-e2e';

351

}

352

353

return updates;

354

});

355

356

// Restore configuration

357

const originalConfig = getConfig();

358

359

// Temporarily change config

360

configure({ asyncUtilTimeout: 500 });

361

362

// ... run tests ...

363

364

// Restore

365

configure(originalConfig);

366

```

367

368

## Configuration Best Practices

369

370

### Global Setup

371

372

```typescript

373

// test-setup.js

374

import { configure } from '@testing-library/dom';

375

376

// Global configuration for all tests

377

configure({

378

testIdAttribute: 'data-testid',

379

asyncUtilTimeout: process.env.CI ? 10000 : 5000,

380

showOriginalStackTrace: process.env.NODE_ENV === 'development',

381

throwSuggestions: process.env.NODE_ENV === 'development',

382

defaultIgnore: 'script, style, svg',

383

});

384

```

385

386

### Per-Test Configuration

387

388

```typescript

389

// Individual test file

390

import { configure, getConfig } from '@testing-library/dom';

391

392

describe('Slow operations', () => {

393

let originalConfig;

394

395

beforeAll(() => {

396

originalConfig = getConfig();

397

configure({ asyncUtilTimeout: 15000 });

398

});

399

400

afterAll(() => {

401

configure(originalConfig);

402

});

403

404

test('handles slow async operation', async () => {

405

// Tests run with increased timeout

406

});

407

});

408

```

409

410

### Environment Detection

411

412

```typescript

413

// config/testing-library.js

414

import { configure } from '@testing-library/dom';

415

416

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

417

const isDevelopment = process.env.NODE_ENV === 'development';

418

const isJSDOM = typeof window !== 'undefined' && !window.navigator.userAgent.includes('Chrome');

419

420

configure({

421

asyncUtilTimeout: isCI ? 10000 : 5000,

422

showOriginalStackTrace: isDevelopment,

423

throwSuggestions: isDevelopment,

424

computedStyleSupportsPseudoElements: !isJSDOM,

425

defaultHidden: false,

426

testIdAttribute: 'data-testid',

427

});

428

```

429

430

## Types

431

432

```typescript { .api }

433

interface Config {

434

testIdAttribute: string;

435

unstable_advanceTimersWrapper(cb: (...args: unknown[]) => unknown): unknown;

436

asyncWrapper(cb: (...args: any[]) => any): Promise<any>;

437

eventWrapper(cb: (...args: any[]) => any): void;

438

asyncUtilTimeout: number;

439

computedStyleSupportsPseudoElements: boolean;

440

defaultHidden: boolean;

441

defaultIgnore: string;

442

showOriginalStackTrace: boolean;

443

throwSuggestions: boolean;

444

getElementError: (message: string | null, container: Element) => Error;

445

}

446

447

interface ConfigFn {

448

(existingConfig: Config): Partial<Config>;

449

}

450

```