Skip to content

Commit 932c547

Browse files
feature: configure API from DTL (#1141)
1 parent 3bce908 commit 932c547

File tree

7 files changed

+119
-3
lines changed

7 files changed

+119
-3
lines changed

src/__tests__/config.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { getConfig, configure, resetToDefaults } from '../config';
2+
3+
beforeEach(() => {
4+
resetToDefaults();
5+
});
6+
7+
test('getConfig() returns existing configuration', () => {
8+
expect(getConfig().asyncUtilTimeout).toEqual(1000);
9+
});
10+
11+
test('configure() overrides existing config values', () => {
12+
configure({ asyncUtilTimeout: 5000 });
13+
expect(getConfig().asyncUtilTimeout).toEqual(5000);
14+
});
15+
16+
test('resetToDefaults() resets config to defaults', () => {
17+
configure({ asyncUtilTimeout: 5000 });
18+
expect(getConfig().asyncUtilTimeout).toEqual(5000);
19+
20+
resetToDefaults();
21+
expect(getConfig().asyncUtilTimeout).toEqual(1000);
22+
});

src/__tests__/waitFor.test.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
import { Text, TouchableOpacity, View, Pressable } from 'react-native';
3-
import { fireEvent, render, waitFor } from '..';
3+
import { fireEvent, render, waitFor, configure, resetToDefaults } from '..';
44

55
class Banana extends React.Component<any> {
66
changeFresh = () => {
@@ -19,6 +19,10 @@ class Banana extends React.Component<any> {
1919
}
2020
}
2121

22+
beforeEach(() => {
23+
resetToDefaults();
24+
});
25+
2226
class BananaContainer extends React.Component<{}, any> {
2327
state = { fresh: false };
2428

@@ -64,6 +68,32 @@ test('waits for element until timeout is met', async () => {
6468
await waitFor(() => getByText('Fresh'));
6569
});
6670

71+
test('waitFor defaults to asyncWaitTimeout config option', async () => {
72+
configure({ asyncUtilTimeout: 100 });
73+
const { getByText } = render(<BananaContainer />);
74+
75+
fireEvent.press(getByText('Change freshness!'));
76+
await expect(waitFor(() => getByText('Fresh'))).rejects.toThrow();
77+
78+
// Async action ends after 300ms and we only waited 100ms, so we need to wait
79+
// for the remaining async actions to finish
80+
await waitFor(() => getByText('Fresh'), { timeout: 1000 });
81+
});
82+
83+
test('waitFor timeout option takes precendence over `asyncWaitTimeout` config option', async () => {
84+
configure({ asyncUtilTimeout: 2000 });
85+
const { getByText } = render(<BananaContainer />);
86+
87+
fireEvent.press(getByText('Change freshness!'));
88+
await expect(
89+
waitFor(() => getByText('Fresh'), { timeout: 100 })
90+
).rejects.toThrow();
91+
92+
// Async action ends after 300ms and we only waited 100ms, so we need to wait
93+
// for the remaining async actions to finish
94+
await waitFor(() => getByText('Fresh'));
95+
});
96+
6797
test('waits for element with custom interval', async () => {
6898
const mockFn = jest.fn(() => {
6999
throw Error('test');

src/config.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export type Config = {
2+
/** Default timeout, in ms, for `waitFor` and `findBy*` queries. */
3+
asyncUtilTimeout: number;
4+
};
5+
6+
const defaultConfig: Config = {
7+
asyncUtilTimeout: 1000,
8+
};
9+
10+
let config = {
11+
...defaultConfig,
12+
};
13+
14+
export function configure(options: Partial<Config>) {
15+
config = {
16+
...config,
17+
...options,
18+
};
19+
}
20+
21+
export function resetToDefaults() {
22+
config = defaultConfig;
23+
}
24+
25+
export function getConfig() {
26+
return config;
27+
}

src/pure.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ export type {
1616
RenderResult as RenderAPI,
1717
} from './render';
1818
export type { RenderHookOptions, RenderHookResult } from './renderHook';
19+
export type { Config } from './config';
1920

2021
export { act };
2122
export { cleanup };
23+
export { configure, resetToDefaults } from './config';
2224
export { fireEvent };
2325
export { render };
2426
export { waitFor };

src/waitFor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* globals jest */
22
import act, { setReactActEnvironment, getIsReactActEnvironment } from './act';
3+
import { getConfig } from './config';
34
import { ErrorWithStack, copyStackTrace } from './helpers/errors';
45
import {
56
setTimeout,
@@ -9,7 +10,6 @@ import {
910
} from './helpers/timers';
1011
import { checkReactVersionAtLeast } from './react-versions';
1112

12-
const DEFAULT_TIMEOUT = 1000;
1313
const DEFAULT_INTERVAL = 50;
1414

1515
export type WaitForOptions = {
@@ -22,7 +22,7 @@ export type WaitForOptions = {
2222
function waitForInternal<T>(
2323
expectation: () => T,
2424
{
25-
timeout = DEFAULT_TIMEOUT,
25+
timeout = getConfig().asyncUtilTimeout,
2626
interval = DEFAULT_INTERVAL,
2727
stackTraceError,
2828
onTimeout,

typings/index.flow.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,13 @@ declare module '@testing-library/react-native' {
367367

368368
declare export var waitForElementToBeRemoved: WaitForElementToBeRemovedFunction;
369369

370+
declare interface Config {
371+
asyncUtilTimeout: number;
372+
}
373+
374+
declare export var configure: (options: $Shape<Config>) => void;
375+
declare export var resetToDefaults: () => void;
376+
370377
declare export var act: (callback: () => void) => Thenable;
371378
declare export var within: (instance: ReactTestInstance) => Queries;
372379
declare export var getQueriesForElement: (

website/docs/API.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ title: API
4545
- [Examples](#examples)
4646
- [With `initialProps`](#with-initialprops)
4747
- [With `wrapper`](#with-wrapper)
48+
- [Configuration](#configuration)
49+
- [`configure`](#configure)
50+
- [`asyncUtilTimeout` option](#asyncutiltimeout-option)
51+
- [`resetToDefaults()`](#resettodefaults)
4852
- [Accessibility](#accessibility)
4953
- [`isInaccessible`](#isinaccessible)
5054

@@ -714,6 +718,30 @@ it('should use context value', () => {
714718
});
715719
```
716720

721+
722+
## Configuration
723+
724+
### `configure`
725+
726+
```ts
727+
type Config = {
728+
asyncUtilTimeout: number;
729+
};
730+
731+
function configure(options: Partial<Config>) {}
732+
```
733+
734+
#### `asyncUtilTimeout` option
735+
736+
Default timeout, in ms, for async helper functions (`waitFor`, `waitForElementToBeRemoved`) and `findBy*` queries. Defaults to 1000 ms.
737+
738+
739+
### `resetToDefaults()`
740+
741+
```ts
742+
function resetToDefaults() {}
743+
```
744+
717745
## Accessibility
718746

719747
### `isInaccessible`

0 commit comments

Comments
 (0)