Introduction to Cypress and UI Test Automation
Published: 2023-05-08 13:09:18

## Introduction to Test Automation

Let's consider an example of an e-commerce software development company that is facing challenges in meeting deadlines due to the increasing demand for its services. They have a large codebase and manual testing processes that make it difficult to catch bugs and ensure quality. The team also faces technical challenges, such as the need to test across multiple browsers and devices, as well as performance issues resulting in slow page load times.

To overcome all these challenges, test automation can be used to automate functional, regression, and load testing. This will enable them to catch bugs earlier in the development cycle and reduce the need for manual testing.

There are many automation tools available in the market right now including popular tools like Selenium, UFT, Appium, WebDriverIO, and Cypress.

Implementing test automation will allow the e-commerce company to accelerate testing and reduce bugs, delivering high-quality software faster, and improving customer experience. By automating the testing process, the team can overcome technical difficulties and focus on developing new features and services to meet growing customer demand.

In this blog post, we’ll explore one of the automation testing tools: Cypress. We will discuss how different Cypress is from other tools and its advantages over other test automation tools.

## What is Cypress?

[Cypress](https://www.cypress.io/) is a next-generation front-end Automation testing tool built for modern web applications. It is a JavaScript-based end-to-end testing framework and is known for faster test execution as compared with other testing tools (like [Selenium](https://github.com/SeleniumHQ/selenium) or [Protractor](https://github.com/angular/protractor)).

Cypress is a powerful testing framework that has gained popularity among developers because of its unique architecture. Here are some reasons why Cypress is preferred over other testing frameworks:

- **Fast**: Cypress is known for its fast test execution speed. Unlike other testing frameworks that rely on Selenium WebDriver to interact with the browser, Cypress runs tests directly in the browser. This makes Cypress faster and more efficient in executing tests.
- **Easy to install and set up**: Cypress is easy to install and set up with a simple command-line interface that allows developers to get started quickly.
- **Real-time reloading**: Cypress automatically reloads the test runner and updates the test results in real-time as developers write and modify tests. This allows developers to quickly test changes and see the results without having to manually reload the browser.
- **Powerful debugging tools**: Cypress comes with a powerful debugger that allows developers to step through their test code and quickly identify and fix issues.
- **Automatic waiting and retries**: Cypress automatically waits for elements to become available before interacting with them, and it retries failed commands automatically, making tests more reliable and reducing the risk of flaky tests.
- **Time travel**: Cypress allows developers to go back in time and see what happened at any point during the test, which can be helpful for debugging complex issues.
- **Built-in assertions and APIs**: Cypress provides built-in assertions and APIs that make it easy to write and maintain tests.

Overall, Cypress offers a unique architecture and several advantages over other testing frameworks, making it a powerful tool for developers to create and maintain high-quality web applications. By providing a fast and reliable testing framework with powerful debugging tools and built-in APIs, Cypress enables developers to test their applications more efficiently and effectively, leading to development of higher-quality applications with fewer defects.

### Cypress Architecture

Most testing tools (such as Selenium) operate by running outside of the browser and communicating with it through remote commands sent across the network. However, the Cypress engine is unique in that it runs directly inside the browser.

Cypress' architecture is mainly divided into three main components: Test Runner, Cypress Server, and Browser.

- **Test Runner**: The Test Runner is a GUI that allows you to interact with your tests and view the results. It also provides debugging and snapshotting capabilities. The Cypress Test Runner can execute tests in parallel across multiple browser instances, which can significantly speed up your test suite.
- **Cypress Server**: The Cypress Server is a node.js process that runs in the background and manages the interaction between the Test Runner and the Browser. Cypress uses a unique architecture called "Dual Server" architecture, where the Test Runner and the Cypress Server run in separate processes. This allows Cypress to manage the browser and execute tests more efficiently.
- **Browser**: The Browser is the actual browser instance that runs your application and executes your tests. Cypress communicates with the Browser using a custom protocol called "Cypress Protocol." This protocol allows Cypress to control the browser and access its internals, such as the DOM and network requests.

Besides these three components, Cypress also provides a variety of plugins that extends its functionality, including integration with other tools such as CI/CD platforms and code coverage tools.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9uiucv32a2gie90vllm.png)

<p align="center"><a href="https://www.programsbuzz.com/article/cypress-architecture">Adapted from ProgramsBuzz</a> </p>

