top of page
Writer's pictureTandid Alam

End to End Testing with Cypress

Contents


- What is End to End Testing?

- What is Cypress?

- Getting Started

- Cypress Folder Structure

- Basic Testing Methods Used in Cypress

- Cypress Testing Methods

- Simple Cypress Example

- Making Use of Fixtures

- Making Use of Commands

- Learning Resources


 

What is Cypress?


Cypress is faster, better and provides definitive testing that runs on a browser.Cypress is mainly compared with Selenium, but it is completely different. Cypress does not run on top of Selenium, which means it is completely independent. Instead, Cypress runs on top of Mocha, which is a Javascript-rich test framework. It is compatible with only the Chai Assertion Library, which can access a wide range of BDD and TDD assertions.


 

Getting Started


To install Cypress, run this command in the newly created folder:

npm install cypress —save-dev

This command will install Cypress locally as a dev dependency for your project.


Create a script tag in your package.json file:

"cypress": "cypress open"

Then:


npm run cypress

This will open up a folder structure for cypress as well as a GUI where you can create tests.


The default folder structure of Cypress is shown below. You can create test cases under the folder “integration”. Clicking on the first .spec, the first test case starts executing.


 

Cypress Folder Structure


From the screenshots, you can see that Cypress has created a default folder hierarchy when it opens the first time. Below are the details for each of these folders/files created by Cypress.



Fixtures: Fixtures are external pieces of static data that your tests can use. It is recommended not to complex code data in the test case. It should be driven from an external source like CSV, HTML, or JSON.


Integration: This is the main folder to store all your tests. We add the Basic, End to End Test, Visual or Cucumber test here. All your spec files will be here.


Plugins: The Plugin folder contains the plugins or listeners. Cypress will automatically include the plugins file “cypress/plugins/index.js”.


Support: There are two files inside the support folder: commands.js and index.js

  • command.js: is the file where you add your commonly used functions and custom commands. It includes functions you may call to use in different tests, such as the login function. Cypress created some functions for you, and you can override them here if you want.

  • index.js: This file runs before every single spec file. This file is a great place to put global configuration and behavior that modifies Cypress like before or before. By default, it imports only commands.js, but you can import or require other files to keep things organized.


Node_Modules: All the node packages will be installed in the node_modules directory and available in all the test files. So, in a nutshell, this is the folder where NPM installs all the project dependencies.


Cypress.json: It is used to store different configurations. e.g., timeout, base URL, test files, or any other configurations we want to override for tweaking the behavior of Cypress. We can also manage the customized folder structure because it is part of, by default, Cypress Configurations.


Apart from the above four folders, we have some more folders like Screenshot, Download, and Video to store different related files.


 

Basic Testing Methods Used in Cypress


Cypress has adopted Mocha’s syntax for developing test cases. Below are a few main constructs that are majorly used in Cypress test development:

  • describe(): It is used to group our tests. It takes two arguments, the first is the name of the test group, and the second is a callback function.

  • it(): It is used for individual test cases. It takes two arguments, a string explaining what the test should do and a callback function that contains our actual test.

  • before(): It runs once before all tests in the block.

  • after(): It runs once after all tests in the block.

  • beforeEach(): It runs before each test in the block.

  • afterEach(): It runs after each test in the block.

  • .only(): It is used to run a specified suite or test; append “.only” against the .it() block.

  • .skip(): It is used to skip a specified suite or test; append “.skip()” against the .it() block.


 

Common Cypress Commands


Make sure to prefix commands with cy.


  • .get(): Used to filter or query matching DOM elements

  • .should(): Used for assertions. Assertions are passed in for the first parameter like 'have.id', 'have.length' whereas the second parameter is the value to pass the assertion

  • .visit(): Pass in a URL as a parameter to visit that URL

  • .type(): Takes in a string with the text that should be typed into the element

  • .click(): Clicks on the selector that was passed as the parameter

  • as(): Takes in a string to replace the selector with a new alias. You reference this alias with @.

  • .server(): Start a server to begin routing responses to cy.route() and to change the behavior of network requests. This is deprecated in version 6.0

  • .route(): Manages the behavior of network requests. This is deprecated in version 6.0


Learn more in the API documentation: Table of Contents | Cypress Documentation

 

Simple Cypress Example


 //type definition for Cypress object 'cy'
/// <reference types="cypress" />

describe("Testing the application", function() {
  it("should login with username and password", function() {

      // visit the lambdageeks page
      cy.visit('https://demo.applitools.com/')

      // Enter the username info into the #username text input field
      cy.get('#username').type('test123')

      // Enter the password into the #password text input field
      cy.get('#password').type('123')

      // Click on the login button
      cy.get('#log-in').click();

      // Check if the url includes /app after logging in
      cy.url().should('include', '/app')

  });
});


 

Making Use of Fixtures:


In your fixture folder you can store your data in order to seed test data.


You can store something like this:


[
  {
    "id": 1,
    "name": "Buy Milk",
    "isComplete": false
  },
  {
    "id": 2,
    "name": "Buy Eggs",
    "isComplete": true
  },
  {
    "id": 3,
    "name": "Buy Bread",
    "isComplete": false
  },
  {
    "id": 4,
    "name": "Make French Toast",
    "isComplete": false
  }
]

And then call it from the fixtures folder like this:


cy.route('GET', '/api/todos', 'fixture:todos')

 

Making Use of Commands:


Sometimes you'll have repetitive code that you can put into simple commands. For instance, seeding sample data and visiting a URL after clicking a test spec can lead to repetitive code. Here's how you can make a command for this:


Cypress.Commands.add('seedAndVisit', (seedData = 'fixture:todos') => {
  cy.server()
  cy.route('GET', '/api/todos', seedData)
  cy.visit('/')
})

Then you can call the seedAndVisit() command like this:

  describe('Input form', () => {
  beforeEach(() => {
    cy.seedAndVisit([])
  })
  ...
 

Learning Resources:


Comments


bottom of page