API Testing with Cypress: Part 3 - CI pipeline on Github Actions
Tags: cypress, ci, pipeline
Published: 2022-05-23 06:50:24

## Hello guys!

It's been a while since I posted parts 1 and 2 of this article, and I was owing part 3.

This time our goal will be to put the tests to run in a **Continuous Integration** pipeline, after all, we want it to be an automated test. So let's dive into that.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/KmlTchPoFQT84/giphy.gif">

### Access your GitHub repository

The first step, if you haven't read parts 1 and 2 yet, hurry up, it's super easy and that way we'll make sure we're on the same page.

In part 1, I showed you how you can create your repository on GitHub and some of the most basic Git commands to upload your local data to the repository created in your account. 

Assuming you already have this repository created under your account, access it. In my case, the link is: 

https://github.com/murillowelsi/cypress-api-tutorial

Make sure your local repository is synced with the remote repository.

### Creating your first workflow

Create a `.github/workflows` directory in your repository on GitHub if it does not already exist.

In the .github/workflows directory, create a file named `ci.yml`. You can do this manually or simply by executing the following command:

```shell
mkdir -p .github/workflows && touch .github/workflows/ci.yml
```

Now you should be able to see this directory structure in your VsCode:

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

### Editing and understanding the YML file

Each step of our pipeline will be added inside the configuration file, and when the `ci.yml` file is pushed to the remote repository, GitHub will automatically identify that there is a workflow to be executed and the tests will be run.

This is going to be a bit boring, I know, but let's increase the yml little by little so that you understand what each step is intended to do. Be patient, mate!

<img width="100%" style="width:100%" src="https://media.giphy.com/media/l0HlKrB02QY0f1mbm/giphy.gif">

#### name:

We can give a name to the workflow, it will appear in the Actions tab of the GitHub repository.

```yml
name: Cypress Tests
```

#### on:

It specifies the trigger for this workflow. This example uses the push event, so a workflow run is triggered every time someone pushes a change to the repository or merges a pull request. This is triggered by a push to every branch

```yml
name: Cypress Tests

on: [push]
```

#### jobs:

Groups all the jobs that run in the `ci.yml` workflow.

```yml
name: Cypress Tests

on: [push]

jobs:
```

#### cypress-run:

Defines a job named `cypress-run`. The keys within it will define the properties of the job.

```yml
name: Cypress Tests

on: [push]

jobs:
  cypress-run:
```

#### runs-on:

Configures the job to run on the latest version of an Ubuntu Linux runner. This means that the job will execute on a fresh virtual machine hosted by GitHub.

```yml
name: Cypress Tests

on: [push]

jobs:
  cypress-run:
    runs-on: ubuntu-latest
```

#### steps:

Groups together all the steps that run in the `cypress-run` job. Each item nested under this section is a separate action or shell script.

```yml
name: Cypress Tests

on: [push]

jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
```

#### step -  Checkout

The `uses` keyword specifies that this step will run v3 of the actions/checkout action. This is an action that checks out your repository onto the runner, allowing you to run scripts or other actions against your code.

```yml
name: Cypress Tests

on: [push]

jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
```

#### step -  Checkout

This step uses the `cypress-io/github-action@v2` action. The Cypress team maintains an official Cypress GitHub Action for running Cypress tests. This action provides npm installation, custom caching, additional configuration options and simplifies setup of advanced workflows with Cypress in the GitHub Actions platform.

```yml
name: Cypress Tests

on: [push]

jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cypress run 🧪
        uses: cypress-io/github-action@v2
```

For now, this is all we need to run the tests in the pipeline. Let's then commit the new files and upload them to GitHub:

```shell
git add .github/workflows/ci.yml
git commit -m "Added github actions workflow"
git push origin main
```

At this point, if we access the repository on GitHub and click on the Actions tab, we should be able to see that the actions were triggered by the commit as we wanted.

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

If we click on the running task, we can see the logs of all the commands that were executed

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

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

And finally, if we scroll down, we'll see the tests and their status (if everything went well, you'll see green, otherwise I feel sorry for you).

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

## Reporters

To finish this article in style, let's make our CI pipeline even fancier by adding reports to it. 

Cypress is built on top of Mocha, so any reporter built for Mocha can be used with Cypress. 

Let's install some dependencies that will help us generate these reports. Run this command in your terminal:

```shell
npm install cypress-multi-reporters mochawesome mochawesome-merge mochawesome-report-generator rimraf -D
```

Create a configuration file for the reports in the root folder of your project: 
  
```shell
touch reporter-config.json
```

In this file, paste the following content:

```json
{
  "reporterEnabled": "mochawesome",
  "mochawesomeReporterOptions": {
      "reporterDir": "mochawesome-report",
      "quiet": true,
      "overwrite": false,
      "html": false,
      "json": true
  }
}
```

Add the following scripts to `package.json`. It will help us generate the reports:

```json
"scripts": {
    "cy:open": "npx cypress open",
    "cy:run": "npx cypress run",
    "report:merge": "mochawesome-merge > index.json",
    "report:mocha": "marge index.json",
    "report:clean": "rimraf mochawesome-report index.js"
  },
```
 
To test **Mochawesome** reports, first run the tests:

```shell
npm run cy:run
```

Then run the following commands:

```shell
npm run report:merge
npm run report:mocha
```

`report:merge` -> will merge results from all specs
`report:mocha` -> will generate the report

To clean the results of the previous run:

```shell
npm run report:clean
```

Note that now the reports were generated inside the `mochawesome-report` folder, as configured in the json.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nt49mf59igs691xf9xvm.png)
 
Open the `index.html` file with any browser and see the run results

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

## Publishing the reports to GitHub Pages

Cool, we are already generating the reports locally, but we want more. Let's now publish them on a GitHub Page totally for free.

First let's increment our pipeline to generate the reports:

```yml
name: Cypress Tests

on:
  push:
  schedule:
    - cron: '0 0 * * 1'

jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cypress run 🧪
        uses: cypress-io/github-action@v2
      - run: npm run report:merge
      - run: npm run report:mocha

      - name: Reports deploy 🚀
        uses: JamesIves/github-pages-deploy-action@v4.3.3
        with:
            BRANCH: gh-pages
            FOLDER: mochawesome-report
```

Note that we now have a schedule key and cron. 

The cron expression **'0 0 * * 1'** basically means that tests will be run **weekly at 00:00 on Mondays**. 

_Check https://crontab.guru/ to better understand how cron expressions work._

Now we also have a new step called Reports deploy. In this step we will use an action responsible for deploying the results of our tests on a GitHub Page in the `gh-pages` branch.

Let's commit and push this to the repository:

```shell
git commit -am "Added step to deploy result to gh-pages"
git push origin main
```

The pipeline will run, but the reports will not be available yet. Our last step will be to configure the branch in the repository.

In your GitHub repository, under your repository name, click Settings.

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

In the "Code and automation" section of the sidebar, click on Pages. Select the `gh-pages` branch and Save.

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

Check that another action called `pages-build-deployment` has been run:

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

To see your published site, under "GitHub Pages", click your site's URL:

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

<img width="100%" style="width:100%" src="https://media.giphy.com/media/hlCZosJCwRhbW/giphy.gif">
 
...aaand BOOYAHH! Reports are available online, free of charge, and will be generated every time the tests are run:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqvf8hkfjpnmbcjyqyio.png)
 
Thanks for reading this post this far, and who knows, maybe we'll see you in part 4? I accept suggestions for topics for a future article. See ya!!