This folder contains setup code and fixtures for end-to-end-testing (e2e) using Cypress. Below you will find answers to questions that came up during development of the initial test suite. They may help you when fixing or developing tests for fixmy.frontend.
The main place to go when in doubt about how Cypress works are its docs, especially pay attention to the faq section.
Before starting with the FAQ, here is a short link list about the topic.
- best practices for cypress tests 1
- best practices for cypress tests 2
- best practices for general e2e testing
- lessons learned with cypress
- Cypress CI (incl. Parallelization)
Yep, checkout Der Softwerker: Frontend Spezial by CodeCentric. The german article "Cypress und Redux" from Enno Lohmann explains the basics of Cypress (how to reference and interact with elements and more) and how it can be used in a Redux-driven app. As of now it is my primary source besides the Cypress docs.
2. Redux integration: How can I manipulate the store to put the app in a certain state before I can interact with the UI to test it?
It is an anti-pattern to set the app in a certain, testable state just by changing routes and simulating user interactions. In a redux-based app, the store can be mainpulated directly to configure the app with the desired state before tests are run.
There are two options:
- Within a test, the store can be retrieved in order to dispatch actions that manipulate state.
- An object can be provided as initial state to be loaded during initialization of the app.
During Cypress tests, the Redux store is globally made available by attaching it to the window object. During a test, the store can be bound to an alias that may then be used by other Cypress commands:
cy.window()
.its('store')
.as('store');
Having aliased the store, an action could be dispatched like so:
cy.get('@store') // get the store using the alias defined before
.invoke('dispatch', { type: types.ADD_TODO, text: 'Einkaufen' }); // invoke the dispatch method and pass the action
Of course we can also read the store using getState()
.
This option is already used in the KatasterKI tests.
The idea here is to set window.initialState
to a certain object,
e.g. retrieved by loading a JSON using a fixture.
The top-level reducer is configured so that it initializes the app's state from
window.initialState
if window.Cypress
is defined.
Providing this initialState
should be done before UI tests are fired, e.g. by
using before
\ beforeEach
hooks or by hooking into the beginning of a
route change like so:
cy.visit('/', {
onBeforeLoad: (win) => {
win.initialState = {
// some state
};
}
});
The following way worked for me, there surely are smarter ways.
- Set a debugger statement somewhere before you think the error resides.
- Start the dev server, then run
npm run cypress -- run --browser chrome
in another console / run window This will launch chrome with open dev tools which should stop at the entered break point.
Yes, you can use the environment variable CYPRESS_BROWSER_WINDOW
to control the
position and size of the window. For example with
$ CYPRESS_BROWSER_WINDOW="1920,1080;1920,0" npm run test:e2e-chrome
You can start the integration test suite and run it in browser windows of size 1920x1080 which start at x=1920 y=0 on the screen.
Caveat: Enabling this option will also direct Chrome to use a user data directory at
~/chrome-test-user
.