Skip to content

Commit 4781177

Browse files
committed
.
1 parent e9b1ce8 commit 4781177

File tree

1 file changed

+40
-52
lines changed

1 file changed

+40
-52
lines changed

src/user-event/press/press.ts

Lines changed: 40 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import type { ReactTestInstance } from 'react-test-renderer';
33
import act from '../../act';
44
import { getEventHandler } from '../../event-handler';
55
import { getHostParent, isHostElement } from '../../helpers/component-tree';
6-
import { isHostTextInput } from '../../helpers/host-component-names';
6+
import { isHostText, isHostTextInput } from '../../helpers/host-component-names';
77
import { isPointerEventEnabled } from '../../helpers/pointer-events';
8-
import { isEditableTextInput } from '../../helpers/text-input';
98
import { EventBuilder } from '../event-builder';
109
import type { UserEventConfig, UserEventInstance } from '../setup';
1110
import { dispatchEvent, wait } from '../utils';
@@ -46,18 +45,13 @@ const basePress = async (
4645
element: ReactTestInstance,
4746
options: BasePressOptions,
4847
): Promise<void> => {
49-
if (isEditableTextInput(element) && isPointerEventEnabled(element)) {
50-
await emitTextInputPressEvents(config, element, options);
51-
return;
52-
}
53-
54-
if (!isHostTextInput(element) && isHostPressable(element)) {
55-
await emitTextPressEvents(config, element, options);
48+
if (isEnabledHostElement(element) && hasPressEventHandler(element)) {
49+
await emitDirectPressEvents(config, element, options);
5650
return;
5751
}
5852

5953
if (isEnabledTouchResponder(element)) {
60-
await emitPressablePressEvents(config, element, options);
54+
await emitPressabilityPressEvents(config, element, options);
6155
return;
6256
}
6357

@@ -69,53 +63,40 @@ const basePress = async (
6963
await basePress(config, hostParentElement, options);
7064
};
7165

72-
const emitPressablePressEvents = async (
73-
config: UserEventConfig,
74-
element: ReactTestInstance,
75-
options: BasePressOptions,
76-
) => {
77-
await wait(config);
78-
79-
dispatchEvent(element, 'responderGrant', EventBuilder.Common.responderGrant());
80-
81-
const duration = options.duration ?? DEFAULT_MIN_PRESS_DURATION;
82-
await wait(config, duration);
66+
function isEnabledHostElement(element: ReactTestInstance) {
67+
if (!isHostElement(element) || !isPointerEventEnabled(element)) {
68+
return false;
69+
}
8370

84-
dispatchEvent(element, 'responderRelease', EventBuilder.Common.responderRelease());
71+
if (isHostText(element)) {
72+
return element.props.disabled !== true;
73+
}
8574

86-
// React Native will wait for minimal delay of DEFAULT_MIN_PRESS_DURATION
87-
// before emitting the `pressOut` event. We need to wait here, so that
88-
// `press()` function does not return before that.
89-
if (DEFAULT_MIN_PRESS_DURATION - duration > 0) {
90-
await act(async () => {
91-
await wait(config, DEFAULT_MIN_PRESS_DURATION - duration);
92-
});
75+
if (isHostTextInput(element)) {
76+
// @ts-expect-error - workaround incorrect ReactTestInstance type
77+
return element.props.editable !== false;
9378
}
94-
};
9579

96-
const isEnabledTouchResponder = (element: ReactTestInstance) => {
80+
return true;
81+
}
82+
83+
function isEnabledTouchResponder(element: ReactTestInstance) {
9784
return isPointerEventEnabled(element) && element.props.onStartShouldSetResponder?.();
98-
};
85+
}
9986

100-
const isHostPressable = (element: ReactTestInstance) => {
101-
const hasPressEventHandler =
87+
function hasPressEventHandler(element: ReactTestInstance) {
88+
return (
10289
getEventHandler(element, 'press') ||
10390
getEventHandler(element, 'longPress') ||
10491
getEventHandler(element, 'pressIn') ||
105-
getEventHandler(element, 'pressOut');
106-
107-
return (
108-
isHostElement(element) &&
109-
isPointerEventEnabled(element) &&
110-
!element.props.disabled &&
111-
hasPressEventHandler
92+
getEventHandler(element, 'pressOut')
11293
);
113-
};
94+
}
11495

11596
/**
116-
* Dispatches a press event sequence for Text.
97+
* Dispatches a press event sequence for host elements that have `onPress*` event handlers.
11798
*/
118-
async function emitTextPressEvents(
99+
async function emitDirectPressEvents(
119100
config: UserEventConfig,
120101
element: ReactTestInstance,
121102
options: BasePressOptions,
@@ -141,19 +122,26 @@ async function emitTextPressEvents(
141122
}
142123
}
143124

144-
/**
145-
* Dispatches a press event sequence for TextInput.
146-
*/
147-
async function emitTextInputPressEvents(
125+
async function emitPressabilityPressEvents(
148126
config: UserEventConfig,
149127
element: ReactTestInstance,
150128
options: BasePressOptions,
151129
) {
152130
await wait(config);
153-
dispatchEvent(element, 'pressIn', EventBuilder.Common.touch());
154131

155-
// Note: TextInput does not have `onPress`/`onLongPress` props.
132+
dispatchEvent(element, 'responderGrant', EventBuilder.Common.responderGrant());
156133

157-
await wait(config, options.duration);
158-
dispatchEvent(element, 'pressOut', EventBuilder.Common.touch());
134+
const duration = options.duration ?? DEFAULT_MIN_PRESS_DURATION;
135+
await wait(config, duration);
136+
137+
dispatchEvent(element, 'responderRelease', EventBuilder.Common.responderRelease());
138+
139+
// React Native will wait for minimal delay of DEFAULT_MIN_PRESS_DURATION
140+
// before emitting the `pressOut` event. We need to wait here, so that
141+
// `press()` function does not return before that.
142+
if (DEFAULT_MIN_PRESS_DURATION - duration > 0) {
143+
await act(async () => {
144+
await wait(config, DEFAULT_MIN_PRESS_DURATION - duration);
145+
});
146+
}
159147
}

0 commit comments

Comments
 (0)