victorious-traffic-84253
02/22/2023, 9:54 AMmount command that wraps my React components with my Redux Provider which works just fine - it's the same as what is explained in this guide https://docs.cypress.io/guides/component-testing/react/examples#Redux.
I have a component which compares it's previous props to it's current props, and so in my component test I need to rerender it from one boolean state to the other; To do this I am making use of the rerender method like this:
it("temporarily displays a 'saved' state when the 'saving' prop changes from true to false", () => {
const WrappedButton = ({ ...props }) => (
<Button {...props}>Click me</Button>
);
cy.mount(<WrappedButton saving={true} />).then(({ rerender }) => {
cy.get("[data-test='button-loading']").should("exist");
cy.get("[data-test='button-saved']").should("not.exist");
rerender(<WrappedButton saving={false} />);
cy.get("[data-test='button-loading']").should("not.exist");
cy.get("[data-test='button-saved']").should("exist");
});
});
Because my Button component connects to the Redux store, I'm getting the following error in Cypress when it gets to the rerender… line of code.
(uncaught exception)Invariant Violation: Could not find "store" in the context of "Connect(Button)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(Button) in connect options.
Does anyone have any ideas how to solve this? If I refactor my Button component so that it doesn't connect to the Redux store everything works as expected, but in this scenario that isn't a viable solution. I would expect any rerendered component to still be wrapped in the Redux Provider.high-holiday-75305
02/22/2023, 2:57 PMrerender, do something like cy.get("[data-test='button-finish-saving']").click() to change some state variable from true to false, causing a re-render naturally.
Rough code for wrapping re-renders (have not tested this):
Cypress.Commands.add('mount', (component, options = {}) => {
// Use the default store if one is not provided
const { reduxStore = getStore(), ...mountOptions } = options
const wrapped = <Provider store={reduxStore}>{component}</Provider>
const { rerender, ...rest } = mount(wrapped, mountOptions)
return {
rest,
rerender: (reactNode) => rerender(<Provider store={reduxStore}>{reactNode}</Provider>);
}
})victorious-traffic-84253
02/22/2023, 3:56 PMrerender method).
I have tried the first option using your rough code but unfortunately it does't work and I'm not smart enough to fix it…
Cypress detected that you invoked one or more cy commands in a custom command but returned a different value.
The custom command was:
> cy.mount()
The return value was:
> {rest: {specwindow: <window>, chainerid: ch-http://localhost:8082-130}, rerender: function(){}}
Because cy commands are asynchronous and are queued to be run later, it doesn't make sense to return anything else.
Do you have any other ideas?high-holiday-75305
02/22/2023, 4:06 PMCypress.Commands.add('mount', (component, options = {}) => {
// Use the default store if one is not provided
const { reduxStore = getStore(), ...mountOptions } = options
const wrapped = <Provider store={reduxStore}>{component}</Provider>
return mount(wrapped, mountOptions).then(({ rerender, ...rest }) => ({
...rest,
rerender: (reactNode) => rerender(<Provider store={reduxStore}>{reactNode}</Provider>),
}));
})high-holiday-75305
02/22/2023, 4:08 PMmount was a command since it wasn't prefixed with cy in that examplehigh-holiday-75305
02/22/2023, 4:10 PM...victorious-traffic-84253
02/22/2023, 4:11 PM