Run Cypress tests on Real Devices

Use BrowserStack Automate to run Cypress tests on real devices and browsers

Get Started free
Home Guide Cypress Docker Tutorial

Cypress Docker Tutorial

By Gurudatt S A, Community Contributor -

Docker is a platform that enables the packaging of an application along with all its dependencies required for it to run. This package is called an Image, which can be executed as a Container.

Cypress is a popular test automation tool that allows you to run API, Component, and End-to-End tests within the selected browser version. This also means that you have to constantly maintain the Cypress Version and Browser version installed on the machine where the Cypress tests run to be in sync.

Combining Cypress with Docker ensures that the Cypress version and browser version remain consistently synchronized, as specified, whether tests are run locally or in a CI environment.

Understanding Docker

Before delving further, it is essential to understand Docker architecture and the key concepts involved.

Docker Architecture

The architecture comprises of three key components

  • Docker Host
  • Client
  • Registry

Docker Host

Docker host consists of

  • Docker daemon
  • Images
  • Containers

Docker Daemon takes input from Docker clients and does all the heavy lifting of building, running, and distributing the Docker containers.

The Docker daemon and client interact using REST API. The Docker daemon listens for Docker API requests and manages Docker objects such as Images (blueprints of applications), Containers (runtime instances of images), Networks (connections enabling communication between containers), and Volumes (persistent storage for container data)..

Docker Client

Users interact with the Docker daemon using the client. The client takes the input commands such as docker run docker build docker pull. The docker command uses the Docker API and the docker client sends these commands to Docker Daemon using REST API.

Docker Registry

Docker registry is the centralized place where images are stored. Docker Hub is a public registry that anyone can use.

By default, Docker searches for images in the Docker Hub. A private registry can be used as an alternative to Docker Hub.

Docker Desktop

Docker Desktop is an installation file for MAC, Windows, and Linux environments that enables the building and sharing of containers. It includes the docker daemon, docker client, docker compose, docker content trust, Kubernetes, and credential helper.

Dockerfile Overview

To run an application in Docker, an image must first be created, which can then be executed as a container.

To build the image, docker refers to the dockerfile which contains the instructions on how to build the image.

Below is a simple example of how a docker file looks

# Use an official Node.js image as the base
FROM node:14

# Set the working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json files to the container
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code to the container
COPY . .

# Expose the port the app runs on
EXPOSE 3000

# Command to start the application
CMD ["node", "app.js"]

After placing this file in the root directory, the following command can be executed to build the image.

docker build -t my-node-app .
  • docker build will create the image
  • -t my-node-app is to provide a tag for the image. In this case, the tag is my-node-app
  • . at the end of the command specifies the build context. In this case, docker will use the current directory and all its content to build the image.

Docker image and Container

A docker image is an executable package that contains everything required to run the application.

  • A typical example that a docker image would contain
  • Application Code
  • Runtime like Node.js, Python, etc.
  • System tools
  • Libraries/Dependencies
  • Configuration Files

The docker image is built in terms of layers. Every command in the dockerfile is a layer. These layers are cached and reused, making the images efficient.

Note: The Docker images are Immutable, which means that if you create the Docker image once, you can edit that image, but any change must be made to the new image.

The running instance of the docker image is called Container. The application will be running inside the container.

Here’s a breakdown of the command:

  • docker run: Runs the image as a container
  • -d: Run the container in detached mode(Runs in background)
  • -p 3000:3000: Maps the 3000 port on the machine where the container is running to the 3000 port inside the container.
  • –name my-running-app: Assigns the name to the container
  • my-node-app: name of the docker image

Benefits of using Docker

Docker is beneficial and popular because of its flexibility, efficiency, and portability.

Below are the few key benefits of docker:

  • Environment Consistency: By packaging the application and its dependency as an image and running it as a container, the application behaves the same across environments.
  • Isolation: Every container runs in an isolated environment, which allows multiple containers to run within the same host/machine without interference.
  • Fast and Lightweight: Containers consume fewer resources than VMs, and since they don’t need to boot a full OS, they operate faster.
  • Portability: Docker images built once can be run as containers in any environment, making it powerful from a portability perspective.
  • Usage: Docker allows CI/CD (Continuous Integration/Continuous Deployment) automation, making it widely used in DevOps practices

What is Cypress Docker

Cypress provides docker images with a browser and a Cypress test runner pre-installed.

Running the Cypress tests using the Cypress docker containers ensures that the tests’ execution remains consistent regarding browser, Cypress, and node.js versions.

