Skip to content

Commit 4e31fbd

Browse files
elicwhitefacebook-github-bot
authored andcommitted
Pressable: Update ReactTestTools to be able to tab on Pressable
Summary: This was all yungsters idea. I blame him. :) Switching Pressable to be a functional component presents a new challenge. ReactNativeTestTools can no longer find its instance because there is no instance Pressable uses forwardRef. We need a way to both find a pressable, and then call the onPress callback if the pressable isn't also disabled. So in DEV (and thus test) we add the pressable config to a secret key on a function passed onto View. The TestTools look for this key on this function, and then can call onPress. Super hacky, but so is all of ReactNativeTestTools. We aren't proud of this. Changelog: [General][Changed]: Added support for Pressable to ReactNativeTestTools.tap Reviewed By: yungsters Differential Revision: D18849358 fbshipit-source-id: ea8880ceedfc04cda217ee17ba140475d003172c
1 parent 7bc2b91 commit 4e31fbd

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

Libraries/Pressability/Pressability.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,12 @@ export default class Pressability {
546546
},
547547
};
548548

549+
if (process.env.NODE_ENV === 'test') {
550+
// We are setting this in order to find this node in ReactNativeTestTools
551+
responderEventHandlers.onStartShouldSetResponder.testOnly_pressabilityConfig = () =>
552+
this._config;
553+
}
554+
549555
const mouseEventHandlers =
550556
Platform.OS === 'ios' || Platform.OS === 'android'
551557
? null

Libraries/Utilities/ReactNativeTestTools.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ const ReactTestRenderer = require('react-test-renderer');
1818
const ShallowRenderer = require('react-test-renderer/shallow');
1919
const shallowRenderer = new ShallowRenderer();
2020

21-
const {Switch, Text, TextInput, VirtualizedList} = require('react-native');
21+
const {
22+
Switch,
23+
Text,
24+
TextInput,
25+
View,
26+
VirtualizedList,
27+
} = require('react-native');
2228

2329
import type {
2430
ReactTestInstance,
@@ -36,6 +42,8 @@ function byClickable(): Predicate {
3642
typeof node.props.onPress === 'function') ||
3743
// note: Special casing <Switch /> since it doesn't use touchable
3844
(node.type === Switch && node.props && node.props.disabled !== true) ||
45+
(node.type === View &&
46+
node?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig) ||
3947
// HACK: Find components that use `Pressability`.
4048
node.instance?.state?.pressability != null ||
4149
// TODO: Remove this after deleting `Touchable`.
@@ -177,6 +185,16 @@ function tap(instance: ReactTestInstance) {
177185
const {onChange, onValueChange} = touchable.props;
178186
onChange && onChange({nativeEvent: {value}});
179187
onValueChange && onValueChange(value);
188+
} else if (
189+
touchable?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig
190+
) {
191+
const {
192+
onPress,
193+
disabled,
194+
} = touchable.props.onStartShouldSetResponder.testOnly_pressabilityConfig();
195+
if (!disabled) {
196+
onPress({nativeEvent: {}});
197+
}
180198
} else {
181199
// Only tap when props.disabled isn't set (or there aren't any props)
182200
if (!touchable.props || !touchable.props.disabled) {

0 commit comments

Comments
 (0)