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 the test
script command to cypress 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 inside cypress/integration/examples
folder.
In the Cypress window, you can click on individual test to run it.
Create a homepage.spec.js
file in cypress/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./// <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 to homepage.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('[email protected]');
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