Skip to content

Commit e36eada

Browse files
authored
Add testing-library compatibility props (#3357)
## Description This PR adds 3 props to the `Pressable` used for compatibility with [react-native-testing-library](https://github.com/callstack/react-native-testing-library) Full discussion: callstack/react-native-testing-library#1738 ## Test plan <!-- Describe how did you test this change here. -->
1 parent b3d8fd9 commit e36eada

File tree

7 files changed

+43
-14
lines changed

7 files changed

+43
-14
lines changed

src/components/GestureButtonsProps.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,30 @@ export interface RawButtonProps
5050
* Style object, use it to set additional styles.
5151
*/
5252
style?: StyleProp<ViewStyle>;
53+
54+
/**
55+
* Used for testing-library compatibility, not passed to the native component.
56+
*/
57+
// eslint-disable-next-line @typescript-eslint/ban-types
58+
testOnly_onPress?: Function | null;
59+
60+
/**
61+
* Used for testing-library compatibility, not passed to the native component.
62+
*/
63+
// eslint-disable-next-line @typescript-eslint/ban-types
64+
testOnly_onPressIn?: Function | null;
65+
66+
/**
67+
* Used for testing-library compatibility, not passed to the native component.
68+
*/
69+
// eslint-disable-next-line @typescript-eslint/ban-types
70+
testOnly_onPressOut?: Function | null;
71+
72+
/**
73+
* Used for testing-library compatibility, not passed to the native component.
74+
*/
75+
// eslint-disable-next-line @typescript-eslint/ban-types
76+
testOnly_onLongPress?: Function | null;
5377
}
5478
interface ButtonWithRefProps {
5579
innerRef?: React.ForwardedRef<React.ComponentType<any>>;

src/components/Pressable/Pressable.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ import {
2020
} from './utils';
2121
import { PressabilityDebugView } from '../../handlers/PressabilityDebugView';
2222
import { GestureTouchEvent } from '../../handlers/gestureHandlerCommon';
23-
import { INT32_MAX } from '../../utils';
23+
import { INT32_MAX, isTestEnv } from '../../utils';
2424

2525
const DEFAULT_LONG_PRESS_DURATION = 500;
26+
const IS_TEST_ENV = isTestEnv();
2627

2728
export default function Pressable(props: PressableProps) {
2829
const {
@@ -390,7 +391,11 @@ export default function Pressable(props: PressableProps) {
390391
touchSoundDisabled={android_disableSound ?? undefined}
391392
rippleColor={processColor(android_ripple?.color ?? defaultRippleColor)}
392393
rippleRadius={android_ripple?.radius ?? undefined}
393-
style={[pointerStyle, styleProp]}>
394+
style={[pointerStyle, styleProp]}
395+
testOnly_onPress={IS_TEST_ENV ? onPress : undefined}
396+
testOnly_onPressIn={IS_TEST_ENV ? onPressIn : undefined}
397+
testOnly_onPressOut={IS_TEST_ENV ? onPressOut : undefined}
398+
testOnly_onLongPress={IS_TEST_ENV ? onLongPress : undefined}>
394399
{childrenProp}
395400
{__DEV__ ? (
396401
<PressabilityDebugView color="red" hitSlop={normalizedHitSlop} />

src/handlers/createHandler.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
import { filterConfig, scheduleFlushOperations } from './utils';
2020
import findNodeHandle from '../findNodeHandle';
2121
import { ValueOf } from '../typeUtils';
22-
import { deepEqual, isFabric, isJestEnv, tagMessage } from '../utils';
22+
import { deepEqual, isFabric, isTestEnv, tagMessage } from '../utils';
2323
import { ActionType } from '../ActionType';
2424
import { PressabilityDebugView } from './PressabilityDebugView';
2525
import GestureHandlerRootViewContext from '../GestureHandlerRootViewContext';
@@ -428,7 +428,7 @@ export default function createHandler<
428428
}
429429

430430
render() {
431-
if (__DEV__ && !this.context && !isJestEnv() && Platform.OS !== 'web') {
431+
if (__DEV__ && !this.context && !isTestEnv() && Platform.OS !== 'web') {
432432
throw new Error(
433433
name +
434434
' 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<
539539
{
540540
ref: this.refHandler,
541541
collapsable: false,
542-
...(isJestEnv()
542+
...(isTestEnv()
543543
? {
544544
handlerType: name,
545545
handlerTag: this.handlerTag,

src/handlers/gestures/GestureDetector/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import findNodeHandle from '../../../findNodeHandle';
1111
import { GestureType } from '../gesture';
1212
import { UserSelect, TouchAction } from '../../gestureHandlerCommon';
1313
import { ComposedGesture } from '../gestureComposition';
14-
import { isJestEnv } from '../../../utils';
14+
import { isTestEnv } from '../../../utils';
1515

1616
import GestureHandlerRootViewContext from '../../../GestureHandlerRootViewContext';
1717
import { AttachedGestureState, GestureDetectorState } from './types';
@@ -94,7 +94,7 @@ interface GestureDetectorProps {
9494
*/
9595
export const GestureDetector = (props: GestureDetectorProps) => {
9696
const rootViewContext = useContext(GestureHandlerRootViewContext);
97-
if (__DEV__ && !rootViewContext && !isJestEnv() && Platform.OS !== 'web') {
97+
if (__DEV__ && !rootViewContext && !isTestEnv() && Platform.OS !== 'web') {
9898
throw new Error(
9999
'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.'
100100
);

src/handlers/gestures/GestureDetector/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Platform } from 'react-native';
22

3-
import { isJestEnv, tagMessage } from '../../../utils';
3+
import { isTestEnv, tagMessage } from '../../../utils';
44
import { GestureRef, BaseGesture, GestureType } from '../gesture';
55

66
import { flingGestureHandlerProps } from '../../FlingGestureHandler';
@@ -100,7 +100,7 @@ export function checkGestureCallbacksForWorklets(gesture: GestureType) {
100100
const areAllNotWorklets = !areSomeWorklets && areSomeNotWorklets;
101101
// If none of the callbacks are worklets and the gesture is not explicitly marked with
102102
// `.runOnJS(true)` show a warning
103-
if (areAllNotWorklets && !isJestEnv()) {
103+
if (areAllNotWorklets && !isTestEnv()) {
104104
console.warn(
105105
tagMessage(
106106
`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.`

src/handlers/handlersRegistry.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isJestEnv } from '../utils';
1+
import { isTestEnv } from '../utils';
22
import { GestureType } from './gestures/gesture';
33
import { GestureEvent, HandlerStateChangeEvent } from './gestureHandlerCommon';
44

@@ -13,7 +13,7 @@ export function registerHandler(
1313
testID?: string
1414
) {
1515
gestures.set(handlerTag, handler);
16-
if (isJestEnv() && testID) {
16+
if (isTestEnv() && testID) {
1717
testIDs.set(testID, handlerTag);
1818
}
1919
}
@@ -27,7 +27,7 @@ export function registerOldGestureHandler(
2727

2828
export function unregisterHandler(handlerTag: number, testID?: string) {
2929
gestures.delete(handlerTag);
30-
if (isJestEnv() && testID) {
30+
if (isTestEnv() && testID) {
3131
testIDs.delete(testID);
3232
}
3333
}

src/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ export function hasProperty(object: object, key: string) {
3434
return Object.prototype.hasOwnProperty.call(object, key);
3535
}
3636

37-
export function isJestEnv(): boolean {
37+
export function isTestEnv(): boolean {
3838
// @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.
39-
return hasProperty(global, 'process') && !!process.env.JEST_WORKER_ID;
39+
return hasProperty(global, 'process') && process.env.NODE_ENV === 'test';
4040
}
4141

4242
export function tagMessage(msg: string) {

0 commit comments

Comments
 (0)