Building a CI pipeline with GitHub Actions and Cypress

Building a CI pipeline with GitHub Actions and Cypress The importance of Continuous Integration / Continuous Delivery should no longer be questioned these days. Yet many teams fail to recognise the added value of a solid pipeline to deliver code at pace. In this video I am not going to discuss the Advantages and Disadvantages of CI pipelines, but instead I am going to focus on showing how to build a very simple one with Github Actions. For this purpose I am going to choose React as a frontend and Cypress for automation tests. Which seems to be a very common stack these days.

Step 1

Will be to take an existing React application. I found this nextjs simple web app

which I decided to fork and rename cypress-react-pipeline-example

The application is fairly small app running on next js, so I decided to add the pipeline by clicking in Actions and then set-up a new nodejs workflow directly from github. But you could achieve the same by creating a directory called dot github on your project and adding your yaml workflow in there.

Github let me create a pull request for this new workflow which is going to run as soon as I create the PR.

In fact if I refresh the page you can see there are some pending actions on this pull request. By clicking on the Details link, it will take you to the Action view.

Something has failed, and that failed to call "npm ci", that is simply because we don't have that command in our project yet. So let's get started editing the project.

Step 2

I cloned the and opened the new branch it in VSCode. Let's take a look at the pipeline file. First of all we want to add the npm install command to add all dependencies Then we remove the node 10 from our version matrix and we re run the github actions by pushing the change.

This time the build passes hurray!

Step 3

I haven't developed this frontend, and this is obviously just and example, but I will take you trough what we could test here:

starting from the homepage I can see there is a list of movies here, there is also a sort of navbar with 2 links at the top. The movies link just take me back where I already am

Now we know what we are dealing with let's add Cypress for automation testing.

Step 4

Adding cypress to a project is really simple. First we need to install cypress as a dev dependency with the command

npm install cypress --save-dev

Then we can actually open cypress for the first time with the command

npx cypress open

This command will detect our project does not have cypress files so it will create them for us and it will launch a GUI which we don't need right now.

So I am going to delete all cypress examples from the integration/examples directory and the fixture example which we don't need either

Now we can create the first spec file. I am doing so by creating a file called movies.spec.js in the integration directory.

Testing Logic

I could start with some testing scenarios such as: context('Movies') it('should list all movies when I land on the home page')

I just want to write this first spec and run the command

npx cypress run

which does not open the GUI and runs the tests in Headless mode. From the console I can see my test is green and it has passed. So we can proceed to add some logic to it.

Step 5

Cypress has this GUI tool which is really useful, and it can be run with

npx cypress open

like I mentioned before so we open it again and we can see the scenario runs but Cypress does not have anywhere to go, and it rightly suggests to use the cy.visit command.

So we close cypress and we go to the cypress.json file where we can add our baseUrl which is localhost 3000

Then in the spec file I am adding

cy.visit('/') forward slash which is the root of our web application

Provided the application is running When I run cypress again I can see the GUI navigates correctly to the home page.

Now here there is this little target icon which is really useful to find the path of an object on the page. I can simply copy and paste the command from here and paste it in my spec file. Although I don't like all these unnecessary css classes generated by react so I remove them for readability and I simply test that the element should contain Wall-E.

Saving the file will re-run cypress automatically, but then I realise there is an error it's not actually Wall dash e but Wall dot E. So I just settle for WALL in capitals and that will do for now. Although it's not a great test it works.

Step 6

Great so we have our test, we have a pipeline ready to go, we need a command that starts the server and runs the tests in our github actions workflow.

One way to achieve this is to use a library called "start-server-and-test"

We can install this library and add a new script call in the pipeline called int-test for example.

So the way this works is, you call start-server-and-test followed by the start command for the server which is "next" in this case, followed by the host url which we want to ensure is up, which is local host 3000 and then a single test command, which I need to create there as cypress-run.

If I then run npm run int-test I will see the script starting the app then starting the tests aginst the app and finally give me the output and close everything

Great so I can push all this code to my pull request and I can see the pipeline starts again and passes.

And this is how you add a simple pipeline in github actions with cypress. I hope you find this video useful and if you have any questions about cypress or github actions feel free to leave a comment below and I'll see if I know the answer.

Thanks and see you next time