The workflow for using Cypress is as follows: First, the NodeJS server launches a browser with a proxy. The browser is set up with two iframes: one for Cypress and one for the application being tested. Since Cypress is in an iframe with the domain localhost, which is different from the application's domain, a script can be injected into the application's iframe to change its domain to localhost. This enables the two iframes to communicate with each other, allowing Cypress to access all the objects of the application, including the DOM, Window, and LocalStorage. Cypress and Node Js also need to communicate with each other to request OS privileges, such as taking screenshots or recording videos. Finally, since the browser starts with a proxy, NodeJS can control the network layer, capturing and modifying requests as needed.

**How is Cypress different from other test automation frameworks?**

Cypress is different from other test automation frameworks due to the following reasons:

1. Cypress can automatically wait for commands and assertions before moving on. So no more async hell.
2. Cypress provides the testing ability to test Edge Cases by simulating the server response.
3. Cypress runner will take snapshots as and when our tests run. Users can view a detailed breakdown of each step by hovering over each command in the Command Log of Cypress.
4. Cypress offers fast, consistent, and reliable test execution compared to other automation tools due to its architectural design.
5. Since cypress is built on Node.js, it is available as an npm module, and it also uses JavaScript for writing tests. Cypress's inbuilt commands are easy to understand and can be used for 90% of the coding required for the tests.
6. Cypress also bundles with jQuery and inherits many jQuery methods for UI components Identification.

**Cypress Browser Support**

