End to End Tests

Cypress, a JavaScript based framework, is used for end to end (E2E) testing. Tests and associated utilities are within the cypress directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ tree cypress

cypress
├── fixtures
│   ├── images
│   │   └── admin-image.png
│   └── users
│       ├── adminUser.json
│       └── changePasswordUser.json
├── integration
│   ├── adminFlows
│   │   └── config
│   │       └── authenticationSection.spec.js
│   └── loginFlows
│       ├── userChangePassword.spec.js
│       └── userLogin.spec.js
├── plugins
│   └── index.js
└── support
    ├── commands.js
    └── index.js

In addition to Cypress, we use cypress-testing-library. This provides custom Cypress commands and utilities to improve how E2E tests are written. dom-testing-library and preact-testing-library are already used for front-end tests, which both offer a similar API in the context of testing a Preact or Stimulus component. All these tools are part of the Testing Library family.

For the test web server, the cypress-rails gem is used to start a test web server that runs a rails test environment (RAILS_ENV=test). It also resets the database between test runs by starting a database transaction at the beginning of a test and performs a rollback at the end of a test being run. The cypress-rails gem also provides a rake task that allows us to coordinate all this work.

Running E2E Tests Locally

From the command line, run yarn e2e to start E2E testing.

  1. bundle check will run to ensure all the gems for the project are up to date. If they are not, you will be prompted to run bundle install.
1
2
3
4
5
Doing a quick bundle check to make sure gems are all up to date.

 * zonebie (0.6.1)
Install missing gems with `bundle install`
Unable to launch end to end tests. Ensure that all your gems are installed and up to date.
  1. yarn install will run to ensure front-end packages are up to date.
1
2
3
[1/5] 🔍  Validating package.json...
[2/5] 🔍  Resolving packages...
success Already up-to-date.
  1. You will be prompted to set up the end to end (E2E) test database. Type y or Y to install the E2E test database. Typically you only need to select y the first time you run e2e tests, but it can also be run if ever you corrupt your database and need to reset it back to its original state.
1
2
3
Do you need to set up your end to end (E2E) testing database? Answer yes
if this is your first time running E2E tests on your local machine or you
need to recreate your E2E test database. (y/n)
  1. If y or Y is pressed, the E2E test database will install.
1
2
3
4
5
6
7
Setting up the E2E database before running E2E tests...


Dropped database 'PracticalDeveloper_test'
Created database 'PracticalDeveloper_test'

...
  1. The Cypress test runner will open and you are now ready to run end to end tests.

A screenshot of the Cypress test runner

E2E Tests on CI/CD

E2E tests run on a dedicated build node on Travis. It runs headless via the bin/e2e-ci command. These tests currently do not run in parallel with Knapsack Pro as there were issues integrating the cypress-rails gem with the knapsack-pro-cypress npm package.

Cypress Custom commands

Cypress custom commands allow you to extend the functionality of the E2E testing framework. In the case of Forem, we need custom commands to create an article, for example.

A custom command is prefixed like any Cypress command by cy. All custom commands can be found in the commands.js file.

Creating a Custom Article Command

To create an article as part of your test's setup, use the cy.createArticle custom command. It can be called like so:

1
2
3
4
5
cy.createArticle({
  title: 'Test Article',
  tags: ['beginner', 'discuss'], // tags are optional
  content: 'This is a test article',
});

If you want to do something with the article creation's response, you can call it like so.

1
2
3
4
5
6
7
cy.createArticle({
  title: 'Test Article',
  tags: ['beginner', 'discuss'], // tags are optional
  content: 'This is a test article',
}).then((response) => {
  cy.visit(response.body.current_state_path); // path to article
});

Creating a Response Template Command

To create a response template as part of your test's setup, use the cy.createResponseTemplate custom command. It can be called like so:

1
2
3
4
cy.createResponseTemplate({
  title: 'Test Canned Response',
  content: 'This is a test canned response',
});

Additional Resources