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
This commit is contained in:
Eli White
2020-01-28 15:14:23 -08:00
committed by Facebook Github Bot
parent 7bc2b91790
commit 4e31fbd39c
2 changed files with 25 additions and 1 deletions
+6
View File
@@ -546,6 +546,12 @@ export default class Pressability {
},
};
if (process.env.NODE_ENV === 'test') {
// We are setting this in order to find this node in ReactNativeTestTools
responderEventHandlers.onStartShouldSetResponder.testOnly_pressabilityConfig = () =>
this._config;
}
const mouseEventHandlers =
Platform.OS === 'ios' || Platform.OS === 'android'
? null
+19 -1
View File
@@ -18,7 +18,13 @@ const ReactTestRenderer = require('react-test-renderer');
const ShallowRenderer = require('react-test-renderer/shallow');
const shallowRenderer = new ShallowRenderer();
const {Switch, Text, TextInput, VirtualizedList} = require('react-native');
const {
Switch,
Text,
TextInput,
View,
VirtualizedList,
} = require('react-native');
import type {
ReactTestInstance,
@@ -36,6 +42,8 @@ function byClickable(): Predicate {
typeof node.props.onPress === 'function') ||
// note: Special casing <Switch /> since it doesn't use touchable
(node.type === Switch && node.props && node.props.disabled !== true) ||
(node.type === View &&
node?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig) ||
// HACK: Find components that use `Pressability`.
node.instance?.state?.pressability != null ||
// TODO: Remove this after deleting `Touchable`.
@@ -177,6 +185,16 @@ function tap(instance: ReactTestInstance) {
const {onChange, onValueChange} = touchable.props;
onChange && onChange({nativeEvent: {value}});
onValueChange && onValueChange(value);
} else if (
touchable?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig
) {
const {
onPress,
disabled,
} = touchable.props.onStartShouldSetResponder.testOnly_pressabilityConfig();
if (!disabled) {
onPress({nativeEvent: {}});
}
} else {
// Only tap when props.disabled isn't set (or there aren't any props)
if (!touchable.props || !touchable.props.disabled) {