PoshJosh's Blog

Hacking Cypress in 9 minutes

June 15, 2021

Cypress - Hacking it in 9 minutes

Install Cypress

npm install -D cypress

The above command installs Desktop App and CLI

To open the Desktop App

npx cypress open 

The above works because the Desktop App is a binary in your node_modules

My Project
    Cypress
	fixtures
	integration (will contain your test files)
	plugins
	support

In the Cypress GUI, click on any test.spec.js file to run it

Example Basic Test Spec

cy.get('button').click().should('have.class', 'active')

The above command will automatically wait (default = 4secs)

cy.request('/users/1').its('body').should('deep.eql', {name:'Amir'})
it('login user', () => {
    cy.visit('http://localhost:8080/signup')

    cy.get('input[name=“email”]').type('amir@cypress.io')
    cy.get('input[name=“password”]').type('123456')
    cy.get('#login-button').click()

    // After login the user should direct to /home
    cy.location('pathname').should('eq', '/home')

})

Custom commands

Declare custom commands in the commands file in the support directory cypress/support/commands.js

// cypress/support/commands.js

Cypress.Commands.add('login', (email, password) => {
    cy.get('input[name=“email”]').type(email)
    cy.get('input[name=“password”]').type(password)
    cy.get('#login-button').click()
})

After defining the custom command above, use it this way

cy.login('amir@cypress.io', '123456')

Tasks

Custom tasks could be defined e.g to clear seed and/clear test data

// cypress/plugins/index.js

const { seedDatabase, clearDatabase } = require('../../server/db')

module.exports = (on, config) => {
  on('task', {
    'seed:db', (data) => seedDatabase() // can accept arguments
  })

  on('task', {
    'clear:db', () => clearDatabase()
  })
}

Use the declared task

const userSeed = require('../../server/seed/users')

context('User setup', () => {
    beforeEach(() => {
        cy.task('clear:db')
        cy.task('seed:db', userSeed.data)
    })

    it('login user', () => {
        cy.visit('http://localhost:8080/login')
        cy.login('amir@cypress.io', '123456')
        cy.location('pathname').should('eq', '/board')
    })
})

More on custom commands

We could add a programmatic implementation of our earlier login command to make the login process even more efficient.

// cypress/support/commands.js

// We rename the earlier login command to 'loginWithUI'
Cypress.Commands.add('loginWithUI', (email, password) => {
    cy.get('input[name=“email”]').type(email)
    cy.get('input[name=“password”]').type(password)
    cy.get('#login-button').click()
})

// login programmatically
Cypress.Commands.add('login', (email, password) => {
    return cy.window().then(win => {
        return win.app.$store.dispatch('login', {
            email: 'amir@cypress.io',    
            password: '123456',    
        }) 
    }) 
})

Notes:

  • Cypress has programmatic access to our app
  • We can directly call the function that does the login within our application
  • We achieve this by attaching an instance of our app to the global window of the browser
  • We then use window command of Cypress to access the global app instance.
  • The central state management of the application (in this case Vuex) is used to dispatch the login functionality directly i.e $store.dispatch

Stubbing network response with fixtures

Define fixture e.g in cypress/fixtures/tweets.json

const userSeed = require('../../server/seed/users')

context('Tweet Loading', () => {
    beforeEach(() => {
        cy.task('clear:db')
        cy.task('seed:db', userSeed.data)
        cy.visit('http://localhost:8080/login')
        cy.login('amir@cypress.io', '123456')
    })

    // stub network response with a fixture
    it('load tweets for selected hashtags', () => {
        cy.server() // stub a server
  
        // Define what happens when a call is made to GET /tweets
        cy.route('GET', '/tweets*', 'fixture:tweets') 
            .as('tweets') // label the route to be able to refer to it elsewhere

        // drive the input box        
        cy.get('#hashtags').type('javascript{enter}').type('cypressio{enter}')

       // wait for the response to return
        cy.window().then(win => {
            cy.wait('@tweets') // Refer to the labelled route
                .its('response.body.tweets')
                .should('have.length', win.app.$store.state.tweets.length)
        })
    })
})

Simulate slow response/error scenarios

const userSeed = require('../../server/seed/users')

context('Tweet Loading', () => {
    beforeEach(() => {
        cy.task('clear:db')
        cy.task('seed:db', userSeed.data)
        cy.visit('http://localhost:8080/login')
        cy.login('amir@cypress.io', '123456')
    })

    // stub network response with a fixture
    it('load tweets for selected hashtags', () => {
        cy.server() // stub a server
  
        cy.fixture('tweets').then(tweets => {
            cy.route({
                url: '/tweets*',
                response: '/tweets*',
                delay: 3000, // simulate slow response
                status: 404,   // simulate error scenarios
            })
        }).as('tweets')
    })
})

In the earlier example we used a fixture via the route command with a string pattern fixture:tweets

In this example we are using the cypress cy.fixture command

Headless mode

Outside of Cypress Desktop App, for example from within a CI pipeline

npx cypress run

