mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
refactor: remove real timers warning in User Event (#1654)
* refactor: remove real timers warning in User Event * chore: tweak docs
This commit is contained in:
committed by
GitHub
parent
239e046798
commit
b6c33d0082
@@ -2,13 +2,11 @@ import React from 'react';
|
||||
import { Pressable, Text } from 'react-native';
|
||||
import { render, screen } from '../../../pure';
|
||||
import { userEvent } from '../..';
|
||||
import * as WarnAboutRealTimers from '../../utils/warn-about-real-timers';
|
||||
|
||||
describe('userEvent.longPress with real timers', () => {
|
||||
beforeEach(() => {
|
||||
jest.useRealTimers();
|
||||
jest.restoreAllMocks();
|
||||
jest.spyOn(WarnAboutRealTimers, 'warnAboutRealTimersIfNeeded').mockImplementation();
|
||||
});
|
||||
|
||||
test('calls onLongPress if the delayLongPress is the default one', async () => {
|
||||
@@ -90,18 +88,3 @@ describe('userEvent.longPress with real timers', () => {
|
||||
expect(mockOnLongPress).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test('warns about using real timers with userEvent', async () => {
|
||||
jest.restoreAllMocks();
|
||||
const mockConsoleWarn = jest.spyOn(console, 'warn').mockImplementation();
|
||||
|
||||
render(<Pressable testID="pressable" />);
|
||||
|
||||
await userEvent.longPress(screen.getByTestId('pressable'));
|
||||
|
||||
expect(mockConsoleWarn.mock.calls[0][0]).toMatchInlineSnapshot(`
|
||||
"It is recommended to use userEvent with fake timers
|
||||
Some events involve duration so your tests may take a long time to run.
|
||||
For instance calling userEvent.longPress with real timers will take 500 ms."
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -10,13 +10,11 @@ import {
|
||||
import { createEventLogger, getEventsNames } from '../../../test-utils';
|
||||
import { render, screen } from '../../..';
|
||||
import { userEvent } from '../..';
|
||||
import * as WarnAboutRealTimers from '../../utils/warn-about-real-timers';
|
||||
|
||||
describe('userEvent.press with real timers', () => {
|
||||
beforeEach(() => {
|
||||
jest.useRealTimers();
|
||||
jest.restoreAllMocks();
|
||||
jest.spyOn(WarnAboutRealTimers, 'warnAboutRealTimersIfNeeded').mockImplementation();
|
||||
});
|
||||
|
||||
test('calls onPressIn, onPress and onPressOut prop of touchable', async () => {
|
||||
@@ -301,18 +299,3 @@ describe('userEvent.press with real timers', () => {
|
||||
expect(mockOnPress).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test('warns about using real timers with userEvent', async () => {
|
||||
jest.restoreAllMocks();
|
||||
const mockConsoleWarn = jest.spyOn(console, 'warn').mockImplementation();
|
||||
|
||||
render(<Pressable testID="pressable" />);
|
||||
|
||||
await userEvent.press(screen.getByTestId('pressable'));
|
||||
|
||||
expect(mockConsoleWarn.mock.calls[0][0]).toMatchInlineSnapshot(`
|
||||
"It is recommended to use userEvent with fake timers
|
||||
Some events involve duration so your tests may take a long time to run.
|
||||
For instance calling userEvent.longPress with real timers will take 500 ms."
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ import { isPointerEventEnabled } from '../../helpers/pointer-events';
|
||||
import { isHostText, isHostTextInput } from '../../helpers/host-component-names';
|
||||
import { EventBuilder } from '../event-builder';
|
||||
import { UserEventConfig, UserEventInstance } from '../setup';
|
||||
import { dispatchEvent, wait, warnAboutRealTimersIfNeeded } from '../utils';
|
||||
import { dispatchEvent, wait } from '../utils';
|
||||
import { DEFAULT_MIN_PRESS_DURATION } from './constants';
|
||||
|
||||
export interface PressOptions {
|
||||
@@ -69,8 +69,6 @@ const emitPressablePressEvents = async (
|
||||
element: ReactTestInstance,
|
||||
options: BasePressOptions,
|
||||
) => {
|
||||
warnAboutRealTimersIfNeeded();
|
||||
|
||||
await wait(config);
|
||||
|
||||
dispatchEvent(element, 'responderGrant', EventBuilder.Common.responderGrant());
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import * as timersHelper from '../../../helpers/timers';
|
||||
import { warnAboutRealTimersIfNeeded } from '../warn-about-real-timers';
|
||||
|
||||
describe('warnAboutRealTimersIfNeeded()', () => {
|
||||
it('warn when RNTL_SKIP_AUTO_DETECT_FAKE_TIMERS is not present and fake timers are not enabled', () => {
|
||||
const warnMock = jest.spyOn(console, 'warn').mockImplementation();
|
||||
const helperMock = jest.spyOn(timersHelper, 'jestFakeTimersAreEnabled').mockReturnValue(false);
|
||||
|
||||
warnAboutRealTimersIfNeeded();
|
||||
|
||||
expect(warnMock).toHaveBeenCalledWith(
|
||||
'It is recommended to use userEvent with fake timers\n' +
|
||||
'Some events involve duration so your tests may take a long time to run.\n' +
|
||||
'For instance calling userEvent.longPress with real timers will take 500 ms.',
|
||||
);
|
||||
|
||||
warnMock.mockRestore();
|
||||
helperMock.mockRestore();
|
||||
});
|
||||
|
||||
it('never warns when RNTL_SKIP_AUTO_DETECT_FAKE_TIMERS is present', () => {
|
||||
const warnMock = jest.spyOn(console, 'warn').mockImplementation();
|
||||
process.env.RNTL_SKIP_AUTO_DETECT_FAKE_TIMERS = 'true';
|
||||
|
||||
warnAboutRealTimersIfNeeded();
|
||||
|
||||
expect(warnMock).not.toHaveBeenCalled();
|
||||
|
||||
warnMock.mockRestore();
|
||||
});
|
||||
|
||||
it('never warns when fake timers are enabled', () => {
|
||||
const warnMock = jest.spyOn(console, 'warn').mockImplementation();
|
||||
const helperMock = jest.spyOn(timersHelper, 'jestFakeTimersAreEnabled').mockReturnValue(true);
|
||||
|
||||
warnAboutRealTimersIfNeeded();
|
||||
|
||||
expect(warnMock).not.toHaveBeenCalled();
|
||||
|
||||
warnMock.mockRestore();
|
||||
helperMock.mockRestore();
|
||||
});
|
||||
});
|
||||
@@ -2,4 +2,3 @@ export * from './content-size';
|
||||
export * from './dispatch-event';
|
||||
export * from './text-range';
|
||||
export * from './wait';
|
||||
export * from './warn-about-real-timers';
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { jestFakeTimersAreEnabled } from '../../helpers/timers';
|
||||
|
||||
export const warnAboutRealTimersIfNeeded = () => {
|
||||
if (process.env.RNTL_SKIP_AUTO_DETECT_FAKE_TIMERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
const areFakeTimersEnabled = jestFakeTimersAreEnabled();
|
||||
if (areFakeTimersEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`It is recommended to use userEvent with fake timers
|
||||
Some events involve duration so your tests may take a long time to run.
|
||||
For instance calling userEvent.longPress with real timers will take 500 ms.`);
|
||||
};
|
||||
@@ -53,7 +53,9 @@ await user.press(element);
|
||||
|
||||
This helper simulates a press on any pressable element, e.g. `Pressable`, `TouchableOpacity`, `Text`, `TextInput`, etc. Unlike `fireEvent.press()`, a more straightforward API that will only call the `onPress` prop, this function simulates the entire press interaction in a more realistic way by reproducing the event sequence emitted by React Native runtime. This helper will trigger additional events like `pressIn` and `pressOut`.
|
||||
|
||||
## `longPress()` \{#long-press}
|
||||
This event will take a minimum of 130 ms to run due to the internal React Native logic. Consider using fake timers to speed up test execution for tests involving `press` and `longPress` interactions.
|
||||
|
||||
## `longPress()`
|
||||
|
||||
```ts
|
||||
longPress(
|
||||
@@ -69,7 +71,9 @@ const user = userEvent.setup();
|
||||
await user.longPress(element);
|
||||
```
|
||||
|
||||
Simulates a long press user interaction. In React Native, the `longPress` event is emitted when the press duration exceeds the long press threshold (by default, 500 ms). In other aspects, this action behaves similarly to regular `press` action, e.g., by emitting `pressIn` and `pressOut` events. The press duration is customizable through the options. This should be useful if you use the `delayLongPress` prop. When using real timers, this will take 500 ms, so it is highly recommended to use that API with fake timers to prevent the test from taking a long time to run.
|
||||
Simulates a long press user interaction. In React Native, the `longPress` event is emitted when the press duration exceeds the long press threshold (by default, 500 ms). In other aspects, this action behaves similarly to regular `press` action, e.g., by emitting `pressIn` and `pressOut` events. The press duration is customizable through the options. This should be useful if you use the `delayLongPress` prop.
|
||||
|
||||
This event will, by default, take 500 ms to run. Due to internal React Native logic, it will take at least 130 ms regardless of the duration option passed. Consider using fake timers to speed up test execution for tests involving `press` and `longPress` interactions.
|
||||
|
||||
### Options {#longpress-options}
|
||||
|
||||
@@ -107,7 +111,7 @@ This function will add text to the text already present in the text input (as sp
|
||||
- `skipPress` - if true, `pressIn` and `pressOut` events will not be triggered.
|
||||
- `submitEditing` - if true, `submitEditing` event will be triggered after typing the text.
|
||||
|
||||
### Sequence of events
|
||||
### Sequence of events {#type-sequence}
|
||||
|
||||
The sequence of events depends on the `multiline` prop and the passed options.
|
||||
|
||||
@@ -156,7 +160,7 @@ This helper simulates the user clearing the content of a `TextInput` element.
|
||||
|
||||
This function supports only host `TextInput` elements. Passing other element types will result in throwing an error.
|
||||
|
||||
### Sequence of events
|
||||
### Sequence of events {#clear-sequence}
|
||||
|
||||
Events will not be emitted if the `editable` prop is set to `false`.
|
||||
|
||||
@@ -200,7 +204,7 @@ This helper simulates the user pasting given text to a `TextInput` element.
|
||||
|
||||
This function supports only host `TextInput` elements. Passing other element types will result in throwing an error.
|
||||
|
||||
### Sequence of events
|
||||
### Sequence of events {#paste-sequence}
|
||||
|
||||
Events will not be emitted if the `editable` prop is set to `false`.
|
||||
|
||||
@@ -278,7 +282,7 @@ This function will remember where the last scroll ended, so subsequent scroll in
|
||||
|
||||
To simulate a `FlatList` (and other controls based on `VirtualizedList`) scrolling, you should pass the `contentSize` and `layoutMeasurement` options, which enable the underlying logic to update the currently visible window.
|
||||
|
||||
### Sequence of events
|
||||
### Sequence of events {#scroll-sequence}
|
||||
|
||||
The sequence of events depends on whether the scroll includes an optional momentum scroll component.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user