Skip to content

Commit 4adb92b

Browse files
feat: wrap waitFor in (async) act to support async queries without explicit act call (#344)
* Wrapped waitFor call in act to support async waitFor/findBy * Updated docs * Spelling mistake * Added short info in migration guide * Corrected spelling * Clarified comments * Added async act implementation conditional on React version * Code review changes * Update src/waitFor.js Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * Update src/waitFor.js Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * Fixed prettier * Update src/waitFor.js Co-authored-by: Michał Pierzchała <thymikee@gmail.com> Co-authored-by: Michał Pierzchała <thymikee@gmail.com>
1 parent 10bae7d commit 4adb92b

File tree

5 files changed

+44
-2
lines changed

5 files changed

+44
-2
lines changed

src/waitFor.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
// @flow
22

3+
import * as React from 'react';
4+
import act from './act';
35
import { throwRemovedFunctionError } from './helpers/errors';
46

57
const DEFAULT_TIMEOUT = 4500;
68
const DEFAULT_INTERVAL = 50;
79

10+
function checkReactVersionAtLeast(major: number, minor: number): boolean {
11+
if (React.version === undefined) return false;
12+
const [actualMajor, actualMinor] = React.version.split('.').map(Number);
13+
14+
return actualMajor > major || (actualMajor === major && actualMinor >= minor);
15+
}
16+
817
export type WaitForOptions = {
918
timeout?: number,
1019
interval?: number,
1120
};
1221

13-
export default function waitFor<T>(
22+
function waitForInternal<T>(
1423
expectation: () => T,
1524
options?: WaitForOptions
1625
): Promise<T> {
@@ -38,6 +47,25 @@ export default function waitFor<T>(
3847
});
3948
}
4049

50+
export default async function waitFor<T>(
51+
expectation: () => T,
52+
options?: WaitForOptions
53+
): Promise<T> {
54+
if (!checkReactVersionAtLeast(16, 9)) {
55+
return waitForInternal(expectation, options);
56+
}
57+
58+
let result: T;
59+
60+
//$FlowFixMe: `act` has incorrect flow typing
61+
await act(async () => {
62+
result = await waitForInternal(expectation, options);
63+
});
64+
65+
//$FlowFixMe: either we have result or `waitFor` threw error
66+
return result;
67+
}
68+
4169
export function waitForElement<T>(
4270
expectation: () => T,
4371
_timeout: number = 4500,

website/docs/API.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ function waitFor<T>(
336336

337337
Waits for non-deterministic periods of time until your element appears or times out. `waitFor` periodically calls `expectation` every `interval` milliseconds to determine whether the element appeared or not.
338338

339+
:::info
340+
In order to properly use `waitFor` you need at least React >=16.9.0 (featuring async `act`) or React Native >=0.60 (which comes with React >=16.9.0).
341+
:::
342+
339343
```jsx
340344
import { render, waitFor } from 'react-testing-library';
341345

@@ -403,4 +407,4 @@ expect(submitButtons).toHaveLength(3); // expect 3 elements
403407

404408
## `act`
405409

406-
Useful function to help testing components that use hooks API. By default any `render`, `update`, and `fireEvent` calls are wrapped by this function, so there is no need to wrap it manually. This method is re-exported from [`react-test-renderer`](https://github.com/facebook/react/blob/master/packages/react-test-renderer/src/ReactTestRenderer.js#L567]).
410+
Useful function to help testing components that use hooks API. By default any `render`, `update`, `fireEvent`, and `waitFor` calls are wrapped by this function, so there is no need to wrap it manually. This method is re-exported from [`react-test-renderer`](https://github.com/facebook/react/blob/master/packages/react-test-renderer/src/ReactTestRenderer.js#L567]).

website/docs/GettingStarted.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ This library has a peerDependencies listing for `react-test-renderer` and, of co
6666

6767
As you may have noticed, it's not tied to React Native at all – you can safely use it in your React components if you feel like not interacting directly with DOM.
6868

69+
:::info
70+
In order to properly use helpers for async tests (`findBy` queries and `waitFor`) you need at least React >=16.9.0 (featuring async `act`) or React Native >=0.60 (which comes with React >=16.9.0).
71+
:::
72+
6973
### Additional Jest matchers
7074

7175
In order to use addtional React Native-specific jest matchers from [@testing-library/jest-native](https://github.com/testing-library/jest-native) package add it to your project:

website/docs/MigrationV2.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ export default function waitFor<T>(
5858

5959
Both changes should improve code readibility.
6060

61+
`waitFor` calls (and hence also `findBy` queries) are now wrapped in `act` by default, so that you should no longer need to use `act` directly in your tests.
62+
6163
:::tip
6264
You can usually avoid `waitFor` by a proper use of `findBy` asynchronous queries. It will result in more streamlined testing experience.
6365
:::

website/docs/Queries.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ title: Queries
3232

3333
`findAllBy` queries return a promise which resolves to an array when any matching elements are found. The promise is rejected if no elements match after a default timeout of 4500ms.
3434

35+
:::info
36+
In order to properly use `findBy` and `findAllBy` queries you need at least React >=16.9.0 (featuring async `act`) or React Native >=0.60 (which comes with React >=16.9.0).
37+
:::
38+
3539
:::info
3640
`findBy` and `findAllBy` queries accept optional `waitForOptions` object argument which can contain `timeout` and `interval` properies which have the same meaning as respective options for [`waitFor`](https://callstack.github.io/react-native-testing-library/docs/api#waitfor) function.
3741
:::

0 commit comments

Comments
 (0)