Cypress provides below images:

  • cypress/factory: A base image template which can be used with ARGs to create a custom docker image.
  • cypress/base: All operating system dependencies, no Cypress, and no browsers.
  • cypress/browsers: All operating system dependencies, no Cypress, and some browsers.
  • cypress/included: All operating system dependencies, Cypress, and some browsers installed globally.

Out of these, the most popular and regularly used is Cypress/included ,as it comes with Cypress and has browsers installed.

Setting up and Running Cypress tests using Cypress Docker

The setting up of docker is straightforward.

  1. Download the docker desktop from here and install.
  2. After successful installation, open the docker desktop (This will run the docker daemon)

To run the Cypress tests in docker container, execute the below docker command from the root of your Cypress project

docker run -it -v $PWD:/e2e -w /e2e cypress/included:13.11.0

Note: $PWD works in Linux, macOS, GitBash. For window system replace the $PWD with %cd% (Ex: docker run -it -v %cd%:/e2e -w /e2e cypress/included:13.11.0)

Here’s a breakdown of the command

  • docker run: This will start a new docker container(Note that this will look for existing images and if the specified image and version of the cypress is not found then it will download)
  • -it: This will run the container in interactive mode and also show the output in real-time in the terminal
  • -v $PWD:/e2e: This will mount the current directory on the host machine into the container at /e2e (Note that $PWD is an environment variable which points to current working directory from where the command is executed)
  • -w /e2e: This will set the working directory inside the running container to /e2e folder where our tests resides
  • cypress/included:13.11.0 : Specifies the type of image you want and its version. This image comes with Cypress pre-installed along with some browsers(Electron).

Once you execute the above command, the terminal will look similar to the one below.

Setting up Cypress Tests Using Cypress Docker

Running Cypress tests using Cypress Docker

Cross Browser Testing with Cypress Docker

Cypress provides different browsers in its image cypress/browser. Using this image, testing can be performed across all supported browsers running inside the container.

Below are the browsers supported in the cypress/browsers image.

  • Google Chrome
  • Mozilla Firefox
  • Microsoft Edge

With cross browser testing the same functionality can be validated across different browsers and ensure the behavior is consistent.

To start with cross browser testing, the below items are required:

  • dockerfile
  • docker-compose file
  • pipeline yaml file

Creating dockerfile

In the root of your cypress project, create a new file and name it as Dockerfile and add the below commands

FROM cypress/browsers:latest

WORKDIR /e2e

COPY ./package.json .
COPY ./cypress.config.ts .
COPY ./cypress ./cypress

RUN npm install &&\
   npx cypress info

ENTRYPOINT ["npx", "cypress", "run"]

Here’s a break down of the commands:

  • FROM cypress/browsers:latest: This line specifies the base image and its version that must be used.
  • WORKDIR /e2e : Sets the e2e folder as working directory
  • COPY ./package.json . : copies the package.json file into the root of working directory
  • COPY ./cypress.config.ts . : copies the cypress.config.ts file into the root of working directory
  • COPY ./cypress ./cypress : copies the folder cypress into the root of working directory as a folder with same name
  • RUN npm install &&\
    npx cypress info : Installs the dependencies and then prints the information from cypress(This is helpful to check the cypress version and browser details)
  • ENTRYPOINT [“npx”, “cypress”, “run”] : This is the default command that will be executed when the container starts

Creating docker-compose file

Create a new file named docker-compose.yml and paste the below command

version: '3.8'

services:
 e2e-chrome:
   build: .
   command: "-b chrome"


  e2e-firefox:
   build: .
   command: "-b firefox -c video=false"

Here’s a break down of the commands

  • version: ‘3.8’: This is the docker-compose file version
  • e2e-chrome: This is the service name which will use the container to run the cypress tests
  • build: This will ensure to use the Dockerfile to build the image for each service
  • command : This is to pass the optional commands to the Entry point command specified in the Dockerfile. “-b chrome” is to ensure cypress uses browser chrome to run tests

Another service has been created to test on Firefox using the same command block.

Create github workflow to run the tests across browser in Github

In the root of the project, create a new folder named .github > workflows > crossbrowserTest.yml

Paste the below in the file and save

name: cross browser testing

on:
 push:
   branches:
    - 'main'

