How to handle navigating by reference for react-navigation tests
We've set-up out navigation using these docs here, so that we can call the navigation function imperatively (e.g. from middleware functions etc).
In RootNavigation component, we set this up like this (note setting the ref on the NavigationContainer):
const RootNavigator = () => {
const setNavRef = useCallback((ref: NavigationContainerRef) => {
if (ref) {
setTopLevelNavigator(ref)
}
}, [])
return (
<NavigationContainer ref={setNavRef}>
<RootStack.Navigator>
<RootStack.Screen
name="RootCards"
component={RootCardNavigator}
/>
</RootStack.Navigator>
</NavigationContainer>
)
}
I've then tried to recreate this in the tests:
const setNavRef = ref => {
if (ref) {
setTopLevelNavigator(ref)
}
}
const component = (
<NavigationContainer ref={setNavRef}>
<RootCardNavigator {...props} />
</NavigationContainer>
)
const { findByText, findByTestId, toJSON, debug } = render(component)
const button = await findByTestId('applanding-nextbtn')
fireEvent(button, 'press')
//...test we're on the next screen
This actually works (we go to the next screen and the test passes), however I get this warning:
Warning: An update to CardContainer inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act
in CardContainer (created by CardStack)
I can hack round it by adding update(component) after the initial render in the tests, but is there a more elegant way to handle this?
@matt-dalton any luck with this?
I'm afraid not - I went with the hack in the end as I couldn't find a better way
<Navigator screenOptions={{ animationEnabled: false }}> worked for me @matt-dalton.
I assume there's some animation that's not being mocked out by the mocks suggested in https://reactnavigation.org/docs/testing/
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
// As of [email protected] file has moved
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
Think I figured out a better solution, can you try mocking react-native-screens @matt-dalton like I outline in https://github.com/react-navigation/react-navigation/issues/9701
Updated @matt-dalton with my solution in that issue.
However wondering if there's any RNTL wizards who know why React Navigation is causing this error.
@matt-dalton could you verify that the issue you reported does still occur on the latest version of RNTL (& React Native, React, React Test Renderer). If so, could you please provide repro repository hopefully based on ours examples/basic app in our repo.
I'm going to have to perform all the upgrades to be able to check that, so unfortunately won't be able to check soon
@matt-dalton understood. I'll close the issue as non-actionable. If you are able to make a repro repository please create a new issue for that.