React-native: Can't trigger on TouchableOpacity.onPress or Text.onPress event

Created on 10 Feb 2017  路  2Comments  路  Source: facebook/react-native

Testing react-native TouchableOpacity.onPress does not work, can't manually trigger an onPress() event from tests.

Given a component that contains a TouchableOpacity:

export default function Button(props) {
    return (
        <TouchableOpacity
            accessible={false}
            onPress ={ props.onPress }
            style ={ someStyle }
        >
            <Text style={ someTextStyle }>
                Press ME!
            </Text>
        </TouchableOpacity>
    );
};

And given a test, that renders it:

it("renders and press button", () => {
    const btn = create(<Button onPress={() => ...} />);
    const btnTree = btn.toJSON();
    expect(btnTree).toMatchSnapshot(); // works
    debugger;
    btnTree.children[0].props.onPress() // too bad
});

If i break point just before trying to trigger the onPress, i can get to explore what is inside the tree for the TouchableOpacity component (btnTree.children[0]):

{ type: 'View',
  props: 
   { accessible: false,
     accessibilityLabel: undefined,
     accessibilityComponentType: undefined,
     accessibilityTraits: undefined,
     style: 
      { backgroundColor: '#F7C92F',
        alignSelf: 'stretch',
        borderRadius: 1,
        marginBottom: 5,
        opacity: 1 },
     testID: undefined,
     onLayout: undefined,
     isTVSelectable: true,
     tvParallaxProperties: undefined,
     hitSlop: undefined,
     onStartShouldSetResponder: [Function: val],
     onResponderTerminationRequest: [Function: val],
     onResponderGrant: [Function: val],
     onResponderMove: [Function: val],
     onResponderRelease: [Function: val],
     onResponderTerminate: [Function: val] },
  children: 
   [ { type: 'Text',
       props: [Object],
       children: [Object],
       '$$typeof': [Object] } ],
  '$$typeof': 
   { handle: 15,
     type: 'symbol',
     description: 'react.test.json',
     text: 'Symbol(react.test.json)' } }

As you can see, there is no onPress at the props, now if instead of adding the onPress at the TouchableOpacity, i add it to the Text component. I would be able to see an onPress prop there, but i'm still unable to call the method.

I would expect to be able to trigger an onPress for testing.

Using "react-native": "0.41.0", "react-test-renderer": "~15.4.2", "jest": "^18.1.0", with "preset": "react-native",

Locked

All 2 comments

I would not expect children[0].props.onPress() to work. In general I don't think you are supposed to be able to grab props and children off the React tree like that. For the more general case of how to test touch events, maybe http://stackoverflow.com/questions/35138975/unit-testing-touch-events-in-react-native is useful for you? If that doesn't work, then I would suggest refactoring so that you can call this method without doing the children[0].props thing. Hope this helps!

hi, i'm new to reactnative. i have this stop watch i have been experimenting with but it isnt working. it doesnt display any errors, i think the onPress() isn't doing what it's supposed to.......

import React, { Component } from 'react';
import { AppRegistry,
Text ,
StyleSheet,
View,
TouchableHighlight,
} from 'react-native';

class AwesomeProject extends Component {

constructor(props){
super(props);
this.state={timeElapsed:null};
}

render() {
return (

<View style={styles.container}>
    <View style={[styles.header, this.border('yellow')]}>
        <View style={[styles.timerWrapper, this.border('red')]}>
            <Text>
                {this.state.timeElapsed}
            </Text>
        </View>
        <View style={[styles.buttonWrapper, this.border('green')]}>
            {this.startStopButton()}
            {this.lapButton()}
        </View>
    </View>
    <View style={[styles.footer, this.border('blue')]}>
        <Text>
            List of laps
        </Text>
    </View>
</View>

);

}

startStopButton(){
return (
underlayColor="grey"
onPress={()=>{this.handleStartPress}}>

Start


);
}

lapButton(){
return (


Lap


);
}

handleStartPress(){
var startTime = new Date();

setInterval(() => {
this.setState({
    timeElapsed: new Date() - startTime
});

}, 30);
}

border(color){
return{
borderColor: color,
borderWidth: 4
}

}
}

var styles = StyleSheet.create({
container : {
flex: 1, //Fill the entire screen
alignItems: 'stretch'
},

header:{//yellow
    flex: 1
},

footer:{//blue
    flex: 1
},

timerWrapper:{
    flex: 5,
    justifyContent: 'center',
    alignItems: 'center'
},

buttonWrapper:{
    flex: 3,
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center'
}

});

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

Was this page helpful?
0 / 5 - 0 ratings