What you will learn from this how-to
- Creating Gitlab CI configuration
- Define variables in Gitlab CI
- Run cypress tests in Gitlab CI
- Fix cypress 'sad face' crash
- In the second part of this post: Automatic deploys with GitLab CI
A bit of history
I have written something similar a while back on my personal blog - Testing websites with cypress and GitLab CI - Part2
The new version described here is updated and works even better with Gitlab CI and it should be easy for you to adapt it to some other CI.
This post also does not cover the installation of cypress, I have written about this in my Testing websites with cypress and GitLab CI - Part1 post and there are a lot of posts about that out there.
Move cypress to a separate docker image
I needed cypress with ruby 2.3 to get
wagon from LocomotiveCMS working, to keep my project's
.gitlab-ci.yml clean I decided to create a separate docker image for cypress and ruby based on the official cypress Dockerfile you can find the resulting Dockerfile in our Gitlab repo.
I will spare you the content of the Dockerfile and you can find the resulting image on Dockerhub under lcxat/cypress-ruby
The main takeaway is that it bases on ruby:2.3.8 and node:12.1.0 after which it installs cypress on top of it. Update it to the ruby version you need if 2.3.8 does not suit you.
Creating Gitlab CI configuration
The Building stage
Let's start with the building stage in gitlab CI and work from there to a complete
- gem install bundler
- bundle install -j $(nproc) --path vendor
- sed -e s/APIKEY/$LOCO_API/g config/deploy-testing.yml > config/deploy.yml
- bundle exec wagon deploy testing -v -d
Let's analyze what's going on here, I'm starting off the previously mentioned Docker image
lcxat/cypress-ruby. To speed things up I have added a cache setting in the
.gitlab-ci.yml and also told bundler to install the gems in the
vendor path which is cached.
Then there is this
sed part, a little bit of
wagon background: The
wagon tool needs an API key to be able to deploy to our testing environment, you could start
wagon locally on the gitlab CI and test it like that, but the problem is that
wagon does not behave 100% the same as after deploying the page, that's why I went with a real deploy to a testing page on a live server. Now since you don't want any API keys in the git repo, I use
sed and Gitlab's variable settings to fix this and create a valid
Go in your gitlab under settings -> CI/CD and add a new variable called
LOCO_API with your API Key as the value.
deploy.yml looks something like this
sed runs it replaces
APIKEY with the value provided in Gitlab's variables setting mentioned above.
If you now commit and push to gitlab you should have a successful pipeline run for the building stage. Great, now let's go to the testing part.
Testing with cypress
Add a test stage to your
.gitlab-ci.yml file like this:
- sed -i -e s#http://localhost:3333/#$CMS_URL#g cypress.json
- npm test
and extend your
ok, let's dig into this. There is again a sed command the edits the
cypress.json in place
I'm doing this since I also want to be able to test locally, that's why the
cypress.json looks like this
This allows me to test locally but of course, will fail when testing on CI since wagon did not start the server locally. Once again you must define a gitlab variable pointing to where the test page is deployed and name the variable
npm test to work, you need to have a proper setup
package.json something like this, please note
"private": true, to prevent npm from publishing your repo.
Ok, now commit and push to gitlab and wait for the test to start ... and most likely fail.
We detected that the Chromium Renderer process just crashed.
This is the equivalent to seeing the 'sad face' when Chrome dies.
This can happen for a number of different reasons:
- You wrote an endless loop and you must fix your own code
- There is a memory leak in Cypress (unlikely but possible)
- You are running Docker (there is an easy fix for this: see link below)
- You are running lots of tests on a memory intense application
- You are running in a memory starved VM environment
- There are problems with your GPU / GPU drivers
- There are browser bugs in Chromium
You can learn more including how to fix Docker here:
or as screenshot
Well, this is a bummer :(
What's happening here is that the Electron app runs out of shared memory and crashes, the cypress link tells you if you are running in docker, that you should start it with
--ipc=host but that won't work in my case. Gitlab runner is running as a docker container but I would not like to start all containers with this setting. Assuming you are running gitlab-runner in docker, edit your
config.toml and add this to your volume setting
which will then look something like this:
volumes = ["/opt/docker/gitlab-runner/cache:/cache","/dev/shm:/dev/shm"] you don't really need the
cache part, but I wanted to see what gitlab-ci is doing with the cache so I added that part as well.
Stop & Restart your gitlab-runner to pick up the changes and rerun the failed job, it should now pass with flying colors and no more Chromium crashes.
Some notes about the cache
I have been playing with several cache settings and here are some things that might help when looking at what gitlab-ci does. If you look at the end of the build, you must see that gitlab-ci has created the cache
Creating cache new-docker...
vendor/ruby: found 9813 matching files
No URL provided, cache will be not uploaded to shared cache server. Cache will be stored only locally.
Don't freak when looking at the next stage where it says
Reinitialized existing Git repository in /builds/foo/bar/.git/
Checking out ee8d93ed as new_docker...
This is not gitlab removing the cache but git clean! Don't worry, the cache will be back when needed, gitlab-ci takes care of that. Just make sure you run
bundle on each stage where you need the gems and don't forget to add the --path vendor otherwise it will install all gems from scratch an not use the cache
In the second part - Automatic deploys with GitLab CI, I will take this a step further and configure gitlab to automatically deploy to staging and add a manual option to allow deploying to production with the click of a button.