cypress-helper-redux
Cypress commands for manipulating a Redux store during testing. For example to:
- Set up a predictable state before certain tests
- Dispatch actions to make state adjustmens before or during tests
- Validate state during or after tests have run
Inspiration
Usage
cy.reduxVisit
A wrapper around cy.visit
allowing you to specify the initial Redux state you want for a test:
cy.reduxVisit'/', ;
Other options you supply will be sent through to cy.visit
:
cy.reduxVisit'/', ;
If you don't want or need to specify any initial state, you can of course also just use cy.visit
as you normally would.
cy.redux
Gives direct access to the Redux store to do with as you please.
cy.redux.then;
If you hooked up the action creators and selectors, they're passed in as the next arguments:
cy.redux.then;
cy.reduxSelect
Wrapper around cy.redux
for selecting a value from the current state, for example to validate something after or during a test.
// Using a functioncy.reduxSelectstate.foo.value.then; // Using an already defined selector functioncy.reduxSelectgetValue.then;
cy.reduxSelector
Wrapper around cy.reduxSelect
which, if you've provided it, gives you access to the selectors object so you can pick your selector from that.
cy.reduxSelectorselectors.foo.getValue.then;
cy.reduxDispatch
Wrapper around cy.redux
for dispatching actions, for example to set something up before or during a test.
// Single actioncy.reduxDispatch; // Multiple actions, as parameterscy.reduxDispatch , , ; // Multiple actions, as arraycy.reduxDispatch;
You can also provide a callback for creating the actions:
// Callback returning a single actioncy.reduxDispatch; // Callback returning an array of actionscy.reduxDispatch;
And if you've hooked up the action creators object, it's passed in as the first argument:
// Callback returning a single action, using the action creators objectcy.reduxDispatchactions.foo.myAction; // Callback returning multiple action, using the action creators objectcy.reduxDispatch;
Setup
1. Install dependency
npm install --save-dev cypress-helper-redux
2. Include the custom commands
// In e.g. cypress/support/index.tsinclude 'cypress-helper-redux';
3. Connect the helper with your store
// E.g. in src/store/index.ts // Get initial state (for using cy.reduxVisit); // Create the store, as you normally would;; // Connect with the Cypress helperif 'Cypress' in window
4. Typescript
The Redux helper should know at least the first 2 of the following types, but preferably all of them if you want full IDE and typechecking joyfulness:
MyStore
– The type of your Redux store, i.e. the type of whatcreateStore
returns
Orimport { Store as MyStore } from redux
if you don't careMyRootState
– The shape of your root state
Ortype MyRootState = any
if you don't careMyRootAction
– The type of an allowed action
Ortype MyRootAction = AnyAction
if you don't care or have a type for thatMyActionCreators
– The type of your action creator object
Ortype MyActionCreators = any | undefined
if you don't care or don't use itMySelectors
– The type of your selectors object
Ortype MySelectors = any | undefined
if you don't care or don't use it
Haven't found a way to declare those types in an application and then "inject" them into cypress-helper-redux
in a way that allows automatically adjusting the Cypress API correctly. So... as a work around, create a type-definition file in you Cypress directory, paste the following into it, and adjust the types mentioned above as needed:
// E.g in cypress/support/cypress-helper-redux.d.ts // Import and/or define the types mentioned above; // NOTE: Do not change the following, unless the API of cypress-helper-redux changes // Define cy.redux; // Define cy.reduxVisit;; // Define cy.reduxDispatch;;; // Define cy.reduxSelect;; // Define cy.reduxSelector;; // Add them all to the Cypress chaindeclare global
Sample
For a complete example on hooking things up, have a look at the sample app.
It's also an example of how one could write things to make combining Typescript with React/Redux much more enjoyable (in my opinion at least).
It uses for example a variant of Ducks and typesafe-actions for Redux, and Redux Hooks in React the components. You'll also find a typesafe redux-thunk action, which was interesting to figure out how to type...
TODO
-
Typesafe Cypress commands, without copy-pasting stuff
Really not sure how though... ideas are welcome... 😕 -
Snapshot logging
In Cypress there seems to be a way to do snapshot logging, which I think would be very good to do before and after dispatching Redux actions. But, I haven't yet been able to figure out exactly how one does that... so, please let me know if you have any pointers... 🤔 -
Helper functions to connect store with helper
Should be simple in theory, but for some reason, everything seems to crash (gettingcy is not defined
in Cypress) the instant I do any import of helper code from the application code... Might be simple enough as it is though, and it might prevent any helper code ending up in application bundles, so... maybe better the way it is...? Advice and feedback welcome... 👍