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:11:53 -08:00 коммит произвёл Facebook Github Bot
Родитель 7bc2b91790
Коммит 4e31fbd39c
2 изменённых файлов: 25 добавлений и 1 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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) {