@testing-library/react-native 12.1.3 → 12.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintcache +1 -1
- package/.eslintignore +1 -0
- package/build/fireEvent.js +2 -5
- package/build/fireEvent.js.map +1 -1
- package/build/helpers/component-tree.d.ts +11 -5
- package/build/helpers/component-tree.js +5 -1
- package/build/helpers/component-tree.js.map +1 -1
- package/build/helpers/deprecation.js +1 -1
- package/build/helpers/deprecation.js.map +1 -1
- package/build/helpers/findAll.d.ts +2 -1
- package/build/helpers/findAll.js +2 -1
- package/build/helpers/findAll.js.map +1 -1
- package/build/helpers/host-component-names.d.ts +12 -0
- package/build/helpers/host-component-names.js +18 -0
- package/build/helpers/host-component-names.js.map +1 -1
- package/build/helpers/matchers/matchLabelText.js +1 -1
- package/build/helpers/matchers/matchLabelText.js.map +1 -1
- package/build/pure.d.ts +2 -0
- package/build/pure.js +7 -0
- package/build/pure.js.map +1 -1
- package/build/queries/a11yState.js +1 -1
- package/build/queries/a11yState.js.map +1 -1
- package/build/queries/a11yValue.js +1 -1
- package/build/queries/a11yValue.js.map +1 -1
- package/build/queries/displayValue.js +5 -6
- package/build/queries/displayValue.js.map +1 -1
- package/build/queries/hintText.js +1 -1
- package/build/queries/hintText.js.map +1 -1
- package/build/queries/labelText.js +1 -1
- package/build/queries/labelText.js.map +1 -1
- package/build/queries/placeholderText.js +3 -4
- package/build/queries/placeholderText.js.map +1 -1
- package/build/queries/role.js +1 -1
- package/build/queries/role.js.map +1 -1
- package/build/queries/testId.js +3 -3
- package/build/queries/testId.js.map +1 -1
- package/build/queries/text.js +1 -2
- package/build/queries/text.js.map +1 -1
- package/build/render.js.map +1 -1
- package/build/user-event/clear.d.ts +3 -0
- package/build/user-event/clear.js +41 -0
- package/build/user-event/clear.js.map +1 -0
- package/build/user-event/event-builder/common.d.ts +48 -6
- package/build/user-event/event-builder/common.js +37 -20
- package/build/user-event/event-builder/common.js.map +1 -1
- package/build/user-event/event-builder/index.d.ts +94 -0
- package/build/user-event/event-builder/index.js +3 -1
- package/build/user-event/event-builder/index.js.map +1 -1
- package/build/user-event/event-builder/text-input.d.ts +91 -0
- package/build/user-event/event-builder/text-input.js +117 -0
- package/build/user-event/event-builder/text-input.js.map +1 -0
- package/build/user-event/index.d.ts +5 -2
- package/build/user-event/index.js +8 -1
- package/build/user-event/index.js.map +1 -1
- package/build/user-event/press/index.d.ts +1 -1
- package/build/user-event/press/index.js +6 -0
- package/build/user-event/press/index.js.map +1 -1
- package/build/user-event/press/press.d.ts +3 -3
- package/build/user-event/press/press.js +54 -64
- package/build/user-event/press/press.js.map +1 -1
- package/build/user-event/setup/setup.d.ts +45 -3
- package/build/user-event/setup/setup.js +17 -2
- package/build/user-event/setup/setup.js.map +1 -1
- package/build/user-event/type/index.d.ts +1 -1
- package/build/user-event/type/index.js +6 -0
- package/build/user-event/type/index.js.map +1 -1
- package/build/user-event/type/parseKeys.d.ts +1 -0
- package/build/user-event/type/parseKeys.js +40 -0
- package/build/user-event/type/parseKeys.js.map +1 -0
- package/build/user-event/type/type.d.ts +7 -2
- package/build/user-event/type/type.js +70 -8
- package/build/user-event/type/type.js.map +1 -1
- package/build/user-event/utils/content-size.d.ts +15 -0
- package/build/user-event/utils/content-size.js +26 -0
- package/build/user-event/utils/content-size.js.map +1 -0
- package/build/user-event/utils/{events.d.ts → dispatch-event.d.ts} +2 -2
- package/build/user-event/utils/dispatch-event.js +36 -0
- package/build/user-event/utils/dispatch-event.js.map +1 -0
- package/build/user-event/utils/host-components.d.ts +2 -0
- package/build/user-event/utils/host-components.js +11 -0
- package/build/user-event/utils/host-components.js.map +1 -0
- package/build/user-event/utils/index.d.ts +5 -1
- package/build/user-event/utils/index.js +48 -4
- package/build/user-event/utils/index.js.map +1 -1
- package/build/user-event/utils/text-range.d.ts +4 -0
- package/build/user-event/utils/text-range.js +2 -0
- package/build/user-event/utils/text-range.js.map +1 -0
- package/build/user-event/utils/warn-about-real-timers.d.ts +1 -0
- package/build/user-event/utils/warn-about-real-timers.js +20 -0
- package/build/user-event/utils/warn-about-real-timers.js.map +1 -0
- package/examples/basic/.expo/README.md +15 -0
- package/examples/basic/.expo/packager-info.json +4 -0
- package/examples/basic/.expo/settings.json +10 -0
- package/examples/basic/__tests__/App.test.tsx +30 -12
- package/examples/basic/package.json +7 -7
- package/examples/basic/yarn.lock +7499 -0
- package/examples/react-navigation/README.md +2 -0
- package/examples/react-navigation/package.json +5 -5
- package/examples/react-navigation/yarn.lock +5018 -0
- package/examples/redux/README.md +5 -0
- package/examples/redux/package.json +7 -7
- package/examples/redux/yarn.lock +4819 -0
- package/experiments-app/.expo/packager-info.json +2 -2
- package/experiments-app/package.json +7 -9
- package/experiments-app/src/MainScreen.tsx +1 -0
- package/experiments-app/src/experiments.ts +20 -2
- package/experiments-app/src/screens/FlatListEvents.tsx +57 -0
- package/experiments-app/src/screens/ScrollViewEvents.tsx +65 -0
- package/experiments-app/src/screens/SectionListEvents.tsx +91 -0
- package/experiments-app/src/screens/TextInputEventPropagation.tsx +5 -17
- package/experiments-app/src/screens/TextInputEvents.tsx +13 -15
- package/experiments-app/src/utils/helpers.ts +13 -3
- package/experiments-app/yarn.lock +901 -1105
- package/experiments-rtl/.babelrc +8 -0
- package/experiments-rtl/.eslintrc.json +3 -0
- package/experiments-rtl/.gitignore +35 -0
- package/experiments-rtl/README.md +34 -0
- package/experiments-rtl/jest-setup.js +1 -0
- package/experiments-rtl/jest.config.js +4 -0
- package/experiments-rtl/next.config.js +4 -0
- package/experiments-rtl/package.json +38 -0
- package/experiments-rtl/postcss.config.js +6 -0
- package/experiments-rtl/public/next.svg +1 -0
- package/experiments-rtl/public/vercel.svg +1 -0
- package/experiments-rtl/src/app/__tests__/click.test.tsx +31 -0
- package/experiments-rtl/src/app/__tests__/managed-text-input.test.tsx +51 -0
- package/experiments-rtl/src/app/globals.css +27 -0
- package/experiments-rtl/src/app/layout.tsx +22 -0
- package/experiments-rtl/src/app/page.tsx +113 -0
- package/experiments-rtl/tailwind.config.ts +20 -0
- package/experiments-rtl/tsconfig.json +28 -0
- package/experiments-rtl/yarn.lock +5418 -0
- package/package.json +4 -2
- package/src/__tests__/act.test.tsx +4 -0
- package/src/fireEvent.ts +1 -5
- package/src/helpers/component-tree.ts +14 -9
- package/src/helpers/deprecation.ts +1 -1
- package/src/helpers/findAll.ts +6 -4
- package/src/helpers/host-component-names.tsx +21 -0
- package/src/helpers/matchers/matchLabelText.ts +0 -1
- package/src/pure.ts +2 -0
- package/src/queries/a11yState.ts +2 -6
- package/src/queries/a11yValue.ts +2 -6
- package/src/queries/displayValue.ts +7 -14
- package/src/queries/hintText.ts +2 -7
- package/src/queries/labelText.ts +1 -3
- package/src/queries/placeholderText.ts +6 -13
- package/src/queries/role.ts +1 -2
- package/src/queries/testId.ts +5 -10
- package/src/queries/text.ts +3 -6
- package/src/render.tsx +1 -1
- package/src/user-event/__tests__/__snapshots__/clear.test.tsx.snap +269 -0
- package/src/user-event/__tests__/clear.test.tsx +217 -0
- package/src/user-event/clear.ts +59 -0
- package/src/user-event/event-builder/common.ts +35 -19
- package/src/user-event/event-builder/index.ts +2 -0
- package/src/user-event/event-builder/text-input.ts +86 -0
- package/src/user-event/index.ts +7 -3
- package/src/user-event/press/__tests__/longPress.real-timers.test.tsx +4 -2
- package/src/user-event/press/__tests__/press.real-timers.test.tsx +4 -2
- package/src/user-event/press/__tests__/press.test.tsx +40 -5
- package/src/user-event/press/index.ts +1 -1
- package/src/user-event/press/press.ts +93 -64
- package/src/user-event/setup/setup.ts +54 -5
- package/src/user-event/type/__tests__/__snapshots__/type-managed.test.tsx.snap +339 -0
- package/src/user-event/type/__tests__/__snapshots__/type.test.tsx.snap +644 -2
- package/src/user-event/type/__tests__/parseKeys.test.ts +23 -0
- package/src/user-event/type/__tests__/type-managed.test.tsx +120 -0
- package/src/user-event/type/__tests__/type.test.tsx +299 -27
- package/src/user-event/type/index.ts +1 -1
- package/src/user-event/type/parseKeys.ts +41 -0
- package/src/user-event/type/type.ts +128 -10
- package/src/user-event/utils/__tests__/dispatch-event.test.tsx +41 -0
- package/src/user-event/utils/__tests__/wait.test.ts +0 -1
- package/src/user-event/utils/content-size.ts +25 -0
- package/src/user-event/utils/dispatch-event.ts +38 -0
- package/src/user-event/utils/host-components.ts +6 -0
- package/src/user-event/utils/index.ts +5 -1
- package/src/user-event/utils/text-range.ts +4 -0
- package/src/user-event/{press/utils/warnAboutRealTimers.ts → utils/warn-about-real-timers.ts} +8 -1
- package/website/docs/API.md +19 -25
- package/website/docs/Queries.md +64 -59
- package/website/docs/UserEvent.md +134 -9
- package/website/sidebars.js +1 -1
- package/build/helpers/filterNodeByType.d.ts +0 -3
- package/build/helpers/filterNodeByType.js +0 -9
- package/build/helpers/filterNodeByType.js.map +0 -1
- package/build/user-event/press/utils/warnAboutRealTimers.d.ts +0 -1
- package/build/user-event/press/utils/warnAboutRealTimers.js +0 -14
- package/build/user-event/press/utils/warnAboutRealTimers.js.map +0 -1
- package/build/user-event/utils/events.js +0 -44
- package/build/user-event/utils/events.js.map +0 -1
- package/src/helpers/filterNodeByType.ts +0 -7
- package/src/user-event/utils/events.ts +0 -54
package/src/user-event/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { ReactTestInstance } from 'react-test-renderer';
|
|
2
2
|
import { setup } from './setup';
|
|
3
|
-
import { PressOptions } from './press
|
|
3
|
+
import { PressOptions } from './press';
|
|
4
|
+
import { TypeOptions } from './type';
|
|
5
|
+
|
|
6
|
+
export { UserEventConfig } from './setup';
|
|
4
7
|
|
|
5
8
|
export const userEvent = {
|
|
6
9
|
setup,
|
|
@@ -9,6 +12,7 @@ export const userEvent = {
|
|
|
9
12
|
press: (element: ReactTestInstance) => setup().press(element),
|
|
10
13
|
longPress: (element: ReactTestInstance, options?: PressOptions) =>
|
|
11
14
|
setup().longPress(element, options),
|
|
12
|
-
type: (element: ReactTestInstance, text: string) =>
|
|
13
|
-
setup().type(element, text),
|
|
15
|
+
type: (element: ReactTestInstance, text: string, options?: TypeOptions) =>
|
|
16
|
+
setup().type(element, text, options),
|
|
17
|
+
clear: (element: ReactTestInstance) => setup().clear(element),
|
|
14
18
|
};
|
|
@@ -2,13 +2,15 @@ import React from 'react';
|
|
|
2
2
|
import { Pressable, Text } from 'react-native';
|
|
3
3
|
import { render, screen } from '../../../pure';
|
|
4
4
|
import { userEvent } from '../..';
|
|
5
|
-
import * as WarnAboutRealTimers from '
|
|
5
|
+
import * as WarnAboutRealTimers from '../../utils/warn-about-real-timers';
|
|
6
6
|
|
|
7
7
|
describe('userEvent.longPress with real timers', () => {
|
|
8
8
|
beforeEach(() => {
|
|
9
9
|
jest.useRealTimers();
|
|
10
10
|
jest.restoreAllMocks();
|
|
11
|
-
jest
|
|
11
|
+
jest
|
|
12
|
+
.spyOn(WarnAboutRealTimers, 'warnAboutRealTimersIfNeeded')
|
|
13
|
+
.mockImplementation();
|
|
12
14
|
});
|
|
13
15
|
|
|
14
16
|
test('calls onLongPress if the delayLongPress is the default one', async () => {
|
|
@@ -10,13 +10,15 @@ import {
|
|
|
10
10
|
import { createEventLogger, getEventsName } from '../../../test-utils';
|
|
11
11
|
import { render, screen } from '../../..';
|
|
12
12
|
import { userEvent } from '../..';
|
|
13
|
-
import * as WarnAboutRealTimers from '
|
|
13
|
+
import * as WarnAboutRealTimers from '../../utils/warn-about-real-timers';
|
|
14
14
|
|
|
15
15
|
describe('userEvent.press with real timers', () => {
|
|
16
16
|
beforeEach(() => {
|
|
17
17
|
jest.useRealTimers();
|
|
18
18
|
jest.restoreAllMocks();
|
|
19
|
-
jest
|
|
19
|
+
jest
|
|
20
|
+
.spyOn(WarnAboutRealTimers, 'warnAboutRealTimersIfNeeded')
|
|
21
|
+
.mockImplementation();
|
|
20
22
|
});
|
|
21
23
|
|
|
22
24
|
test('calls onPressIn, onPress and onPressOut prop of touchable', async () => {
|
|
@@ -304,7 +304,7 @@ describe('userEvent.press with fake timers', () => {
|
|
|
304
304
|
expect(mockOnPress).toHaveBeenCalled();
|
|
305
305
|
});
|
|
306
306
|
|
|
307
|
-
test('works on Text', async () => {
|
|
307
|
+
test('press works on Text', async () => {
|
|
308
308
|
const { events, logEvent } = createEventLogger();
|
|
309
309
|
|
|
310
310
|
render(
|
|
@@ -317,11 +317,29 @@ describe('userEvent.press with fake timers', () => {
|
|
|
317
317
|
press me
|
|
318
318
|
</Text>
|
|
319
319
|
);
|
|
320
|
-
await userEvent.press(screen.getByText('press me'));
|
|
321
320
|
|
|
321
|
+
await userEvent.press(screen.getByText('press me'));
|
|
322
322
|
expect(getEventsName(events)).toEqual(['pressIn', 'press', 'pressOut']);
|
|
323
323
|
});
|
|
324
324
|
|
|
325
|
+
test('longPress works Text', async () => {
|
|
326
|
+
const { events, logEvent } = createEventLogger();
|
|
327
|
+
|
|
328
|
+
render(
|
|
329
|
+
<Text
|
|
330
|
+
onPress={logEvent('press')}
|
|
331
|
+
onPressIn={logEvent('pressIn')}
|
|
332
|
+
onPressOut={logEvent('pressOut')}
|
|
333
|
+
onLongPress={logEvent('longPress')}
|
|
334
|
+
>
|
|
335
|
+
press me
|
|
336
|
+
</Text>
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
await userEvent.longPress(screen.getByText('press me'));
|
|
340
|
+
expect(getEventsName(events)).toEqual(['pressIn', 'longPress', 'pressOut']);
|
|
341
|
+
});
|
|
342
|
+
|
|
325
343
|
test('doesnt trigger on disabled Text', async () => {
|
|
326
344
|
const { events, logEvent } = createEventLogger();
|
|
327
345
|
|
|
@@ -361,7 +379,7 @@ describe('userEvent.press with fake timers', () => {
|
|
|
361
379
|
expect(events).toEqual([]);
|
|
362
380
|
});
|
|
363
381
|
|
|
364
|
-
test('works on
|
|
382
|
+
test('press works on TextInput', async () => {
|
|
365
383
|
const { events, logEvent } = createEventLogger();
|
|
366
384
|
|
|
367
385
|
render(
|
|
@@ -371,12 +389,27 @@ describe('userEvent.press with fake timers', () => {
|
|
|
371
389
|
onPressOut={logEvent('pressOut')}
|
|
372
390
|
/>
|
|
373
391
|
);
|
|
392
|
+
|
|
374
393
|
await userEvent.press(screen.getByPlaceholderText('email'));
|
|
394
|
+
expect(getEventsName(events)).toEqual(['pressIn', 'pressOut']);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
test('longPress works on TextInput', async () => {
|
|
398
|
+
const { events, logEvent } = createEventLogger();
|
|
399
|
+
|
|
400
|
+
render(
|
|
401
|
+
<TextInput
|
|
402
|
+
placeholder="email"
|
|
403
|
+
onPressIn={logEvent('pressIn')}
|
|
404
|
+
onPressOut={logEvent('pressOut')}
|
|
405
|
+
/>
|
|
406
|
+
);
|
|
375
407
|
|
|
408
|
+
await userEvent.longPress(screen.getByPlaceholderText('email'));
|
|
376
409
|
expect(getEventsName(events)).toEqual(['pressIn', 'pressOut']);
|
|
377
410
|
});
|
|
378
411
|
|
|
379
|
-
test('does not call onPressIn and onPressOut on non editable
|
|
412
|
+
test('does not call onPressIn and onPressOut on non editable TextInput', async () => {
|
|
380
413
|
const { events, logEvent } = createEventLogger();
|
|
381
414
|
|
|
382
415
|
render(
|
|
@@ -387,11 +420,12 @@ describe('userEvent.press with fake timers', () => {
|
|
|
387
420
|
onPressOut={logEvent('pressOut')}
|
|
388
421
|
/>
|
|
389
422
|
);
|
|
423
|
+
|
|
390
424
|
await userEvent.press(screen.getByPlaceholderText('email'));
|
|
391
425
|
expect(events).toEqual([]);
|
|
392
426
|
});
|
|
393
427
|
|
|
394
|
-
test('does not call onPressIn and onPressOut on
|
|
428
|
+
test('does not call onPressIn and onPressOut on TextInput with pointer events disabled', async () => {
|
|
395
429
|
const { events, logEvent } = createEventLogger();
|
|
396
430
|
|
|
397
431
|
render(
|
|
@@ -402,6 +436,7 @@ describe('userEvent.press with fake timers', () => {
|
|
|
402
436
|
onPressOut={logEvent('pressOut')}
|
|
403
437
|
/>
|
|
404
438
|
);
|
|
439
|
+
|
|
405
440
|
await userEvent.press(screen.getByPlaceholderText('email'));
|
|
406
441
|
expect(events).toEqual([]);
|
|
407
442
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { press, longPress } from './press';
|
|
1
|
+
export { PressOptions, press, longPress } from './press';
|
|
@@ -1,50 +1,65 @@
|
|
|
1
1
|
import { ReactTestInstance } from 'react-test-renderer';
|
|
2
|
-
import { EventBuilder } from '../event-builder';
|
|
3
|
-
import { UserEventInstance } from '../setup';
|
|
4
|
-
import { wait } from '../utils';
|
|
5
2
|
import act from '../../act';
|
|
6
3
|
import { getHostParent } from '../../helpers/component-tree';
|
|
7
|
-
import { filterNodeByType } from '../../helpers/filterNodeByType';
|
|
8
4
|
import { isPointerEventEnabled } from '../../helpers/pointer-events';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
5
|
+
import { isHostText } from '../../helpers/host-component-names';
|
|
6
|
+
import { EventBuilder } from '../event-builder';
|
|
7
|
+
import { UserEventConfig, UserEventInstance } from '../setup';
|
|
8
|
+
import {
|
|
9
|
+
dispatchEvent,
|
|
10
|
+
isEditableTextInput,
|
|
11
|
+
wait,
|
|
12
|
+
warnAboutRealTimersIfNeeded,
|
|
13
|
+
} from '../utils';
|
|
11
14
|
import { DEFAULT_MIN_PRESS_DURATION } from './constants';
|
|
12
|
-
import { warnAboutRealTimers } from './utils/warnAboutRealTimers';
|
|
13
15
|
|
|
14
|
-
export
|
|
15
|
-
duration
|
|
16
|
-
}
|
|
16
|
+
export interface PressOptions {
|
|
17
|
+
duration?: number;
|
|
18
|
+
}
|
|
17
19
|
|
|
18
20
|
export async function press(
|
|
19
21
|
this: UserEventInstance,
|
|
20
22
|
element: ReactTestInstance
|
|
21
23
|
): Promise<void> {
|
|
22
|
-
await basePress(this.config, element
|
|
24
|
+
await basePress(this.config, element, {
|
|
25
|
+
type: 'press',
|
|
26
|
+
duration: 0,
|
|
27
|
+
});
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
export async function longPress(
|
|
26
31
|
this: UserEventInstance,
|
|
27
32
|
element: ReactTestInstance,
|
|
28
|
-
options
|
|
33
|
+
options?: PressOptions
|
|
29
34
|
): Promise<void> {
|
|
30
|
-
await basePress(this.config, element,
|
|
35
|
+
await basePress(this.config, element, {
|
|
36
|
+
type: 'longPress',
|
|
37
|
+
duration: options?.duration ?? 500,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface BasePressOptions {
|
|
42
|
+
type: 'press' | 'longPress';
|
|
43
|
+
duration: number;
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
const basePress = async (
|
|
34
|
-
config:
|
|
47
|
+
config: UserEventConfig,
|
|
35
48
|
element: ReactTestInstance,
|
|
36
|
-
options:
|
|
49
|
+
options: BasePressOptions
|
|
37
50
|
): Promise<void> => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
51
|
+
if (isPressableText(element)) {
|
|
52
|
+
await emitTextPressEvents(config, element, options);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (isEditableTextInput(element) && isPointerEventEnabled(element)) {
|
|
57
|
+
await emitTextInputPressEvents(config, element, options);
|
|
43
58
|
return;
|
|
44
59
|
}
|
|
45
60
|
|
|
46
61
|
if (isEnabledTouchResponder(element)) {
|
|
47
|
-
await
|
|
62
|
+
await emitPressablePressEvents(config, element, options);
|
|
48
63
|
return;
|
|
49
64
|
}
|
|
50
65
|
|
|
@@ -56,31 +71,33 @@ const basePress = async (
|
|
|
56
71
|
await basePress(config, hostParentElement, options);
|
|
57
72
|
};
|
|
58
73
|
|
|
59
|
-
const
|
|
60
|
-
config:
|
|
74
|
+
const emitPressablePressEvents = async (
|
|
75
|
+
config: UserEventConfig,
|
|
61
76
|
element: ReactTestInstance,
|
|
62
|
-
options:
|
|
77
|
+
options: BasePressOptions
|
|
63
78
|
) => {
|
|
64
|
-
|
|
65
|
-
if (!areFakeTimersEnabled) {
|
|
66
|
-
warnAboutRealTimers();
|
|
67
|
-
}
|
|
79
|
+
warnAboutRealTimersIfNeeded();
|
|
68
80
|
|
|
69
81
|
await wait(config);
|
|
70
82
|
|
|
71
83
|
await act(async () => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
dispatchEvent(
|
|
85
|
+
element,
|
|
86
|
+
'responderGrant',
|
|
87
|
+
EventBuilder.Common.responderGrant()
|
|
88
|
+
);
|
|
76
89
|
|
|
77
90
|
await wait(config, options.duration);
|
|
78
91
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
dispatchEvent(
|
|
93
|
+
element,
|
|
94
|
+
'responderRelease',
|
|
95
|
+
EventBuilder.Common.responderRelease()
|
|
96
|
+
);
|
|
83
97
|
|
|
98
|
+
// React Native will wait for minimal delay of DEFAULT_MIN_PRESS_DURATION
|
|
99
|
+
// before emitting the `pressOut` event. We need to wait here, so that
|
|
100
|
+
// `press()` function does not return before that.
|
|
84
101
|
if (DEFAULT_MIN_PRESS_DURATION - options.duration > 0) {
|
|
85
102
|
await wait(config, DEFAULT_MIN_PRESS_DURATION - options.duration);
|
|
86
103
|
}
|
|
@@ -94,41 +111,53 @@ const isEnabledTouchResponder = (element: ReactTestInstance) => {
|
|
|
94
111
|
);
|
|
95
112
|
};
|
|
96
113
|
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
114
|
+
const isPressableText = (element: ReactTestInstance) => {
|
|
115
|
+
const hasPressEventHandler = Boolean(
|
|
116
|
+
element.props.onPress ||
|
|
117
|
+
element.props.onLongPress ||
|
|
118
|
+
element.props.onPressIn ||
|
|
119
|
+
element.props.onPressOut
|
|
103
120
|
);
|
|
104
|
-
};
|
|
105
121
|
|
|
106
|
-
const isEnabledTextInput = (element: ReactTestInstance) => {
|
|
107
122
|
return (
|
|
108
|
-
|
|
123
|
+
isHostText(element) &&
|
|
109
124
|
isPointerEventEnabled(element) &&
|
|
110
|
-
element.props.
|
|
125
|
+
!element.props.disabled &&
|
|
126
|
+
hasPressEventHandler
|
|
111
127
|
);
|
|
112
128
|
};
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Dispatches a press event sequence for Text.
|
|
132
|
+
*/
|
|
133
|
+
async function emitTextPressEvents(
|
|
134
|
+
config: UserEventConfig,
|
|
116
135
|
element: ReactTestInstance,
|
|
117
|
-
options:
|
|
118
|
-
)
|
|
119
|
-
const { onPressIn, onPress, onPressOut } = element.props;
|
|
136
|
+
options: BasePressOptions
|
|
137
|
+
) {
|
|
120
138
|
await wait(config);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
139
|
+
dispatchEvent(element, 'pressIn', EventBuilder.Common.touch());
|
|
140
|
+
|
|
141
|
+
// Emit either `press` or `longPress`.
|
|
142
|
+
dispatchEvent(element, options.type, EventBuilder.Common.touch());
|
|
143
|
+
|
|
127
144
|
await wait(config, options.duration);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
dispatchEvent(element, 'pressOut', EventBuilder.Common.touch());
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Dispatches a press event sequence for TextInput.
|
|
150
|
+
*/
|
|
151
|
+
async function emitTextInputPressEvents(
|
|
152
|
+
config: UserEventConfig,
|
|
153
|
+
element: ReactTestInstance,
|
|
154
|
+
options: BasePressOptions
|
|
155
|
+
) {
|
|
156
|
+
await wait(config);
|
|
157
|
+
dispatchEvent(element, 'pressIn', EventBuilder.Common.touch());
|
|
158
|
+
|
|
159
|
+
// Note: TextInput does not have `onPress`/`onLongPress` props.
|
|
160
|
+
|
|
161
|
+
await wait(config, options.duration);
|
|
162
|
+
dispatchEvent(element, 'pressOut', EventBuilder.Common.touch());
|
|
163
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ReactTestInstance } from 'react-test-renderer';
|
|
2
2
|
import { jestFakeTimersAreEnabled } from '../../helpers/timers';
|
|
3
|
-
import { press, longPress } from '../press';
|
|
4
|
-
import { type } from '../type';
|
|
5
|
-
import {
|
|
3
|
+
import { PressOptions, press, longPress } from '../press';
|
|
4
|
+
import { TypeOptions, type } from '../type';
|
|
5
|
+
import { clear } from '../clear';
|
|
6
6
|
|
|
7
7
|
export interface UserEventSetupOptions {
|
|
8
8
|
/**
|
|
@@ -46,7 +46,7 @@ const defaultOptions: Required<UserEventSetupOptions> = {
|
|
|
46
46
|
* Creates a new instance of user event instance with the given options.
|
|
47
47
|
*
|
|
48
48
|
* @param options
|
|
49
|
-
* @returns
|
|
49
|
+
* @returns UserEvent instance
|
|
50
50
|
*/
|
|
51
51
|
export function setup(options?: UserEventSetupOptions) {
|
|
52
52
|
const config = createConfig(options);
|
|
@@ -54,6 +54,12 @@ export function setup(options?: UserEventSetupOptions) {
|
|
|
54
54
|
return instance;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Options affecting all user event interactions.
|
|
59
|
+
*
|
|
60
|
+
* @param delay between some subsequent inputs like typing a series of characters
|
|
61
|
+
* @param advanceTimers function to be called to advance fake timers
|
|
62
|
+
*/
|
|
57
63
|
export interface UserEventConfig {
|
|
58
64
|
delay: number;
|
|
59
65
|
advanceTimers: (delay: number) => Promise<void> | void;
|
|
@@ -66,14 +72,56 @@ function createConfig(options?: UserEventSetupOptions): UserEventConfig {
|
|
|
66
72
|
};
|
|
67
73
|
}
|
|
68
74
|
|
|
75
|
+
/**
|
|
76
|
+
* UserEvent instance used to invoke user interaction functions.
|
|
77
|
+
*/
|
|
69
78
|
export interface UserEventInstance {
|
|
70
79
|
config: UserEventConfig;
|
|
80
|
+
|
|
71
81
|
press: (element: ReactTestInstance) => Promise<void>;
|
|
72
82
|
longPress: (
|
|
73
83
|
element: ReactTestInstance,
|
|
74
84
|
options?: PressOptions
|
|
75
85
|
) => Promise<void>;
|
|
76
|
-
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Simulate user pressing on a given `TextInput` element and typing given text.
|
|
89
|
+
*
|
|
90
|
+
* This method will trigger the events for each character of the text:
|
|
91
|
+
* `keyPress`, `change`, `changeText`, `endEditing`, etc.
|
|
92
|
+
*
|
|
93
|
+
* It will also trigger events connected with entering and leaving the text
|
|
94
|
+
* input.
|
|
95
|
+
*
|
|
96
|
+
* The exact events sent depend on the props of the TextInput (`editable`,
|
|
97
|
+
* `multiline`, value, defaultValue, etc) and passed options.
|
|
98
|
+
*
|
|
99
|
+
* @param element TextInput element to type on
|
|
100
|
+
* @param text Text to type
|
|
101
|
+
* @param options Options affecting typing behavior:
|
|
102
|
+
* - `skipPress` - if true, `pressIn` and `pressOut` events will not be
|
|
103
|
+
* triggered.
|
|
104
|
+
* - `submitEditing` - if true, `submitEditing` event will be triggered after
|
|
105
|
+
* typing the text.
|
|
106
|
+
*/
|
|
107
|
+
type: (
|
|
108
|
+
element: ReactTestInstance,
|
|
109
|
+
text: string,
|
|
110
|
+
options?: TypeOptions
|
|
111
|
+
) => Promise<void>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Simulate user clearing the text of a given `TextInput` element.
|
|
115
|
+
*
|
|
116
|
+
* This method will simulate:
|
|
117
|
+
* 1. entering TextInput
|
|
118
|
+
* 2. selecting all text
|
|
119
|
+
* 3. pressing backspace to delete all text
|
|
120
|
+
* 4. leaving TextInput
|
|
121
|
+
*
|
|
122
|
+
* @param element TextInput element to clear
|
|
123
|
+
*/
|
|
124
|
+
clear: (element: ReactTestInstance) => Promise<void>;
|
|
77
125
|
}
|
|
78
126
|
|
|
79
127
|
function createInstance(config: UserEventConfig): UserEventInstance {
|
|
@@ -86,6 +134,7 @@ function createInstance(config: UserEventConfig): UserEventInstance {
|
|
|
86
134
|
press: press.bind(instance),
|
|
87
135
|
longPress: longPress.bind(instance),
|
|
88
136
|
type: type.bind(instance),
|
|
137
|
+
clear: clear.bind(instance),
|
|
89
138
|
};
|
|
90
139
|
|
|
91
140
|
Object.assign(instance, api);
|