jobs:
 cypress-run:
   runs-on: ubuntu-latest
   timeout-minutes: 5

   steps:
     - name: checkout
       uses: actions/checkout@v3

     - name: run docker-compose
       run: docker compose up -d e2e-chrome e2e-firefox

     - name: wait for services to start
       run: docker compose logs -f

Here is a break down of the commands:

name: Specifies the name of the workflow

Below block specifies to trigger this workflow when any code is pushed to main branch

on:
 push:
   branches:
    - 'main'
  • cypress-run: This is the job name
  • Runs-on: This is to specify in which OS the tests need to be run
  • timeout-minutes: Maximum time allowed to complete this job

Below block is a step within the job to check out the code

steps:
     - name: checkout
       uses: actions/checkout@v3

Below block is a step to create the image and run the containers under the services defined in the docker-compose file in parallel

- name: run docker-compose
       run: docker compose up -d e2e-chrome e2e-firefox

Below block is a step to create the image and run the containers under the services defined in the docker-compose file in parallel

- name: run docker-compose
       run: docker compose up -d e2e-chrome e2e-firefox

Below block is to wait for containers to start and then print the logs

- name: wait for services to start
       run: docker compose logs -f

The file structure in the project should look like below

File Structure

Once this is pushed to github and you navigate to Actions tab, the workflow will look like below

Workflow

The log can be checked to ensure the services and containers have been created with the specified browser.

Check the logs

Why use BrowserStack Automate for Cypress Tests?

Here’s why you should run your Cypress tests on Real Devices & Browsers using BrowserStack Automate:

  • Diverse Environment Testing: It enables the execution of Cypress tests across a broad selection of browsers and operating systems, eliminating the necessity for maintaining local testing infrastructure. This ensures consistent application performance across various platforms.
  • Parallel Testing: BrowserStack Automate significantly reduces total testing time by allowing simultaneous execution of multiple Cypress test suites, facilitating quicker iterative feedback and accelerated deployment cycles.
  • CI/CD Integration: The platform seamlessly integrates with major CI/CD systems, including GitHub Actions, Azure Pipelines, GitLab CI/CD, CircleCI, Jenkins, and Bitbucket, automating the testing process within the development pipeline.
  • Diagnostic Tools for Better Debugging: BrowserStack provides comprehensive diagnostic capabilities, including detailed logs, screenshots, and video recordings of test sessions, aiding in the swift identification and resolution of issues.
  • Testing on Real Devices: Beyond simulated environments, BrowserStack also supports testing on real devices and browsers on the cloud, offering more precise and real-world test outcomes.
  • Customizable Test Execution: Users can tailor test executions to meet specific needs through BrowserStack’s user interface or APIs, enabling adaptable and controlled test runs.

BrowserStack Automate Banner

cy.wrap is a versatile and essential command in Cypress that allows you to handle non-Cypress objects, functions, and promises effectively. By wrapping objects or responses, you can seamlessly integrate Cypress’s native assertions and commands into your test scripts, enhancing both flexibility and readability.

Whether dealing with API responses, asynchronous operations, or external functions, mastering cy.wrap can significantly improve your test automation workflow and ensure more reliable results in your testing process.

BrowserStack Automate is an excellent choice for running Cypress tests because it offers a scalable, cloud-based infrastructure that eliminates the need for complex local setups.

BrowserStack supports real-time cross-browser testing, parallel execution, and integrations with CI/CD pipelines, ensuring faster test runs and streamlined workflows.

Talk to an Expert

Top Useful Docker Commands

Here is a list of some of the most useful docker commands:

  • docker inspect <container_or_image_name_or_id> : To view detailed information about docker image or Container
  • docker stats: To view resource usage of all the running containers
  • docker history <image_name_or_id>: To view the history of how the image is built
  • docker volume ls: To view all the volumes within the container
  • docker-compose down: To stop the running docker compose services
  • docker run -it –rm –memory=”512m” –cpus=”1″ my-app : To limit the memory and CPU usage

Conclusion

Cypress docker effectively ensures that parameters like node.js, cypress, and browser version are used as needed and remain the same across test execution environments.

Effective pipelines can be built with Cypress Docker to ensure the application behaves consistently across various browsers during cross-browser testing.

Useful Resources for Cypress

Understanding Cypress

Use Cases

Tool Comparisons

Tags
Automation Testing Cypress Real Device Cloud

Featured Articles

TestCafe vs Cypress: Core Differences

Cypress vs Selenium: Key Differences

Automation Tests on Real Devices & Browsers

Seamlessly Run Automation Tests on 3500+ real Devices & Browsers