Cypress Tests Parallelization With X-Server In Gitlab CI

Nithin Ramesha
EQS Engineering Blog
3 min readOct 24, 2022

We all have a massive amount of spec files that take an eternity to go through our pipelines. Any good end-to-end tests in a CI process should be developer friendly for developers to receive early feedback on their newest changes with the test results from the CI pipeline.

This article will aid you in parallelizing your test/spec files to reduce test execution time if you use a Cypress-Gitlab configuration in your project.

X Server Conflict

Since Cypress requires a x11 server, and in order to progress, please familiarize yourself with the xvfb concept.

The below error is thrown by the jobs Test 2 and Test 3
_XSERVTransSocketUNIXCreateListener: ...SocketCreateListener() failed 59_XSERVTransMakeAllCOTSServerListeners: server already running60(EE)61Fatal server error:62(EE) Cannot establish any listening sockets - Make sure an X server isn't already running(EE)

Do you recognize the trouble code seen above? Otherwise, proceed to the solution section.

You probably have separated your tests to run in multiple parallel jobs in GitLab, which led to the problem. The error code attempts to convey a lot of information.

  • The cypress instance has already established an X server in the Test 1 job.
  • Jobs Test 2 and Test 3 are attempting to reach the same X server initially created and occupied by the cypress instance in Job Test 1, resulting in the 'server already running' error.
  • It requests a new/available X server to avoid conflict with others.

Solution

We use double digits to define the port to spawn different instances of the x11 server in the background, such as :99, but it can be any value between :10 and:99. By doing so, we avoid clashing x11 servers.

Xvfb :99 &
export DISPLAY=:99

Now, let's see how we can configure the xvfb in our GitLab script.

job A:
stage: e2e-tests
script:
- Xvfb :59 &
- export DISPLAY=:59
- npx cypress run --spec test1.cy.ts,test2.cy.ts,test3.cy.ts
after_script:
- rm -rf /tmp/.X59-lock
job B:
stage: e2e-tests
script:
- Xvfb :58 &
- export DISPLAY=:58
- npx cypress run --spec test4.cy.ts,test5.cy.ts,test6.cy.ts
after_script:
- rm -rf /tmp/.X58-lock
job C:
stage: e2e-tests
script:
- Xvfb :57 &
- export DISPLAY=:57
- npx cypress run --spec test7.cy.ts,test8.cy.ts,test9.cy.ts
after_script:
- rm -rf /tmp/.X57-lock

First, let's divide our test/spec files into groups to add them to the GitLab jobs. For example, we pass the following spec files for job A: test1.cy.ts, test2.cy.ts, test3.cy.ts, and so on. Depending on the number of test/spec files, you can have as many jobs as you desire.

Tip: In the after_script: section, we include a short piece of code that deletes the lock file generated during runtime for the port used for our Cypress test execution. So that the next time you execute the job, it won’t clash with the prior residue files in the server for the respective ports.

An example of our internal pipeline with parallelization of e2e-tests

We at EQS Group have lowered our test execution times from approximately 22 minutes to less than 5 minutes. I hope this helps you reduce your projects' execution times; best wishes.

Does your heart beat for developing exciting SaaS products? We are always looking for motivated new team members. Please take a look at our vacancies: https://eqs-group.personio.de/recruiting/positions.

--

--