Problem
We have a quite complex application and we don't want in each test case to go through the whole process to get to specific screen to test it, alternatively we just want to jump to specific one with some state stored in redux store.
What I've tried
I made multiple initial states which loads specific screen so I can test it directly and for each run of detox test I load different mocha.opts to select this portion of test cases and used 'react-native-config' so I can load different state in each run so for example for loading a screen I will do the following:
Question
My method is so complex and require alot of setup and overhead to run test for each screen so I was wondering if any one had the same issue and how could I solve it? In general how can I deal with the react native thread in detox?
You can set it at the reducers . Reducers can also set initialState by looking at the incoming state argument (which would be undefined if createStore is not called with initialState ) and returning the values they would like to use as default.
Redux-persist keeps a copy of your state in a storage engine, and the state copy will be loaded from there on refresh. First, you need to import the appropriate storage engine and then, to parse the state before setting it to undefined and clean each storage state key.
There is no “right” answer for this. Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state.
For the most part if you have a react-redux app I would avoid local state entirely unless you can trying to solve a very component specific problem. For example I would use local state if my component does something on a setInterval and so it is keeping its own timer.
I think there is no way detox can communicate with react native thread in runtime and change state, so I thought of a little hack that uses mocking technique as Leo Natan mentioned, it could be useful in your case
you could mock your App.js file with a screen (App.e2e.js) that has some buttons with known testIDs each button dispatch all the actions needed to load a specific state to store, you can start each test suite by pressing one of the buttons in the beforeEach
method then you can start your normal test flow after that
for example:
if you want to test a screen that is far away (requires too many clicks to reach when the user actually use the app) and requires authentication you could have the following structure:
App.e2e.js has 2 buttons:
onAuthenticationSuccess(user, authToken)
this.navigation.navigate("screenName")
test.js
describe("Screen work as intended", () => {
beforeEach(async () => {
await device.reloadReactNative();
await element(by.id("authButtonID")).tap();
await element(by.id("navigateButtonID")).tap();
});
it("should do something", async () => {
//user is loaded in store
//current screen is the screen you want to test
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With