diff --git a/src/components/GestureButtonsProps.ts b/src/components/GestureButtonsProps.ts index e5075a17da..dabf62d5f1 100644 --- a/src/components/GestureButtonsProps.ts +++ b/src/components/GestureButtonsProps.ts @@ -50,6 +50,30 @@ export interface RawButtonProps * Style object, use it to set additional styles. */ style?: StyleProp; + + /** + * Used for testing-library compatibility, not passed to the native component. + */ + // eslint-disable-next-line @typescript-eslint/ban-types + testOnly_onPress?: Function | null; + + /** + * Used for testing-library compatibility, not passed to the native component. + */ + // eslint-disable-next-line @typescript-eslint/ban-types + testOnly_onPressIn?: Function | null; + + /** + * Used for testing-library compatibility, not passed to the native component. + */ + // eslint-disable-next-line @typescript-eslint/ban-types + testOnly_onPressOut?: Function | null; + + /** + * Used for testing-library compatibility, not passed to the native component. + */ + // eslint-disable-next-line @typescript-eslint/ban-types + testOnly_onLongPress?: Function | null; } interface ButtonWithRefProps { innerRef?: React.ForwardedRef>; diff --git a/src/components/Pressable/Pressable.tsx b/src/components/Pressable/Pressable.tsx index 9223a18cc1..3781afb9f6 100644 --- a/src/components/Pressable/Pressable.tsx +++ b/src/components/Pressable/Pressable.tsx @@ -20,9 +20,10 @@ import { } from './utils'; import { PressabilityDebugView } from '../../handlers/PressabilityDebugView'; import { GestureTouchEvent } from '../../handlers/gestureHandlerCommon'; -import { INT32_MAX } from '../../utils'; +import { INT32_MAX, isTestEnv } from '../../utils'; const DEFAULT_LONG_PRESS_DURATION = 500; +const IS_TEST_ENV = isTestEnv(); export default function Pressable(props: PressableProps) { const { @@ -390,7 +391,11 @@ export default function Pressable(props: PressableProps) { touchSoundDisabled={android_disableSound ?? undefined} rippleColor={processColor(android_ripple?.color ?? defaultRippleColor)} rippleRadius={android_ripple?.radius ?? undefined} - style={[pointerStyle, styleProp]}> + style={[pointerStyle, styleProp]} + testOnly_onPress={IS_TEST_ENV ? onPress : undefined} + testOnly_onPressIn={IS_TEST_ENV ? onPressIn : undefined} + testOnly_onPressOut={IS_TEST_ENV ? onPressOut : undefined} + testOnly_onLongPress={IS_TEST_ENV ? onLongPress : undefined}> {childrenProp} {__DEV__ ? ( diff --git a/src/handlers/createHandler.tsx b/src/handlers/createHandler.tsx index 371d632514..06b269c7d7 100644 --- a/src/handlers/createHandler.tsx +++ b/src/handlers/createHandler.tsx @@ -19,7 +19,7 @@ import { import { filterConfig, scheduleFlushOperations } from './utils'; import findNodeHandle from '../findNodeHandle'; import { ValueOf } from '../typeUtils'; -import { deepEqual, isFabric, isJestEnv, tagMessage } from '../utils'; +import { deepEqual, isFabric, isTestEnv, tagMessage } from '../utils'; import { ActionType } from '../ActionType'; import { PressabilityDebugView } from './PressabilityDebugView'; import GestureHandlerRootViewContext from '../GestureHandlerRootViewContext'; @@ -428,7 +428,7 @@ export default function createHandler< } render() { - if (__DEV__ && !this.context && !isJestEnv() && Platform.OS !== 'web') { + if (__DEV__ && !this.context && !isTestEnv() && Platform.OS !== 'web') { throw new Error( name + ' must be used as a descendant of GestureHandlerRootView. Otherwise the gestures will not be recognized. See https://docs.swmansion.com/react-native-gesture-handler/docs/installation for more details.' @@ -539,7 +539,7 @@ export default function createHandler< { ref: this.refHandler, collapsable: false, - ...(isJestEnv() + ...(isTestEnv() ? { handlerType: name, handlerTag: this.handlerTag, diff --git a/src/handlers/gestures/GestureDetector/index.tsx b/src/handlers/gestures/GestureDetector/index.tsx index dac3e49495..71f9dd2948 100644 --- a/src/handlers/gestures/GestureDetector/index.tsx +++ b/src/handlers/gestures/GestureDetector/index.tsx @@ -11,7 +11,7 @@ import findNodeHandle from '../../../findNodeHandle'; import { GestureType } from '../gesture'; import { UserSelect, TouchAction } from '../../gestureHandlerCommon'; import { ComposedGesture } from '../gestureComposition'; -import { isJestEnv } from '../../../utils'; +import { isTestEnv } from '../../../utils'; import GestureHandlerRootViewContext from '../../../GestureHandlerRootViewContext'; import { AttachedGestureState, GestureDetectorState } from './types'; @@ -94,7 +94,7 @@ interface GestureDetectorProps { */ export const GestureDetector = (props: GestureDetectorProps) => { const rootViewContext = useContext(GestureHandlerRootViewContext); - if (__DEV__ && !rootViewContext && !isJestEnv() && Platform.OS !== 'web') { + if (__DEV__ && !rootViewContext && !isTestEnv() && Platform.OS !== 'web') { throw new Error( 'GestureDetector must be used as a descendant of GestureHandlerRootView. Otherwise the gestures will not be recognized. See https://docs.swmansion.com/react-native-gesture-handler/docs/installation for more details.' ); diff --git a/src/handlers/gestures/GestureDetector/utils.ts b/src/handlers/gestures/GestureDetector/utils.ts index 3d3d79ed70..784eb297ae 100644 --- a/src/handlers/gestures/GestureDetector/utils.ts +++ b/src/handlers/gestures/GestureDetector/utils.ts @@ -1,6 +1,6 @@ import { Platform } from 'react-native'; -import { isJestEnv, tagMessage } from '../../../utils'; +import { isTestEnv, tagMessage } from '../../../utils'; import { GestureRef, BaseGesture, GestureType } from '../gesture'; import { flingGestureHandlerProps } from '../../FlingGestureHandler'; @@ -100,7 +100,7 @@ export function checkGestureCallbacksForWorklets(gesture: GestureType) { const areAllNotWorklets = !areSomeWorklets && areSomeNotWorklets; // If none of the callbacks are worklets and the gesture is not explicitly marked with // `.runOnJS(true)` show a warning - if (areAllNotWorklets && !isJestEnv()) { + if (areAllNotWorklets && !isTestEnv()) { console.warn( tagMessage( `None of the callbacks in the gesture are worklets. If you wish to run them on the JS thread use '.runOnJS(true)' modifier on the gesture to make this explicit. Otherwise, mark the callbacks as 'worklet' to run them on the UI thread.` diff --git a/src/handlers/handlersRegistry.ts b/src/handlers/handlersRegistry.ts index 3a19447edf..f070fc94b2 100644 --- a/src/handlers/handlersRegistry.ts +++ b/src/handlers/handlersRegistry.ts @@ -1,4 +1,4 @@ -import { isJestEnv } from '../utils'; +import { isTestEnv } from '../utils'; import { GestureType } from './gestures/gesture'; import { GestureEvent, HandlerStateChangeEvent } from './gestureHandlerCommon'; @@ -13,7 +13,7 @@ export function registerHandler( testID?: string ) { gestures.set(handlerTag, handler); - if (isJestEnv() && testID) { + if (isTestEnv() && testID) { testIDs.set(testID, handlerTag); } } @@ -27,7 +27,7 @@ export function registerOldGestureHandler( export function unregisterHandler(handlerTag: number, testID?: string) { gestures.delete(handlerTag); - if (isJestEnv() && testID) { + if (isTestEnv() && testID) { testIDs.delete(testID); } } diff --git a/src/utils.ts b/src/utils.ts index 8d7284a443..727fcb4937 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -34,9 +34,9 @@ export function hasProperty(object: object, key: string) { return Object.prototype.hasOwnProperty.call(object, key); } -export function isJestEnv(): boolean { +export function isTestEnv(): boolean { // @ts-ignore Do not use `@types/node` because it will prioritise Node types over RN types which breaks the types (ex. setTimeout) in React Native projects. - return hasProperty(global, 'process') && !!process.env.JEST_WORKER_ID; + return hasProperty(global, 'process') && process.env.NODE_ENV === 'test'; } export function tagMessage(msg: string) {