React, Cypress, Docker mini project

22 June 2021

Category: Mini

Greetings! Last week I was struggling with yet another totally new stuff - implementing Cypress component tests and then dockerize it all. I went through a lot of posts, links, and videos to filter it all out and somehow put it together. So I thought maybe I could make a very minimalistic project as an example for other pilgrims out there.

You can download the project Here.

First run npm install in root directory. Run cd tests. Run npm install in Tests directory. That should fill out the missing packages into node_modules. At this point, the project is already set up so from Tests folder, you can run Cypress tests with just basic docker-compose up.

But lets look at it first in more detail.

React app

React app

The frontend is a super minimalistic react app, nothing fancy or special. Just notice using id from props in Square and Button components. Those are important in Cypress tests.

Cypress

Cypress is set in the way described on the Cypress webpage Here . So simple npm install cypress --save-dev command.

For easier work with Cypress, I also added "cypress": "cypress open" into package.json “scripts” array.

Also added { "baseUrl": "http://localhost:3000" } into Cypress.json for use from inside the tests when running Cypress tests locally.

Otherwise, I would say the tests themselves are pretty standard and basic. To actually learn Cypress tests I used this tutorial . It’s very fast, so you really need to pay attention, but it’s directly from a Cypress guy, so it’s a great source.

To run test locally, just run npm run cypress when inside the Tests directory.

Docker

To run tests from Docker, you can just run the afore mentioned docker-compose up . But let’s look closer on the dockerfiles used. Great source I used as a base is Cypress blog - Run Cypress with a single Docker command .

.dockerignore - here I just ignore Tests, node_modules and Dockerfile, because those are not necessary.

Dockerfile in root directory:

# Get node instance
FROM node:14
# Set workdir
WORKDIR /app
# copy package.json as optimization to not need to run npm install in case nothing changes here
COPY package.json .
# install stuff from package.json
RUN npm install
# copy everything, if something changed
COPY . .
# document exposure of port 3000
EXPOSE 3000
# start the app
CMD [ "npm", "start" ]

I think that the most interesting is docker-compose.yml in Tests directory, so let’s go through it:

# selecting version of docker-compose
version: '3.2'

# setup services (containers)
services:

  # naming service with frontend as "fe"
  fe:
    
    # setting location of the Dockerfile
    build:
    
    # we need to go to parent directory, where the Dockerfile for the React app is
      context: ../
      
      # selecting what Dockerfile to use
      dockerfile: Dockerfile
    
    # setting env variables
    environment:
      # publishing port 3000 (same as -p 3000:3000 while using docker run command)
      - PORT=3000
      
  # Cypress container
  cypress:
    # the Docker image to use from https://github.com/cypress-io/cypress-docker-images
    image: "cypress/included:7.5.0"
    
    # cypress service won't build if building of frontend service fails
    depends_on:
      - fe
      
# setting env variables
    environment:
      # pass base url to test pointing at the web application - in this case it's "fe"
      - CYPRESS_baseUrl=http://fe:3000
      
      # do not record videos
      - CYPRESS_VIDEO=false
      
    # share the current folder as bind mount volume to avoid copying
    working_dir: /e2e
    volumes:
      - ./:/e2e

For convenient shutdown after the tests complete, you can use: docker-compose up --abort-on-container-exit --exit-code-from cypress

For a quick help with those parameters, run docker-compose up --help .

And that’s how it’s done.. well, how is make a foundation stone for this workflow anyways :)

If you want to dive deep into Docker, I can wholeheartedly recommend Maximilian Schwarzemuller’r course on Udemy: Docker & Kubernetes: The Practical Guide .

Cheers!

Petr