Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add testing-library compatibility props #3357

Merged
merged 12 commits into from
Feb 3, 2025
18 changes: 18 additions & 0 deletions src/components/GestureButtonsProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ export interface RawButtonProps
* Style object, use it to set additional styles.
*/
style?: StyleProp<ViewStyle>;

/**
* Used for testing-library compatibility, not passed to the native component.
*/
// eslint-disable-next-line @typescript-eslint/ban-types
testOnly_onPress?: Function | null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of argument should be passed to testOnly_onPress?

Copy link
Contributor Author

@latekvo latekvo Jan 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testOnly_onPress will currently always be of type ((event: PressableEvent) => void) | null, but this may change if more of our components will implement testOnly_onPress.

I've made it of type Function, because RawButtonProps usage is not specific to Pressable.

Link to type definitions: (link)
Extract from type definitions:

export type InnerPressableEvent = {
  changedTouches: InnerPressableEvent[];
  identifier: number;
  locationX: number;
  locationY: number;
  pageX: number;
  pageY: number;
  target: number;
  timestamp: number;
  touches: InnerPressableEvent[];
  force?: number;
};

export type PressableEvent = { nativeEvent: InnerPressableEvent };

export interface PressableProps
  extends AccessibilityProps,
    Omit<ViewProps, 'children' | 'style' | 'hitSlop'> {

  [...]

  onPress?: null | ((event: PressableEvent) => void);
  onPressIn?: null | ((event: PressableEvent) => void);
  onPressOut?: null | ((event: PressableEvent) => void);

  [...]
}


/**
* 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;
}
interface ButtonWithRefProps {
innerRef?: React.ForwardedRef<React.ComponentType<any>>;
Expand Down
9 changes: 8 additions & 1 deletion src/components/Pressable/Pressable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,10 @@ export default function Pressable(props: PressableProps) {
? children({ pressed: pressedState })
: children;

// @ts-ignore Adding type definitions for @types/node causes multiple conflicts with react-native/types,
// and as far as i know, there is no simple way of automatically resolving them.
const inTestEnv = process.env.NODE_ENV === 'test';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use this

export function isJestEnv(): 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;
}
?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioned here: #3357 (comment)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THis would tie the implementation only to Jest test runner. In case of user using other test runners Mocha, Vitest, Bun (not all of these are supported by RNTL atm) this props will not be set. The process.env.NODE_ENV === 'test'; should support all test runners.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 4d942e8


return (
<GestureDetector gesture={gesture}>
<NativeButton
Expand All @@ -390,7 +394,10 @@ 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={inTestEnv ? onPress : undefined}
testOnly_onPressIn={inTestEnv ? onPressIn : undefined}
testOnly_onPressOut={inTestEnv ? onPressOut : undefined}>
{childrenProp}
{__DEV__ ? (
<PressabilityDebugView color="red" hitSlop={normalizedHitSlop} />
Expand Down
Loading