-
Notifications
You must be signed in to change notification settings - Fork 272
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
fireEvent seems to always trigger event (on disabled TouchableOpacity) #28
Comments
Hmm seems like |
Yup, that's a desired behavior – user may press a text, which in fact may trigger a parent press event handler. |
Any idea on how I could test my behaviour? I basically don't set |
cc @Esemesek |
I think it makes sense to stop bubbling just before root component, that would prevent this and seems like a sane solution, but haven't thought it through yet |
Ah I |
For example this works: const MyComponent = ({ disabled, onPress }) => (
<View>
<TouchableHighlight onPress={disabled ? () => {} : onPress} testID={'touchable'}>
<Text>{'Foo'}</Text>
</TouchableHighlight>
</View>
) But then again I'm changing implementation to satisfy the test 😅 |
I usually do both just in case, but I guess we could detect the "disabled" prop on the Core RN components like |
There's probably more cases like this, like |
Yup, we have an idea on how to make it more generic without changing implementation of |
Just merged #30 so the bug is fixed now (not released yet). As for |
Hi @thymikee, thanks for all the hard work on the lib. I know this issue is closed and was a while ago but what was the conclusion on how to deal with a disabled prop? I'm struggling to get my test to pass. |
For test purposes you'll need to make sure by yourself that your events won't fire when disabled prop is passed, there's not really other way until the mocks are fixed. We may, however, consider some special treatment for |
So this... <Button onPress={() => {
if(thing && otherThing) {
this.props.onButtonPress()
}
}} disabled={!thing || !otherThing}>
Press Me
</Button> is the way to go for now? |
I'd extract |
Hi @thymikee, I just bumped into this same issue myself. Is there any newer workaround that doesn't involve modifying the component itself? Can this ticket be reopened? |
You can mock the TouchableOpacity and pass it default implementation plus disabled prop set correctly. We may introduce some special handling to This is unfortunately a shortcoming of our event triggering system and we'd like to create something better, but on the other hand not scoped to React Native internals – and this is gonna be hard, provided no documentation of the event/touch system and platform inconsistencies. I'm however looking forward to what the React Flare project brings. If successful, would make it way easier for us to implement robust and cross-platform React event handling. |
Thanks for the quick reply, your response is quite reasonable. For now as a temporary workaround I'm first checking the element's disabled prop and running my expectations based on that. |
We also just came across this issues. I have added a mock in the
|
In my point of view, I don't think testing should override any component, and should not change the implementation to satisfy the test. |
@swingywc no updates yet.
I see your point, but I have to disagree here. Sometimes, an inability to write a test for a piece of code indicates an accessibility issue with it – e.g. it's not usable by someone using a screen reader. |
I stumbled upon the same issue and the best workaround I found was to use this jest extension for react native. It extends the jest "expect" function with helpers like .toBeDisabled, toBeEmpty, toHaveProp etc... Very useful! |
@thymikee Are you working on this bug???
I disagree with you, I don't understand how this falls under accessibility issue you are talking about, sending different function when disabled, is literally changing code just to pass my test, not because it is requirement, because I expect onPress to be disabled when pass |
@alexakasanjeev we're not currently working on this. But the proper place to fix it is the For example, there's a new I can only advise to always wrap RN touchable components into custom components which you can control. This will also make touchables unified across your app, so it's worth doing anyway. A sample implementation: https://github.com/react-native-community/react-native-platform-touchable/blob/master/PlatformTouchable.js of such primitive |
I test the disable status by using snapshot to check the style. (When disabled, my button has a different color) // Default is disabled
it("matches snapshot", () => {
expect(wrapper).toMatchSnapshot();
});
// Button is enabled when an image is selected
it("matches snapshot when image is selected", () => {
const { getAllByTestId } = wrapper;
const checkBox = getAllByTestId("checkbox");
fireEvent.press(checkBox[0]);
expect(wrapper).toMatchSnapshot();
}); After doing this, in snapshot file there will be 2 cases for the button, which will be disabled state and enabled state with different colors. <View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"borderRadius": 50,
"bottom": 80,
"justifyContent": "center",
"opacity": 1,
"position": "absolute",
"right": 30,
"zIndex": 10,
}
}
testID="deleteButton"
>
<Text
allowFontScaling={false}
style={
Array [
Object {
"color": "#948f8f", <--- grey for disabled state
"fontSize": 40,
},
undefined,
Object {
"fontFamily": "anticon",
"fontStyle": "normal",
"fontWeight": "normal",
},
Object {},
]
}
>
</Text>
</View> <View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"borderRadius": 50,
"bottom": 80,
"justifyContent": "center",
"opacity": 1,
"position": "absolute",
"right": 30,
"zIndex": 10,
}
}
testID="deleteButton"
>
<Text
allowFontScaling={false}
style={
Array [
Object {
"color": "#000", <--- black for enabled state
"fontSize": 40,
},
undefined,
Object {
"fontFamily": "anticon",
"fontStyle": "normal",
"fontWeight": "normal",
},
Object {},
]
}
>
</Text>
</View> |
@TDAK1509 I encourage you to use https://github.com/jest-community/snapshot-diff in such cases :) |
Good news, we're fixing that in the next major release (which will involve rename to Closed via #460 |
could it be this bug is back again? Because Im testing with the extended version that is disabled like this:
and this passes correctly but then I do this:
and this fails saying it was called 1 time 😢 Im using |
I was asking my self the same question , so for me i tried to test the prop it self if it is passed correctly passed :
this is my AppButton Component :
|
@Med-Amine-Fredj it("should be disabled when the disabled prop is true", () => {
const { getByTestId } = render(<AppButton title="Test" disabled={true} />);
const button = getByTestId("AppButton-test");
expect(button).toBeDisabled();
}); |
This is still happening for me when using Pressable component? I am on version 11.4.0 How is everyone testing their disabled component now? |
I'm trying to figure out why it seems like the
fireEvent.press
function always seem to trigger a callback even though it shouldn't be registered. My use case is that I'm trying to write a test that makes sure thatonPress
isn't called if the component is "disabled".Trying to mimic the behaviour below...
The text was updated successfully, but these errors were encountered: