Implementing Cypress Testing into a Codefresh Pipeline
Cypress.io is a next generation front end testing tool built for the modern web. It is utilized by developers or QA engineers building web applications using modern JavaScript frameworks.
They are an extremely robust end-to-end testing platform, and are very extensible. Cypress can test anything that runs in a browser. This makes it a very powerful tool, and perfect to implement into a CI/CD pipeline. For this we’ll need an application to work with.
The Kitchen Sink
Today, we’re going to use a sample application published by the Cypress.io team called Kitchen Sink, and will show how to integrate Cypress testing into a Codefresh pipeline.
This also works out because Codefresh is not included in the example pipeline configs here, so we will have a chance to contribute the finished pipeline YAML to the project so others can use it to implement Cypress testing into their Codefresh pipelines.
The Pipeline
I have cloned the source repository in GitHub so we can use it as we see fit. I created a fresh pipeline in Codefresh, and it defaults to a basic 3-stage Pipeline. For the purposes of this demo, we’re going to nuke the Build stage out and just go with Clone and Test.
Clone Stage
When you setup your pipeline in Codefresh, it asks you for some information, such as the Git reposity. From there, it automatically sets up the Clone stage for you. This makes things very easy, and we didn’t even have to make any changes to it.
steps:
clone:
title: "Cloning repository"
type: "git-clone"
repo: "vtimd/codefresh-blog"
# CF_BRANCH value is auto set when pipeline is triggered
# Learn more at codefresh.io/docs/docs/codefresh-yaml/variables/
revision: "${{CF_BRANCH}}"
git: "github"
stage: "clone"
Test Stage
Let’s take a look at the default YAML for the test stage:
test:
title: "Running test"
type: "freestyle" # Run any command
image: "ubuntu:latest" # The image in which command will be executed
working_directory: "${{clone}}" # Running command where code cloned
commands:
- "ls"
stage: "test"
This gives us all the information that we will need to setup the proper test phase. So let’s break it down and make the changes we need to make. We’re going to leave the title and type as-is because the title is fine, and we are making a Freestyle task. For more info on tasks in Codefresh, check out this page.
The first change will be to the image lime. This is the container image that the Codefresh runtime will use for the stage. To make CI implementation easier, Cypress has a container image ready to go on Docker Hub. We’ll update the YAML replacing the stock Ubuntu image with our cypress image:
image: cypress/base
We’re going to leave the working_directory as it is, because we want to be working in the directory copied from GitHub in the Clone stage. The next section we’re getting into is building out the commands. This is the meat and potatoes of how we make this work. This stage loads the runtime container, then executes the commands inside the container environment. Let’s break down the commands, in order:
- npm ci
The first command is ‘npm ci’. We use this instead of ‘npm run’ to intiate the install of the required dependencies. This command starts by flushing out any modules used in any previous runs, to ensure a clean run.
This is what you should see in the output from the pipeline:
- npm run cy:verify
Next we’re going to run ‘npm run cy:verify’. This is going to run a check to make sure Cypress can run inside of the runtime environment.
The output of which will look like:
- (npm run start:ci &)
Now we need to start and run the app. We’re doing that with ‘npm run start:ci’. In order to make sure that this command runs in the background, we use the & symbol so that bash knows to background it. Though, this causes a syntax error. Due to issues with the execution of the commands in the runtime environment, I needed to put this command in parentheses. The error shown when you don’t do this looks like this:
With this change it is able to successfully execute the command, thus running the app in the background.
- npm run e2e
Now we need to execute the test against the app. To do this, we’ll run the ‘npm run e2e’ command. This runs the Cypress tests against the app. You will will see output in the pipeline similar to the following:
And that’s it. We have made all the code alterations to the original YAML that we need to make the Cypress tests execute successfully in our Codefresh runtime environment. This is the chunk of code that we end up with in the final Pipeline YAML:
test:
title: "Running Cypress test"
type: "freestyle" # Run any command
image: cypress/base
working_directory: "${{clone}}" # Running command where code cloned
commands:
- npm ci
- npm run cy:verify
- (npm run start:ci &)
- npm run e2e
stage: "test"
Conclusion
And with that, we run the pipeline and see that it successfully executes! It takes about 3 minutes and 12 seconds to clone the repo, load the environment, and run the tests.
To wrap things up, you can see that with pretty minimal effort, we were able to take a sample application, build a small test step, and successfully execute a Cypress test in a Codefresh pipeline. If you have any questions, or input, feel free to reach out on Twitter!
-Tim D. – Cloud and Developer Advocate