---
title: "Testing web applications using Cypress"
canonical: "https://docs.getxray.app/space/XRAY/301508241/Testing%20web%20applications%20using%20Cypress"
format: markdown
---
> ℹ️ **What you'll learn**
> ℹ️ 
> ℹ️ - Define tests using Cypress
> ℹ️ - Run the test and push the test report to Xray
> ℹ️ - Validate in Jira that the test results are available

> ⚠️ **Source-code for this tutorial**
> ⚠️ 
> ⚠️ - code is available in [GitHub](https://github.com/Xray-App/tutorial-js-cypress)

# Overview

Cypress is a JavaScript based testing framework for test automation. Cypress is often compared to Selenium, but it is different; unlike Selenium that is executed outside of the browser Cypress is executed within it, in the same run loop as your application.

Cypress runs in a NodeJS server process that allows Cypress and the NodeJS server to constantly communicate, synchronize, and perform tasks on behalf of each other. This provides Cypress the ability to respond to the application's events in real time, and at the same time work outside of the browser for tasks that require a higher privilege.

# Prerequisites


<details>
<summary>Expand</summary>

For this example we will use [Cypress](https://www.cypress.io/) to write tests that aim to validate the[ ](https://github.com/microsoft/playwright-test/blob/master/README.md)[Cypress todo example](https://example.cypress.io/todo).

 We will need:

- Access to a [Cypress todo example](https://example.cypress.io/todo) site that we aim to test
- [Cypress ](https://www.cypress.io/)installed in your machine
</details>


To start using the [Cypress](https://www.cypress.io/) please follow the [Get Started](https://docs.cypress.io/guides/getting-started/installing-cypress) documentation.

The tests consists in validating the operations over todo's elements of the [Cypress todo example](https://example.cypress.io/todo), for that we have defined several tests to:

- Validate that we can add new todo items;
- Validate that we can check an item as completed;
- Validate that we can filter for completed/uncompleted tasks;
- Validate that we can delete all completed tasks.


The target web application is a simple "todos" made available by Cypress.

![image](media://f19c25b9-e90e-45b7-99a7-92b9f6e72ca8)


Each of these tests will have a series of actions and validations to check that the desired behavior is happening as we can see below:

<details>
<summary>todo.cy.js</summary>

```javascript
describe('example to-do app', () => {
  beforeEach(() => {
    cy.visit(Cypress.config('baseUrl'))
  })

  it('can add new todo items', () => {
    const newItem = 'Feed the cat'
    cy.get('[data-test=new-todo]').type(`${newItem}{enter}`)

    cy.get('.todo-list li')
      .should('have.length', 3)
      .last()
      .should('have.text', newItem)
  })

  it('can check an item as completed', () => {
    cy.contains('Pay electric bill')
      .parent()
      .find('input[type=checkbox]')
      .check()

    cy.contains('Pay electric bill')
      .parents('li')
      .should('have.class', 'completed')
  })

  context('with a checked task', () => {
    beforeEach(() => {
      cy.contains('Pay electric bill')
        .parent()
        .find('input[type=checkbox]')
        .check()
    })

    it('can filter for uncompleted tasks', () => {
      cy.contains('Active').click()

      cy.get('.todo-list li')
        .should('have.length', 1)
        .first()
        .should('have.text', 'Walk the dog')

      cy.contains('Pay electric bill').should('not.exist')
    })

    it('can filter for completed tasks', () => {
      cy.contains('Completed').click()

      cy.get('.todo-list li')
        .should('have.length', 1)
        .first()
        .should('have.text', 'Pay electric bill')

      cy.contains('Walk the dog').should('not.exist')
    })

    it('can delete all completed tasks', () => {
      cy.contains('Clear completed').click()

      cy.get('.todo-list li')
        .should('have.length', 1)
        .should('not.have.text', 'Pay electric bill')

      cy.contains('Clear completed').should('not.exist')
    })
  })
})
```
</details>


The tests are simple but let's look into two diferences that allow a little more control, the first one is the possibility to use hooks like `beforeEach` to, as the name implies, execute some operations before each test execution. In this example we are accessing the target page before each test avoiding repeating this instruction in each test.

<details>
<summary>beforeEach</summary>

```javascript
...
beforeEach(() => {
  cy.visit('https://example.cypress.io/todo')
})
...
```
</details>


The other one helps in the test organization and have a direct effect on how the results will be written in the result file, in our case we are using `context` (but we could use `describe` or `specify`). This will group the tests beneath into the same testsuite. 

<details>
<summary>context</summary>

```javascript
...
  context('with a checked task', () => {
...
```
</details>


These tests are defined to validate the application ability to manage todo's by accessing the [Cypress todo example](https://example.cypress.io/todo) and performing operations that will generate an expected output.

Once the code is implemented it can be executed with the following command:

```shell
npx cypress run
```


The results are immediately available in the terminal.

![image](media://2449b7a2-2b94-49e8-9ae0-7ebd62cdbb9c)


 In this example, all tests have succeed, as seen in the previous terminal screenshot. It generates the following JUnit XML report.

<details>
<summary>Junit Report</summary>

```
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="Mocha Tests" time="4.404" tests="6" failures="0">
  <testsuite name="Root Suite" timestamp="2023-01-30T17:46:57" tests="0" file="cypress/e2e/todo.cy.js" time="0.000" failures="0">
  </testsuite>
  <testsuite name="example to-do app" timestamp="2023-01-30T17:46:57" tests="3" time="0.000" failures="0">
    <testcase name="example to-do app displays two todo items by default" time="0.842" classname="displays two todo items by default">
    </testcase>
    <testcase name="example to-do app can add new todo items" time="0.477" classname="can add new todo items">
    </testcase>
    <testcase name="example to-do app can check off an item as completed" time="0.267" classname="can check off an item as completed">
    </testcase>
  </testsuite>
  <testsuite name="with a checked task" timestamp="2023-01-30T17:47:00" tests="3" time="1.060" failures="0">
    <testcase name="example to-do app with a checked task can filter for uncompleted tasks" time="0.345" classname="can filter for uncompleted tasks">
    </testcase>
    <testcase name="example to-do app with a checked task can filter for completed tasks" time="0.350" classname="can filter for completed tasks">
    </testcase>
    <testcase name="example to-do app with a checked task can delete all completed tasks" time="0.341" classname="can delete all completed tasks">
    </testcase>
  </testsuite>
</testsuites>
```
</details>


Notes:

- You can invoke Cypress locally and use it to assist you to write and execute tests with: `npx cypress open`
- Use `cypress.config.js` to define configuration values such as taking screenshots, recordings or the reporter to use (more info [here](https://docs.cypress.io/guides/references/configuration)).
- Different parameters can be used in the command line (more info [here](https://docs.cypress.io/guides/guides/command-line))
- We are using JUnit reporter but others are available (more info [here](https://docs.cypress.io/guides/tooling/reporters))


---

# Integrating with Xray

<span style="color: #172B4D">As we saw in the previous example, where we are producing JUnit reports with the test results. It is now a matter of importing those results to your Jira instance; this can be done by simply submitting automation results to Xray through the REST API, by using one of the available CI/CD plugins (e.g. for Jenkins), or using the Jira interface to do so.</span>


> Macro (ui-tabs)
> 
> > Macro (legacy-content)
> 
> > Macro (legacy-content)


# Tips

- <span style="color: #000000">after results are imported, in Jira Tests can be linked to existing requirements/user stories, so you can track the impacts on their coverage.</span>
- <span style="color: #000000">results from multiple builds can be linked to an existing Test Plan, to facilitate the analysis of test result trends across builds.</span>
- <span style="color: #000000">results can be associated with a Test Environment, in case you want to analyze coverage and test results by that environment later on. A Test Environment can be a testing stage (e.g. dev, staging, preprod, prod) or a identifier of the device/application used to interact with the system (e.g. browser, mobile OS).</span>



---

# References

- [https://www.cypress.io/](https://www.cypress.io/)
- [https://docs.cypress.io/guides/overview/why-cypress](https://docs.cypress.io/guides/overview/why-cypress)

> Macro (toc)

> Macro (style)