In headless mode, we get automatic video recordings of our tests

In a nutshell, use:

npx cypress open - for UI mode i.e desktop app npx cupress run - for headless mode

Cypress dashboard

To record results to the cypress dashboard, use the --record option.

npx cypress run --record

Optimize CI Usage with parallelization

Cypress will optimally figure out how to load balance your test files across your ci machines

npx cypress run --record --parallel

Learn more

Reference


Written byChinomso IkwuagwuExcélsior

Limited conversations with distributed systems.

Modifying legacy applications using domain driven design (DDD)

Gherkin Best Practices

Code Review Best Practices

Hacking Cypress in 9 minutes

Some common mistakes when developing java web applications

How to make a Spring Boot application production ready

SQL JOINS - A Refresher

Add Elasticsearch to Spring Boot Application

Add entities/tables to an existing Jhipster based project

CSS 3 Media Queries - All over again

Maven Dependency Convergence - quick reference

Amazon SNS Quick Reference

AWS API Gateway Quick Reference

Amazon SQS Quick Reference

AWS API Gateway Quick Reference

AWS Lambda Quick Reference

Amazon DynamoDB - Quick Reference

Amazon Aurora

Amazon Relational Database Service

AWS Database Services

AWS Security Essentials

Amazon Virtual Private Cloud Connectivity Options

Summary of AWS Services

AWS Certified Solutions Architect - Quick Reference

AWS CloudFront FAQs - Curated

AWS VPC FAQs - Curated

AWS EC2 FAQs - Curated

AWS Achritect 5 - Architecting for Cost Optimization

AWS Achritect 4 - Architecting for Performance Efficiency

AWS Achritect - 6 - Passing the Certification Exam

AWS Achitect 3 - Architecting for Operational Excellence

AWS Achitect 2 - Architecting for Security

AWS Achitect 1 - Architecting for Reliability

Amazon DynamoDB Accelerator (DAX)

Questions and Answers - AWS Certified Cloud Architect Associate

Questions and Answers - AWS Certified Cloud Architect Associate

AWS Connectivity - PrivateLink, VPC-Peering, Transit-gateway and Direct-connect

AWS - VPC peering vs PrivateLink

Designing Low Latency Systems

AWS EFS vs FSx

AWS Regions, Availability Zones and Local Zones

AWS VPC Endpoints and VPC Endpoint Services (AWS Private Link)

AWS - IP Addresses

AWS Elastic Network Interfaces

AWS Titbits

Jenkins on AWS - Automation

Jenkins on AWS - Setup

Jenkins on AWS - Best practices

Introduction to CIDR Blocks

AWS Lamda - Limitations and Use Cases

AWS Certified Solutions Architect Associate - Part 10 - Services and design scenarios

AWS Certified Solutions Architect Associate - Part 9 - Databases

AWS Certified Solutions Architect Associate - Part - 8 Application deployment

AWS Certified Solutions Architect Associate - Part 7 - Autoscaling and virtual network services

AWS Certified Solutions Architect Associate - Part 6 - Identity and access management

AWS Certified Solutions Architect Associate - Part 5 - Compute services design

AWS Certified Solutions Architect Associate - Part 4 - Virtual Private Cloud

AWS Certified Solutions Architect Associate - Part 3 - Storage services

AWS Certified Solutions Architect Associate - Part 2 - Introduction to Security

AWS Certified Solutions Architect Associate - Part 1 - Key services relating to the Exam

AWS Certifications - Part 1 - Certified solutions architect associate

AWS Virtual Private Cloud (VPC) Examples

Curated info on AWS Virtual Private Cloud (VPC)

Notes on Amazon Web Services 8 - Command Line Interface (CLI)

Notes on Amazon Web Services 7 - Elastic Beanstalk

Notes on Amazon Web Services 6 - Developer, Media, Migration, Productivity, IoT and Gaming

Notes on Amazon Web Services 5 - Security, Identity and Compliance

Notes on Amazon Web Services 4 - Analytics and Machine Learning

Notes on Amazon Web Services 3 - Managment Tools, App Integration and Customer Engagement

Notes on Amazon Web Services 2 - Storages databases compute and content delivery

Notes on Amazon Web Services 1 - Introduction

AWS Auto Scaling - All you need to know

AWS Load Balancers - How they work and differences between them

AWS EC2 Instance Types - Curated

Amazon Web Services - Identity and Access Management Primer

Amazon Web Services - Create IAM User

Preparing Jenkins after Installation

Jenkins titbits, and then some

Docker Titbits

How to Add Chat Functionality to a Maven Java Web App

Packer - an introduction

Terraform - an introduction

Versioning REST Resources with Spring Data REST

Installing and running Jenkins in Docker

Automate deployment of Jenkins to AWS - Part 2 - Full automation - Single EC2 instance

Automate deployment of Jenkins to AWS - Part 1 - Semi automation - Single EC2 instance

Introduction to Jenkins

Software Engineers Reference - Dictionary, Encyclopedia or Wiki - For Software Engineers