End to End testing with React and Cypress

Emily Williams
Imagine Learning Engineering
8 min readJul 13, 2020

The purpose of this article is going to be from an absolute beginner’s perspective on how to set up Cypress and do End to End testing on a simple react application. Before we begin here is a link to Cypress documentation for added clarity
https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell

Now let’s get started.

First, we need to install Yarn on your machine.

For Windows https://classic.yarnpkg.com/en/docs/install#windows-stable

For Mac https://classic.yarnpkg.com/en/docs/install#mac-stable

Create a folder on your computer for your project to be
Open your terminal and cd into the newly created folder.

## clone this repo to a local directoryhttps://github.com/emilystaheli/CypressVisionconferencegit clone https://github.com/<yourUsername>/CypressVisionconference.git## cd into the cloned repocd CypressVisionconference/## install the node_modulesyarn install## start the local webserveryarn start
navigate to http://localhost:8888/#/ to test that it’s working

Install Cypress

Once you have the above project up and running, it’s time to get started installing Cypress.

Navigate to your project directory. Run the following command.

yarn add cypress --dev

This install may take a few minutes as it will install the Javascript package and the Cypress binary needed to execute tests.

If you get an error saying Cypress failed to start, this could be caused by a missing library or dependency.

Run

Npx cypress install --force

Now lets open Cypress by running the following command

yarn run cypress open

When this command runs, it will open the Cypress test runner. Since this is the first time we are running it, it will generate the folder structure and some sample tests. Once the UI opens, feel free to spend some time familiarizing yourself with the test runner.

Now let’s look at the file structure that was generated. There will be a cypress folder that gets initialized inside the root directory of your application. Inside that folder, four more will also have been created.

- cypress|- fixtures|- integration|- plugins|- support

Fixtures

The fixtures folder is where you can store static data used throughout your tests. This can include test data or mock responses.

Integration

This folder is where all of your tests will live. The sample tests that you experimented with earlier will all have been generated here.

Plugins

Cypress has a node process that can be used to extend some of its functionality. This includes configuring file pre-processors or loading configurations.

Support

Out of the box, Cypress provides the support/index.js file that will be run before every spec file. It can be used for several things such as a global beforeEach hook, overrides, and setting up custom commands.

Now that Cypress is running let’s write some End to End tests.

We are going to be doing several tests with Cypress using todoMVC. The application will give you a good variety of writing tests in Cypress.

First, navigate to cypress/integration In the integration folder create a new spec file called input-form.spec.js

Let’s start by testing the input form

At the top of the input-form.spec.jsadd

/// <reference types="cypress" />

By adding this line in your tests makes it possible for IntelliSense to work with Cypress

All Cypress tests will need to be inside a describe and an it block; a describe block describes what your test is doing, and an it block says what you are testing.

Loads the site
So add a describe block and start the first test with an it. Before we test any behavior, we need to visit the page first. To do this we use the command cy.visit(“)

describe('Input form', () => {
it('opens the site', () => {
cy.visit('localhost:8888'); //this is the server that was started earlier
})
})

Before we continue, let’s make sure that we can reach our application.
Startup cypress with

yarn run cypress open

When Cypress opens choose input-form.spec.js

Now let’s verify that it loads the page. Click on input-form.spec.js when Cypress runs. We will see the description from the describe block and the individual test description.

Now that we verified that the site is working let’s write some more tests

Test user input

First, let us test that the input is working and that we will accept input from the user. We will need to select the input form and type what we want to put in the todo. One difference that Cypress has with selenium is that it doesn’t use the ‘by’ selectors that selenium uses. Instead, We will be using cy.get(‘’) to select the element. Cypress makes it easy to find out what selector you need. Run Cypress and use the cypress selector tool and hover over the elements that you want to select then click on the Copy icon.

The selector that Cypress selected is .new-todo, so let’s put that with the cy.get(). If you want to place text in an input field, you will need to use cy.type() command.

