1
1
import { ReactTestInstance } from 'react-test-renderer' ;
2
- import act from '../../act' ;
3
2
import { getHostParent } from '../../helpers/component-tree' ;
4
3
import { isTextInputEditable } from '../../helpers/text-input' ;
5
4
import { isPointerEventEnabled } from '../../helpers/pointer-events' ;
6
5
import { isHostText , isHostTextInput } from '../../helpers/host-component-names' ;
7
6
import { EventBuilder } from '../event-builder' ;
8
7
import { UserEventConfig , UserEventInstance } from '../setup' ;
9
8
import { 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 ;
11
13
12
14
export interface PressOptions {
13
15
duration ?: number ;
@@ -27,7 +29,7 @@ export async function longPress(
27
29
) : Promise < void > {
28
30
await basePress ( this . config , element , {
29
31
type : 'longPress' ,
30
- duration : options ?. duration ?? 500 ,
32
+ duration : options ?. duration ?? DEFAULT_LONG_PRESS_DELAY_MS ,
31
33
} ) ;
32
34
}
33
35
@@ -73,18 +75,14 @@ const emitPressablePressEvents = async (
73
75
74
76
dispatchEvent ( element , 'responderGrant' , EventBuilder . Common . responderGrant ( ) ) ;
75
77
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 ) ;
77
84
78
85
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
- }
88
86
} ;
89
87
90
88
const isEnabledTouchResponder = ( element : ReactTestInstance ) => {
@@ -127,7 +125,10 @@ async function emitTextPressEvents(
127
125
128
126
dispatchEvent ( element , 'pressOut' , EventBuilder . Common . touch ( ) ) ;
129
127
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.
131
132
if ( options . type === 'press' ) {
132
133
dispatchEvent ( element , 'press' , EventBuilder . Common . touch ( ) ) ;
133
134
}
0 commit comments