Step-by-step instructions on how to start end-to-end testing using Cypress.
Basic knowledge of command line, e.g. cd
, mkdir
.
Install NodeJS
-
Create a new folder and name it as you wish, e.g.
testing-project
.mkdir testing-project
-
Go into that folder.
cd testing-project
-
Create a
package.json
file.npm init -y
-
Install Cypress.
npm install cypress
-
In
package.json
file, change thetest
script command tocypress open
.{ "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "cypress open" } }
-
In your command line, run the following command:
npm run test
A Cypress windows will open with list of example tests. If you observe your project folder, you will find that a
cypress
folder is created. The example tests are insidecypress/integration/examples
folder.In the Cypress window, you can click on individual test to run it.
-
Create a
homepage.spec.js
file incypress/integration
folder with the following content:/// <reference types="cypress" /> describe('homepage', () => { it('can show', () => { cy.visit('https://shopit.space/'); cy.contains('The best shopping site in the web that would saves you most money.').should('be.visible'); }) })
cy.visit
will visit the URL that you passed to itcy.contains
will get the element with the specified text.should
assert the element fulfill some requirements. Now we assert the elements that contains the previous text is visible.- The triple slash (
/// <reference types="cypress" />
) comment is a special comment used by your editor to load type definition for Cypress so you get code autocomplete as you type. It's optional.
-
Update the auto-generated
cypress.json
file with the following content:{ "baseUrl": "https://shopit.space" }
-
Now update
homepage.spec.js
:describe('homepage', () => { it('can show', () => { - cy.visit('https://shopit.space/'); + cy.visit('/'); cy.contains('The best shopping site in the web that would saves you most money.').should('be.visible'); }) })
As such the base URL no longer hard-coded in the test. If our URL changes in future, we no longer need to update it in all the tests but only via
cypress.json
. -
Let's write another test in
homepage.spec.js
:describe('homepage', () => { it('can show', () => { ... }) it('can go to help page', () => { cy.visit('/'); cy.contains('Help').click(); cy.contains('Hi, how can we help?').should('be.visible'); }) })
-
Install Cypress Testing Library and Faker.js
npm install @testing-library/cypress faker
-
Include Cypress Testing Library commands by importing it in
cypress/support/commands.js
import '@testing-library/cypress/add-commands';
Now additional selectors are added to Cypress's
cy
object:cy.findByText
cy.findByLabelText
cy.findByPlaceholderText
cy.findByAltText
cy.findByTitle
cy.findByDisplayValue
cy.findByTestId
The detailed explanations for each selectors are explained in Testing Library's docs.
-
Change our tests in
homepage.spec.js
to use selectors from Cypress Testing Library:describe('homepage', () => { it('can show', () => { cy.visit('/'); - cy.contains('The best shopping site in the web that would saves you most money.').should('be.visible'); + cy.findByText('The best shopping site in the web that would saves you most money.').should('be.visible'); }) it('can go to help page', () => { cy.visit('/'); - cy.contains('Help').click(); + cy.findAllByText('Help').first().click(); - cy.contains('Hi, how can we help?').should('be.visible'); + cy.findByText('Hi, how can we help?').should('be.visible'); }) })
-
Add another test file
product.spec.js
next tohomepage.spec.js
:/// <reference types="cypress" /> import faker from 'faker'; describe('product', () => { it('can add comment', () => { cy.visit('/'); cy.findAllByTestId('productBox') .first() .click(); cy.findByLabelText('Your Name') .type(faker.name.findName()); const review = faker.lorem.sentence(2); cy.findByLabelText('Your Review') .type(review); cy.findByText('Add').click(); cy.findByLabelText('Your Review').should('be.enabled'); cy.findByText(review).should('be.visible'); }) })
-
Add another npm script in
package.json
:{ ... "scripts": { "test": "cypress open", + "test:staging": "cypress open --config baseUrl=https://react-ecomm-site.now.sh" } ... }
-
Run the tests against the new URL:
npm run test:staging
-
In
cypress/support/commands.js
file, add the following code:... Cypress.Commands.add('login', () => { cy.visit('/login'); cy.findByLabelText('Email').type('test@shopit.com'); cy.findByLabelText('Password').type('12345678'); cy.findAllByText('Login').filter('button').click(); cy.findByText("You're already login!", { timeout: 5000 }) })
-
Let's add another test in
product.spec.js
:describe('product', () => { ... it('can add comment with authenticated user', () => { cy.login(); cy.visit('/'); cy.findAllByTestId('productBox') .first() .click(); cy.findByLabelText('Your Name').should('have.value', 'Test User'); }) })
Running tests in headless mode allows us to run the tests as part of CI/CD pipeline.
-
Add another npm script in
package.json
:{ ... "scripts": { "test": "cypress open", "test:staging": "cypress open --config baseUrl=https://react-ecomm-site.now.sh", + "test:ci": "cypress run --config video=false" } ... }
-
Run the tests in headless mode:
npm run test:ci