Zhihui Zhang (GK), Technical Lead

avatar

How to use Cypress

Cypress is an open source Javascript End to End Testing Framework, that makes testing anything that runs in a browser easier. Let’s build a new project in Cypress as a beginner. Make sure you have installed npm before you start with our step-by-step guide.

Install Cypress

  1. Create a folder for the project, the name is ‘cypress-test’.
  2. Enter this folder via the CMD.
  3. Run the ‘npm init’ command under this folder directory.
  4. Run the ‘npm install cypress — save-dev’ command under this folder directory (This will install Cypress locally as a dev dependency for your project).
  5. After adding a new project, Cypress will automatically scaffold out a suggested folder structure. By default it will create:

/cypress-test

    /cypress
    |    /fixtures
    |    |  example.json

    |    /integration
    |    |    /examples
    |    |        - actions.spec.js
    |    |        - aliasing.spec.js
    |    |        - assertions.spec.js
    |    |        - connectors.spec.js
    |    |        - cookies.spec.js
    |    |        - cypress_api.spec.js
    |    |        - files.spec.js
    |    |        - local_storage.spec.js
    |    |        - location.spec.js
    |    |        - misc.spec.js
    |    |        - navigation.spec.js
    |    |        - network_requests.spec.js
    |    |        - querying.spec.js
    |    |        - spies_stubs_clocks.spec.js
    |    |        - traversal.spec.js
    |    |        - utilities.spec.js
    |    |        - viewport.spec.js
    |    |        - waiting.spec.js
    |    |        - window.spec.js

    |    /plugins
    |    |        - index.js

    |    /support
    |    |        - commands.js
    |    |        - index.js

    /node_modules

    |cypress.json

    |package.json

    |package-lock.json

/fixture — Fixtures are used as external pieces of static data that can be used by your tests

/integration —  To store test scripts

/plugins —  To add the plug-in of extend cypress behavior

/support —  The support file is a great place to put reusable behavior such as Custom Commands or global overrides that you want applied and available to all of your spec files.

cypress.json — This file is used to store the projectId (after configuring your tests to record) and any configuration values you supply

While Cypress allows to configure where your tests, fixtures, and support files are located, if you’re starting your first project, we recommend you use the above structure.

https://docs.cypress.io/img/snippets/installing-cli.486453a2.mp4

Open cypress

  1. Run the 'npx cypress open' command under this folder directory
  2. After a moment, the Cypress Test Runner will launch

Try running a script

  1. Click on the Runs tab of your project within the Test Runner
  2. Then chrome browser will be launch and to run this script

Introduction to common commands

visit() — Visit a remote URL

get() — To find DOM elements

contains — Get the DOM element containing the text

find() — Get the descendent DOM elements of a specific selector

click() — Click on the elements that you already got

type() — The input text

should() — assertions

fixture() — Load a fixed set of data located in a file

Try writing a script

1. Set intelligent code completion up in Dev environment of the project

Adding a tsconfig.json inside cypress folder with the following configuration should get intelligent code completion working.

{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "../node_modules",
    "types": [
      "cypress"
    ]
  },
  "include": [
    "**/*.*"
  ]
}

Function demonstration

2. Set intelligent code completion up in Dev environment of Visual Studio Code

To set up in Visual Studio Code you can open 'Preferences / Settings / User Settings' and add the json.schemas property.

{
  "json.schemas": [
    {
      "fileMatch": [
        "cypress.json"
      ],
      "url": "https://on.cypress.io/cypress.schema.json"
    }
  ]
}

Function demonstration

3. Write a script in '/cypress-test/cypress/integration/', the name is 'search_via_baidu.js', then run

describe('first test', function(){
    it('baidu search', function(){
        const searchContent = 'Cypress test'
 
        cy.visit('http://www.baidu.com')
        cy.get('[id="kw"]').type(searchContent)
        cy.get('[type="submit"]').click()
        cy.title().should('include',searchContent )
    })
})

Parameterize constants

  1. Adding a constants.json inside cypress/fixture folder
{
    "elements":{
        "search_box":"[id='kw']",
        "search_submit":"[type='submit']"
    },
 
    "variable":{
        "search_value":"cypress test"
    }
}