**Cypress supports all the major browsers including Chrome, Edge, and Firefox. You can find the complete [list of supported browsers by Cypress here](https://docs.cypress.io/guides/guides/launching-browsers#Browser-versions-supported).**

## Test Automation Using Cypress

To show how Cypress can be used for automation testing, we will be using the [TodoMVC website](https://todomvc.com/examples/react/#/). It is a popular test application that is commonly used to demonstrate front-end testing frameworks such as Cypress.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zx9varkjh08fv0j7plkh.png)

The TodoMVC website is a simple to-do list application built with various JavaScript frameworks. It allows you to add and remove todos, mark them as completed, and filter them by status. You can use Cypress to write tests to verify the functionality of the application, such as adding a todo, marking it as completed, and verifying that it appears in the completed list.

### Install Cypress

**Pre-requisites**:
Before installing Cypress, you need to have Node.js installed on your system, which can be downloaded and installed from the [official Node.js website](https://nodejs.org/en/download). It is also suggested to have an IDE like [Visual Studio Code](https://code.visualstudio.com/Download) to make coding with Cypress easier.

To get started with Cypress, you need to install it as a dev dependency in your project. You can do this by running the following command in your terminal:

```sh
npm install --save-dev cypress
``` 

This will download Cypress and add it to your package.json file. You can also use yarn or any other package manager of your choice. Next, you need to open the Cypress Test Runner by running the following command in your terminal:

```sh
npx cypress open
``` 

This will launch a graphical user interface that lets you run and manage your tests. You can also use `npx cypress run` to run your tests headlessly in the terminal.

### Developing Test Cases

We will write two tests for TodoMVC using Cypress: 

1. Test to validate the creation of new to-do items.
2. Test to validate completion of a to-do item.

We will use the `describe` function to group our tests under a common name, and the `it` function to define each test case. We will also use the `beforeEach` function to visit the TodoMVC website before each test. 

Here is how our test file looks like:

```sh
describe('example to-do app', () => {
  const todo1 = 'Feed the dog'
  const todo2 = 'Take pills'
  const todo3 = 'Pay electric bill'

  beforeEach(() => {
    // Visit the to-do app URL before each test
    cy.visit('https://todomvc.com/examples/react/#/')
  })

  it('can add new todo items', () => {
    // Type new to-do items and check if they are added to the list
    cy.get('.new-todo').type(`${todo1}{enter}`)
    cy.get('.new-todo').type(`${todo2}{enter}`)
    cy.get('.new-todo').type(`${todo3}{enter}`)
    cy.get('.view label')
      .should('have.length', 3)
      .eq(0).should('have.text', todo1)
  })

  it('can check off an item as completed', () => {
    // Add new to-do items, check one off as completed and verify it is marked as such
    cy.get('.new-todo').type(`${todo1}{enter}`)
    cy.get('.new-todo').type(`${todo2}{enter}`)
    cy.get('.new-todo').type(`${todo3}{enter}`)
    cy.contains('Pay electric bill')
      .parent()
      .find('input[type=checkbox]')
      .check()
    cy.contains('Pay electric bill')
      .parents('li')
      .should('have.class', 'completed')
  })
}
```

**Explanation to the code:**

The code contains two tests, each of which verifies different functionalities of the app.

The first test verifies that new to-do items can be added to the list by typing them in the input field and pressing enter. It then asserts, using `should()`, that the items are displayed in the list. The assertion includes checking the number of items with the class `view label` and ensuring that the first item in the list has the text ‘Feed the dog’.

The second test adds new to-do items to the list and then verifies that a specific item can be marked as completed by checking the checkbox next to it. It uses the `cy.contains()` command to find the element using the text `Pay electric bill`, and then traverses to the checkbox that is its parent to check it. It then asserts, using `should()`, that the item has the class `completed`, which indicates that it has been marked as completed.

Before each test, the app URL is visited using `cy.visit()` to ensure a clean slate.

### Executing Test Cases

To run our tests for TodoMVC, we need to open the Cypress Test Runner by running 
`npx cypress open` in our terminal. This will show us a list of spec files that we can choose from. We need to select our test file (e.g., `todo_spec.js`) and click on it. This will launch a browser window where we can see our tests running step by step.

We can also see the results of our tests in the Test Runner UI. We can see which tests passed or failed, how long they took, and what assertions were made. We can also inspect each command and see what happened on each step.

**Test 1 run log:**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ae326rlhhggoutu8lw9w.png)

**Test 2 run log:**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ui8r0yng0sk67w4xtxg.png)

The Cypress dashboard also provides detailed insights into the test results, including test run history, video recordings of the test execution, and screenshots captured during the test run. The comprehensive test report allows developers and testers to identify any issues and troubleshoot them quickly, ensuring that the application is thoroughly tested and meets the required quality standards.

### How to Integrate Cypress Test Automation into a CI/CD Pipeline?

Continuous Integration/Continuous Deployment (CI/CD) is a software development approach that involves regularly integrating code changes into a central repository and automatically building, testing, and deploying the updated application. This process helps catch errors early and ensures that the code is always in a deployable state.

There are many [CI/CD tools and platforms](https://www.infracloud.io/build-devops-toolchain/) available, and the most popular one may vary depending on the specific needs of a project or organization. However, some of the most widely used CI/CD tools and platforms are:
- [Jenkins](https://www.jenkins.io/doc/)
- [GitLab CI/CD](https://docs.gitlab.com/ee/ci/)
- [Bamboo](https://confluence.atlassian.com/bamboo/)
- [GitHub Actions](https://docs.github.com/en/actions)

Cypress test automation can be placed in the testing stage of the CI/CD pipeline. This involves running automated tests to check the functionality and performance of the application. By including Cypress tests in the CI/CD pipeline, developers can quickly identify and fix any issues that arise, ensuring a higher level of quality in the final product.

Here's a high-level overview of how Cypress test automation can be integrated into a CI/CD pipeline:

1. Code is pushed to a central repository, triggering a build process.
2. The build process compiles the code and runs unit tests to ensure that the code is working as expected.
3. Once the code passes the unit tests, it is deployed to a staging environment.
4. In the staging environment, automated end-to-end tests are run using Cypress to ensure that the application is functioning correctly and that new changes have not introduced any new issues.
5. If the end-to-end tests pass, the application is deployed to production.

Refer to Cypress’s [official documentation on CI/CD](https://docs.cypress.io/guides/continuous-integration/introduction) on how to integrate Cypress in your CI/CD pipeline.

## Summary

Cypress’s official documentation is extremely good and important. It always comes in handy whenever we need some info. We’ve focused on the important points in this blog that are needed to get a basic idea of what Cypress is, its architecture, how it is different from the existing traditional automation tools like Selenium, and finally the supported browsers and their versions. With this basic info, we can comfortably get started with Cypress automation.

If you're looking to streamline your DevOps processes and optimize your testing efforts with Cypress automation, InfraCloud can help. Our specialized [DevOps consulting services](https://www.infracloud.io/devops-consulting-services/) can help you implement Cypress automation and achieve faster, more reliable test results.

## References & further reading

- [Cypress official website](https://www.cypress.io/)
- [Cypress documentation](https://docs.cypress.io/)
- [Cypress architecture overview](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Cypress-Architecture)
- [Cypress GitHub repository](https://github.com/cypress-io/cypress)
- [Cypress official documentation on Continuous Integration and Continuous Delivery](https://docs.cypress.io/guides/continuous-integration/introduction)
- [Need help with CI/CD? Explore our CI/CD Consulting services](https://www.infracloud.io/ci-cd-consulting/)