banner

Some background info before my recipe. If you’re in hurry, scroll down directly to Install Instructions.

Until now, UI automated testing has been a pain. Always relying on Selenium, and several other node packages, basically the setup I was using 2 years ago to test a react app had dependencies like this:

  • mocha (testing framework)
  • chai (for assertions)
  • chai-as-promised (cleaner assertions)
  • selenium-webdriver (for browser automation)
  • phantomjs-prebuilt (headless browser, to run the tests in the command line)
  • chromedriver (to run the tests using Chrome, good for debug)
  • coffee-script (cleaner sintax)

Not to mention that phantomjs was discontinued in favor of Chrome Headless.

Anyway, the whole shebang was really unstable: as Selenium is an external framework relying on a client/server communication, and phantomjs was not a real browser, several times our working tests will return false negatives.

Then, let’s say “hi!” to cypress and its incredible package dependency:

  • cypress

Yeap, that’s it: it’s a self contained node package, using Electron to run our tests with, in a headless way or with a friendly UI:

Cypress Test Runner

Install Instructions

Just run in your project folder:

npm install cypress --save-dev

After that, we’ll change some default behaviors:

  • we want nice commands to start cypress
  • we don’t want to keep cypress in our project root folder
  • we don’t want to save videos on test success
  • we don’t want cypress assets to be saved on git

Nice commands to start cypress

Open your package.json and add to the scripts section:

"scripts": {
  "cypress:open": "cypress open",
  "cypress": "cypress run"
},

So you’ll be able to call npm run cypress to run the tests in the command line and npm run cypress:open to open the test runner UI.

Change some defaults

By default, cypress will get installed to our project root folder, in a sub-folder named cypress. I moved mine to react/spec/system.

Additionaly I’ve changed my configuration to not save videos on test success and I’ve added a default value for the baseUrl (you can read more configuration values in the configuration documentation).

For all these changes, we need to create a cypress.json file in our project folder with the the following content:

{
  "baseUrl": "http://localhost",
  "fixturesFolder": "react/spec/system/fixtures",
  "integrationFolder": "react/spec/system/integration",
  "pluginsFile": "react/spec/system/plugins/index.js",
  "screenshotsFolder": "react/spec/system/screenshots",
  "supportFile": "react/spec/system/support/index.js",
  "videosFolder": "react/spec/system/videos",
  "video": false
}

Don’t save cypress assets on git

I still kept the cypress default behavior to take screenshots of testing failure when running them in the command line.

But I don’t want to save the screenshots (or even videos, if temporarily enabled) on git. So edit your .gitignore and add these lines:

# Cypress test results assets
react/spec/system/screenshots/*
react/spec/system/videos/*

Write a simple test

If you want more background on this, visit the cypress Write Your First Test page.

Create a file react/spec/system/integration/sample_spec.js with the following content:

describe('My First Test', function() {
  it('Visits Home', function() {
    cy.visit('/')
  })
})

Note that we’re opening the / page, which will visit the baseUrl defined in cypress.json.

As you can guess, visit opens a URL. Check the cypress API commands documentation about all available commands. You can create custom commands in react/spec/system/support/commands.js file.

Now check if our simple sample is working with npm run cypress:open and see the magic happening!

Continuous Integration with Shippable

Now let’s configure our Continuous Integration. I like Shippable for that, but any other CI tool will have a similar setup.

Why I like Shippable? Their Hosted SaaS is easy to configure (just a shippable.yml in your project), it has free or affordable tiers, builtin support for GitHub and BitBucket and works like a charm.

Anyway, like I said, probably any other CI tool will have similar setup. You can check in cypress CI integration page recipes for Jenkins, TrevisCI, [CircleCI)(https://circleci.com) and several others.

This post is not about to teach how to setup Shippable, but, in a quick overview, for a first setup, you need to follow these steps to enable in your project:

  1. Enable a project
  2. Configure build triggers
  3. Build your shippable.yml

Now, assuming you have Shippable working with a node_js setup, let’s change the ci section of shippable.yml to add our cypress tests:

ci:

  # Redirect the output to `/dev/null` due long outputs freezing the build
  - npm install --quiet >> /dev/null

  # Starting app server
  - rails server -d

  # cypress specs
  - npm run cypress

You can see that I’m using Shippable with Ubuntu in a rails application. If you’re using a different OS with Shippable, change the apt-get line to match your OS package manager. You can replace the line to start the web server too (rails server -d) by your application server.