2. Now let's change the script to the following code:

describe('first test', function(){
    it('baidu search', function(){
        const searchContent = 'Cypress test'
 
        cy.visit('https://www.baidu.com')
        cy.fixture('constants.json').then(constants => {
            cy.get(constants.elements.search_box).type(constants.variable.search_value)
            cy.get(constants.elements.search_submit).click()
            cy.title().should('include',constants.variable.search_value )
        })
         
    })
})

3. Save the script and run it again to see the results

Setting environment variables

  1. Add the following in cypress.json
{
  "baseUrl": "https://www.baidu.com/",
  "projectId": "b5jd3y"
}

2. Now let's change the script to the following code:

describe('first test', function(){
    it('baidu search', function(){
        const searchContent = 'Cypress test'
 
        cy.visit('')
        cy.fixture('constants.json').then(constants => {
            cy.get(constants.elements.search_box).type(constants.variable.search_value)
            cy.get(constants.elements.search_submit).click()
            cy.title().should('include',constants.variable.search_value )
        })
         
    })
})

3. Save the script and run it again to see the results

BDD syntax

Cypress has adopted Mocha’s bdd syntax, which fits perfectly with both integration and unit testing. All of the tests you’ll be writing sit on the fundamental harness Mocha provides, namely:

context() is identical to describe() and specify() is identical to it(), so choose whatever terminology works best for you.

Cypress also provides hooks (borrowed from Mocha).

These are helpful to set conditions that you want to run before a set of tests or before each test. They’re also helpful to clean up conditions after a set of tests or after each test

describe('Hooks', function() {
  before(function() {
    // runs once before all tests in the block
  })
 
  after(function() {
    // runs once after all tests in the block
  })
 
  it(function() {
    // runs once after all tests in the block
    // The script function gets the topic content
  })
 
  it.only(function() {
    // runs once after all tests in the block
    // All code under it() does not execute except for code under it()
  })
 
  it.skip(function() {
    // runs once after all tests in the block
    // The code under it skips execution
  })
 
  beforeEach(function() {
    // runs before each test in the block
  })
 
  afterEach(function() {
    // runs after each test in the block
  })
})

2. Now let's try to change the script to modify the following code:

describe('first test', function(){
 
    before('load baidu page', function() {
        cy.fixture('constants.json').as('constants')
        cy.visit('')
    })
   
    it('baidu search',function() {
        const constants = this.constants
 
        cy.get(constants.elements.search_box).type(constants.variable.search_value)
        cy.get(constants.elements.search_submit).click()
         
    })
   
    after('check title', function() {
        const variable = this.constants.variable
        cy.title().should('include',variable.search_value )
    })
  })

Create custom commands

Cypress comes with its own API for creating custom commands and overwriting existing commands. The built in Cypress commands use the very same API that’s defined below.

A great place to define or overwrite commands is in your cypress/support/commands.js file, since it is loaded before any test files are evaluated via an import statement in cypress/support/index.js.

1. Add the following code to cypress/support/command.js :

Cypress.Commands.add("baiduSearch", (searchValue) => {
    cy.fixture('constants.json').then(constants => {
        cy.get(constants.elements.search_box).type(searchValue)
        cy.get(constants.elements.search_submit).click()
    })
})

2. Now let's try to change the script to modify the following code:

describe('first test', function(){
 
    before('load baidu page', function() {
        cy.fixture('constants.json').as('constants')
        cy.visit('')
    })
   
    it('baidu search',function() {
        const constants = this.constants
        cy.baiduSearch(constants.variable.search_value)
    })
   
    after('check title', function() {
        const variable = this.constants.variable
        cy.title().should('include',variable.search_value )
    })
  })

Run the script from the command line

cypress run --- Run all scripts

cypress run --spec 'cypress/integration/search_via_baidu.js' --- 'Run tests specifying a single test file to run instead of all tests'

cypress run --spec 'cypress/integration/examples/*' --- Run tests specifying a glob of where to look for test files (Note: quotes required)

cypress run --spec 'cypress/integration/examples/actions.spec.js,cypress/integration/examples/files.spec.js' --- Run tests specifying multiple test files to run