Skip to content

Latest commit

 

History

History
101 lines (70 loc) · 4.57 KB

README.MD

File metadata and controls

101 lines (70 loc) · 4.57 KB

Cypress End-To-End-Testing

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.

FAQ

1. How can I get started? Is there some kind of High Level introduction article?

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:

  1. Within a test, the store can be retrieved in order to dispatch actions that manipulate state.
  2. An object can be provided as initial state to be loaded during initialization of the app.

1. Within a test, get a reference to the store and dispatch actions

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().

2. Before a test, provide an initialState and let the reducer pick it up

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
    };
  }
});

3. A test fails. How can I debug it?

The following way worked for me, there surely are smarter ways.

  1. Set a debugger statement somewhere before you think the error resides.
  2. 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.

4. I don't like where Cypress opens the Chrome browser window. Can I change it?

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.