11import { ReactTestInstance } from 'react-test-renderer' ;
2- import act from '../../act' ;
32import { getHostParent } from '../../helpers/component-tree' ;
43import { isTextInputEditable } from '../../helpers/text-input' ;
54import { isPointerEventEnabled } from '../../helpers/pointer-events' ;
65import { isHostText , isHostTextInput } from '../../helpers/host-component-names' ;
76import { EventBuilder } from '../event-builder' ;
87import { UserEventConfig , UserEventInstance } from '../setup' ;
98import { dispatchEvent , wait } from '../utils' ;
10- import { DEFAULT_MIN_PRESS_DURATION } from './constants' ;
9+
10+ // These are constants defined in the React Native repo
11+ export const DEFAULT_MIN_PRESS_DURATION = 130 ;
12+ export const DEFAULT_LONG_PRESS_DELAY_MS = 500 ;
1113
1214export interface PressOptions {
1315 duration ?: number ;
@@ -27,7 +29,7 @@ export async function longPress(
2729) : Promise < void > {
2830 await basePress ( this . config , element , {
2931 type : 'longPress' ,
30- duration : options ?. duration ?? 500 ,
32+ duration : options ?. duration ?? DEFAULT_LONG_PRESS_DELAY_MS ,
3133 } ) ;
3234}
3335
@@ -73,18 +75,14 @@ const emitPressablePressEvents = async (
7375
7476 dispatchEvent ( element , 'responderGrant' , EventBuilder . Common . responderGrant ( ) ) ;
7577
76- await wait ( config , options . duration ) ;
78+ // We apply minimum press duration here to ensure that `press` events are emitted after `pressOut`.
79+ // Otherwise, pressables would emit them in the reverse order, which in reality happens only for
80+ // very short presses (< 130ms) and contradicts the React Native docs.
81+ // See: https://reactnative.dev/docs/pressable#onpress
82+ let duration = Math . max ( options . duration , DEFAULT_MIN_PRESS_DURATION ) ;
83+ await wait ( config , duration ) ;
7784
7885 dispatchEvent ( element , 'responderRelease' , EventBuilder . Common . responderRelease ( ) ) ;
79-
80- // React Native will wait for minimal delay of DEFAULT_MIN_PRESS_DURATION
81- // before emitting the `pressOut` event. We need to wait here, so that
82- // `press()` function does not return before that.
83- if ( DEFAULT_MIN_PRESS_DURATION - options . duration > 0 ) {
84- await act ( async ( ) => {
85- await wait ( config , DEFAULT_MIN_PRESS_DURATION - options . duration ) ;
86- } ) ;
87- }
8886} ;
8987
9088const isEnabledTouchResponder = ( element : ReactTestInstance ) => {
@@ -127,7 +125,10 @@ async function emitTextPressEvents(
127125
128126 dispatchEvent ( element , 'pressOut' , EventBuilder . Common . touch ( ) ) ;
129127
130- // Regular press events are emitted after `pressOut`.
128+ // Regular press events are emitted after `pressOut` according to the React Native docs.
129+ // See: https://reactnative.dev/docs/pressable#onpress
130+ // Experimentally for very short presses (< 130ms) `press` events are actually emitted before `onPressOut`, but
131+ // we will ignore that as in reality most pressed would be above the 130ms threshold.
131132 if ( options . type === 'press' ) {
132133 dispatchEvent ( element , 'press' , EventBuilder . Common . touch ( ) ) ;
133134 }
0 commit comments