Paralleling Cypress with Sorry Cypress on Render

Cypress is an integrated testing framework for web apps, and web components. It's popular due to it's ease of setup, and visual browser. In this blog I discuss parallel test running with the open source tool sorry cypress.

TL;DR

If you want to host the sorry cypress kit, then https://render.com/ makes it simple.

There is a sample repo here: https://github.com/simonireilly/render-sorry-cypress

Results

When hosting cypress in parallel for the default cypress test suite I performed a comparison on github actions:

Scenario Cypress time Total time
Cypress single runner 417 (s) 432 (s)
Cypress five runners 98 (s) 117 (s)

It's really a great deal faster to invest in running the test suite in parallel even with just 20 test files, there is a huge benefit to cycle time.

Test run comparison in github actions

Sorry cypress running in github actions

The speed benefits are certainly worthwhile, and the scalability unlocked by a coordinator like sorry cypress, over a configured parallel setup, means low configuration complexity.

Background

I have been using Cypress as a test runner since 2019, and enjoyed it's low barrier to entry.

It is probably well know that Cypress itself is not the fastest test runner, because it uses a full browser when running tests instead of other tools that might use a webkit only.

The advantages of Cypress are that it has a fast release cadence, adds new features frequently, and is intuitive.

To combat the slow test runtimes cypress provides a hosted director. The director issues batches of tests to each runner that joins the pool for that build id. It looks something like this:

Sorry Cypress Architecture

Sorry cypress architecture, on the assumption that cypress themselves do something similar but at a much larger scale!

Running Sorry Cypress

There are some setup instructions for self hosting sorry cypress here.

I wanted to try hosting Sorry Cypress on render.com because:

Render Setup

To run sorry cypress on render it's straight forward; here is a blueprint yaml file that will work for you:

The blueprint-spec is here, I recommend a read: render.com/docs/blueprint-spec

services:
- type: web
name: director
env: docker
healthCheckPath: /
dockerfilePath: ./Dockerfile.director
envVars:
- key: DASHBOARD_URL
fromService:
name: dashboard
type: web
envVarKey: RENDER_EXTERNAL_URL
- key: EXECUTION_DRIVER
value: ../execution/mongo/driver
- key: SCREENSHOTS_DRIVER
value: ../screenshots/s3.driver
- key: MONGODB_DATABASE
value: sorry-cypress
- key: MONGODB_URI
fromService:
name: mongo
type: pserv
envVarKey: MONGODB_URI

- type: web
name: dashboard
env: docker
healthCheckPath: /
dockerfilePath: ./Dockerfile.dashboard
envVars:
- key: GRAPHQL_SCHemA_URL
fromService:
name: api
type: web
envVarKey: RENDER_EXTERNAL_URL
- key: PORT
value: 8080
- key: CI_URL
value: ""

- type: web
name: api
env: docker
dockerfilePath: ./Dockerfile.api
envVars:
- key: MONGODB_URI
fromService:
name: mongo
type: pserv
envVarKey: MONGODB_URI
- key: MONGODB_DATABASE
value: sorry-cypress

- type: pserv
name: mongo
env: docker
dockerfilePath: ./Dockerfile.mongo
envVars:
- key: MONGO_INITDB_ROOT_PASSWORD
value: <password>
- key: MONGO_INITDB_ROOT_USERNAME
value: sorry-cypress
- key: MONGODB_URI
value: mongodb://sorry-cypress:<password>@<replace-with-pserv-address>:27017
disk:
name: data
mountPath: /data/db
sizeGB: 1

You will need to update the <password> before deploying the blueprint, and on first pass it will fail.

After you have mongo deployed you will need to edit the template setting <replace-with-pserv-address> to the network addressable name of your mongo instance:

Get addressable endpoint for mongo

The addressable endpoint for mongo is not known until deploy time; this would be fine if Sorry Cypress supported MONGO_HOST etc. but it expects a fully qualified URI, and render does not yet support env var interpolation

The benefit of render is that it will pick up on these changes, and notice the dependency chain between env var's exported from other services. It will re-deploy on each change, and reboot those services.

Running tests

I have an example runner setup to use github actions, which was shown in the early part of the blog.

The setup itself was very straight forward.

Sorry Cypress Dashboard

Sorry Cypress dashboard showing my example project.

The runs themselves are reported to sorry cypress from the test runners and appear inside the examples. I decided to use the git sha for my test runs since it will be unique all of the time:

Sorry Cypress Dashboard showing test run

Sorry Cypress example test run in the sorry cypress dashboard

Wrap up

I loved using sorry cypress, and hosting it on render was a lot easier than I expected.

Since render is setup to scale, I could see this being the most intuitive way to continue to use sorry cypress at a super low cost of $7.25/month; until my use case expands. At that point scaling up on render seems as easy as a few lines of yaml 👍