After the text is entered into the input-form, we want to check that the text is correct. We will do this by adding .should at the end of the .type method and chain them together.

it('check input text', () => {cy.get('.newtodo').type('Vision Conference').should('have.value', 'Vision Conference');})

Check that task is entered and saved.

After the text is entered into the input-form, we still have to click the enter button to add the item; this is done by adding {enter} in the cy.type. In the todos, let’s check to see if the todo is added correctly. Select the todo item.

it('check input text', () => {
cy.get('.new-todo').clear()
cy.get('.new-todo').type('Vision Conference{enter}')
cy.get('.todo-list li').should('have.text', 'Vision Conference');
});

Let’s go ahead and add a few more items in the todos and check that we can enter multiple items. create three variables at the top of your file before the describe block

var TODO_ITEM_ONE = 'Virtual Adventure';
var TODO_ITEM_TWO = 'Booster Bingo';
var TODO_ITEM_THREE = 'Lip Sync Contest';

Now create a new it block creating three new todos.

it('should add multiple todos', ()=>{
cy.get('.new-todo').type(TODO_ITEM_ONE+'{enter}')
cy.get('.new-todo').type(TODO_ITEM_TWO+'{enter}')
cy.get('.new-todo').type(TODO_ITEM_THREE+'{enter}')
})

Now let’s test that we have all the items. To check items in a list, we will use the .eq() .ea(0) would be the first item in the list eq(1) will be the second and so forth.

it('should have append new items to the bottom of the list', () => {
cy.get('.todo-list li').eq(0).find('label').should('contain', 'Vision Conference')
cy.get('.todo-list li').eq(1).find('label').should('contain', TODO_ITEM_ONE)
cy.get('.todo-list li').eq(2).find('label').should('contain', TODO_ITEM_TWO)
cy.get('.todo-list li').eq(3).find('label').should('contain', TODO_ITEM_THREE)
})

Edit a task

Let’s go ahead and test that we can edit a task. For this test, we will use the eq() method to find the item and cy.dblclick() to click inside the item. Let’s go ahead and edit Virtual Adventure and change it to Learn Cypress.

it('should allow me to edit an item', () => {
cy.get('.todo-list li').eq(1).find('label').dblclick()
// clear out the inputs current value
// and type a new value
cy.get('.todo-list li').eq(1).find('.edit').clear().type('Learn Cypress').type('{enter}')
})

Debug Tests in Cypress
Now let’s take a look at what Cypress does when there is a problem with our code. First, we will use the Cypress Command Log, and then we’ll use the developer tools within our cypress test runner. Let’s go ahead and check that the footer is available when adding a todo Open cypress and run the file.

it('Checks footer is available after adding item', () =>{
cy.get('.footer').should('be.visible');
})

The nice thing about Cypress is that you can go back and see what happened before and after the test failed. You can click on any test and see what happened. In this test case, it looks like the .footer is not visible.

Let’s go ahead and fix the problem.

it('check todo item', () => {
cy.get('.new-todo').clear()
cy.get('.new-todo').type('Vision Conference{enter}')
cy.get('.todo-list li').should('have.text', 'Vision Conference');
});
it('Checks footer is available after adding item', () =>{
cy.get('.footer').should('be.visible'); //checks for footer after item is entered
})

Now that we learned how to debug, it’s time for you to experiment on writing tests. Below is a list of tests that you can try on your own be sure to use cypress documentation https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell if you need help along the way.

Additional tests to write

Check that there are No items entered.

When an item is entered, the text input field should clear.

When all items are completed, Check the All tab says 0 items left.

When all items are completed, Check the Active tab should not have any items.

When all items are completed, Check, the Completed tab should have all the items listed.

Check that when you select an item, the item is crossed out (have.class could be helpful)

When Clear completed is entered, it clears the completed tasks.

The delete icon should remove the selected task.

--

--