UI Testing with Cypress

What is Cypress?

Cypress is an end to end frontend testing framework written in Javascript. While similar to Selenium, Cypress is built to run in a Node.js server process so that it has access to everything that happens in the DOM, making it easier to check events as they happen in the UI.

Why We Use Cypress at Ginkgo

At Ginkgo we tend to iterate quickly on features that touch lots of different lab workflows. Sometimes a simple button change could have unexpected downstream effects which lead to small reactive work to fix them. With Cypress we are able to quickly run through common workflows and confirm that they work as expected without having to manually click through them for every small change we make to the codebase.

Quick Setup

Add the Cypress package.

yarn add cypress -dev

Open Cypress Studio.

yarn cypress open

Cypress Studio

Tips and Tricks

Using cy.get() with a timeout is much better than cy.wait().

Initially it can be tempting to plug in waits everywhere to fix issues with timeouts that happen from longer running tasks. While just adding waits before a get can fix these issues, a much better pattern is to add a longer timeout to cy.get() like: cy.get('[data-cy="table-row"]', { timeout: 7000 }); This allows it to wait till the DOM has that tag or until the timeout occurs rather than just waiting a set amount of time every run.

Leveraging common setup steps into commands cleans up code.

Using Cypress commands and hooks for highly reused pieces of code helps clean up the code and makes it easier to debug what the test is actually trying to test. One highly useful command is login which allows us to just call cy.login(); at the start of each test suite.

Cypress.Commands.add(
 'login',
 ({
   email,
   password,
 } = {}) => {# fetch a API token and save it});

Configuring Cypress to save test videos pays off for figuring flakiness

A really useful feature of Cypress is being able to record the steps of the Cypress Studio in the CI/CD pipeline which allows us to view what happened in the UI to make the test fail, it can be configured to record both mp4 and screenshots which can help narrow down the issues when debugging.

Cypress Video

Set variables in cypress.json.

Overriding some of the default variables in Cypress can be done by setting them in the cypress.json file. Some that are helpful depending on the situation is setting defaultCommandTimeout (controls how long cypress will wait for a tasks to finish before it fails the test), retries (will control the number of times cypress will try to run a fail test before it gives up and marks it as failed), pageLoadTimeout (how long Cypress will wait for the DOM to load up), and numTestsKeptInMemory (the number of test data Cypress will keep in memory — the default is 50 however we were getting a lot of memory consumption and reducing this helped a lot).

Hopefully this helps others realize the value of using Cypress and allows you to get up and running to catch software bugs before they go to production.

(Feature photo by Ferenc Almasi on Unsplash)

Posted By