Extensions & Integrations

Automated functional browser tests are an important part of quality assurance for enterprise websites and web applications. This module provides a collection of conveniences for testing ApostropheCMS sites and applications within Cypress.
Upgrade your project
This is a premium module and requires a Pro license. More here.


ApostropheCMS logo

Cypress Tools for ApostropheCMS

Automated functional browser tests are an important part of quality assurance for enterprise websites and web applications. Cypress is an industry-standard, open-source library for carrying out automated functional browser tests. This module provides a collection of conveniences for testing ApostropheCMS sites and applications within Cypress.

Those conveniences include utilities to manage a test "starter" database (fixtures), create users, log in, log out, open various admin dialog boxes, and so on.

Read on to learn how to get started with the Cypress Tools.

Setup

  1. If you are new to Cypress you should visit the Getting Started section of the documentation and install and initialize Cypress for your Apostrophe application according to their instructions.

  2. In order to be able to reset your application state before each test, you need to install the MongoDB Tools for your operating system. You may have those installed already especially if you already have a local MongoDB server installation.

  3. Pre-populate a local instance of your site with an initial database that suits your tests. If you plan to use the addUser command in your scenarios, be sure that username does not already exist in the database you plan to provide.

If you need to reset your local database to be empty, you can use:

node app @apostrophecms/db:reset

⚠️ don't do this in production!

Then, prepare a dump of your application database in your project's cypress/apos-db folder:

mkdir -p cypress/apos-db
mongodump -d=yourDbName --archive=cypress/apos-db/default --gzip

yourDbName should be changed to match the value of shortName in your application app.js when you are running tests. The --gzip flag is mandatory.

We recommend committing this small mongodump file in git with your project.

  1. Install Cypress Tools for Apostrophe
npm install @apostrophecms-pro/cypress-tools --save-dev
  1. Integrate Cypress Tools for Apostrophe

Add the minimal required configuration to your cypress.config.js

{
  "baseUrl": "http://localhost:3000",
  "env": {
    "@apostrophecms-pro/cypress-tools": {
      "apiKey": "cypressAPIKey",
      "mongoURI": true,
      "dbName": "yourDbName"
    }
  }
}
const { defineConfig } = require('cypress');

module.exports = defineConfig({
  env: {
    '@apostrophecms-pro/cypress-tools': {
      apiKey: "myCypressAPIKey",
      mongoURI: true,
      dbName: "yourDbName"
    }
  },
  e2e: {
    baseUrl: 'http://localhost:3000',
    setupNodeEvents(on, config) {
      return require('./cypress/plugins/index.js')(on, config);
    }
  }
});

Make sure that you make the following changes to the above:

  • Set apiKey to your existing Apostrophe API Key with administration role or add new admin API key for your Apostrophe installation
  • Set mongoURI to a different value if you don't want to use a MongoDB instance on your own computer, without credentials
  • Change dbName to your project's database name (usually the same as shortName in app.js)

Next, open cypress/plugins/index.js and modify it like this:

// cypress/plugins/index.js
const { plugin } = require('@apostrophecms-pro/cypress-tools');

/**
 * @type {Cypress.PluginConfig}
 */
module.exports = (on, config) => {
  plugin(on, config);
  return config;
};

Open cypress/support/e2e.js and add:

require('@apostrophecms-pro/cypress-tools/commands');
  1. Add your first application test in cypress/e2e/it-works.cy.js:
// cypress/e2e/it-works.cy.js
describe('Apostrophe', () => {

  beforeEach(() => {
    cy.task('apos:dbReset');
    cy.addUser('admin').as('user');
  });

  it('it works', function () {
    // Login with role `admin`
    cy.login('admin');

    // Select and expand the user menu
    cy.getAdminBar()
      .contains('button', this.user.title)
      .click();

    // Find the Log Out expanded button 
    cy.contains('button', 'Log Out');
  });
});

Note: you might want to delete the auto-generated specs in cypress/integration first.

Running the tests

First, make sure your app is running so Cypress can talk to it. Leave npm run dev (if you have a dev task in package.json) or node app running in a separate terminal window.

Then type npx cypress open in your CLI OR add "cy:open": "cypress open" to your package.json scripts and run npm run cy:open in your CLI. Find the it-works test and click it. You can also directly run npx cypress run to run your tests in headless mode or create script "cy:run": "cypress run" in your package.json.

Configuration

Be sure to add at least baseUrl to your application cypress.config.js config.

The settings related to Cypress Tools for Apostrophe configuration should be found in the env.@apostrophecms-pro/cypress-tools namespace of your cypress.config.js config:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  env: {
    '@apostrophecms-pro/cypress-tools': {
      apiKey: "myCypressAPIKey",
      // Use "true" to use the local mongodb database
      // (you can point to an external mongodb provider here if needed)
      mongoURI: true,
      // Replace with your site's database name / shortName
      dbName: "yourDbName"
    }
  },
  e2e: {
    baseUrl: 'http://localhost:3000',
    setupNodeEvents(on, config) {
      return require('./cypress/plugins/index.js')(on, config);
    }
  }
});

Every configuration key (except profiles) can be set via Environment variable just by prefixing the given key with APOS_CYPRESS_. For example in the above configuration apiKey may be set (overridden) by environment variables APOS_CYPRESS_apiKey OR APOS_CYPRESS_API_KEY.

Configuration profiles

Cypress recommends using a combination of environment variables and configuration files to manage different environments and multiple sites. However, in the case of features as Apostrophe Assembly, tests do need multiple configurations to correctly manage the DB data, uploads, etc. Additionally, while an Assembly site can be tested in isolation, it always needs the dashboard database to be present.

The Profiles feature aims to solve this problem by allowing you to define multiple configurations in a single cypress.config.js file. Each profile can have its own set of configuration values, which can be overridden from the default configuration.

Here is an example of how to set up profiles in your cypress.config.js for a typical Apostrophe Assembly project:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  env: {
    '@apostrophecms-pro/cypress-tools': {
      assembly: true,
      apiKey: 'cypressAPIKey',
      mongoURI: true,
      dbName: 'test-j47k2538yhvy440spdlu8pti',
      aposRoot: './sites',
      profiles: {
        dashboard: {
          dbName: 'test-dashboard',
          aposRoot: './dashboard',
          baseUrl: 'http://dashboard.localhost:3000'
        },
        'site-demo': {
          dbName: 'test-ga5mh3pedr02ztdtzxn1mpi2',
          baseUrl: 'http://demo.localhost:3000'
        }
      }
    }
  },
  e2e: {
    baseUrl: 'http://default.localhost:3000',
    specPattern: 'cypress/tests/**/*.cy.{js,vue,ts}',
    setupNodeEvents(on, config) {
      return require('./cypress/plugins/index.js')(on, config);
    }
  }
});

In the above example, we have defined two profiles additionally to the default configuration: dashboard and site-demo. When no profile is specified for the commands that understand that option, the default configuration will be used. The default configuration in this case is set to a specific site. The dashboard and site-demo profiles are used to test the dashboard and site-demo sites respectively. The dashboard profile has a different dbName, aposRoot and baseUrl configuration than the default configuration. The site-demo profile differs only by dbName and baseUrl configuration. The profiles can be named (by convention) with the shortName of the site. All databases should have a dedicated DB dump file, usually named after the profile name, default for the default configuration.

The following configuration keys can be overridden in the profiles:

  • apiKey
  • aposRoot
  • mongoURI
  • dbName
  • baseUrl

Some of the commands and tasks that accept a profile option are:

  • addPiece
  • addPage
  • addUser
  • addImage
  • addFile
  • aposDeleteDocs
  • aposRequest
  • apos:dbReset
  • apos:dbUpdate
  • apos:dbFind

For a full list of commands and tasks that accept a profile option, see the API Reference.

Key Default Required Description
apiKey undefined No Your Apostrophe API key - test mode only, admin permissions advised, required for the REST API request commands such as addPiece and addPage
dbDumpFolder "cypress/apos-db" No A relative path to the gzipped mongodb dump profiles (see task apos:dbReset).
uploadDumpFolder "cypress/apos-uploads" No A relative path to the dumped public uploads profiles.
aposRoot . No A relative (to the current Cypress process path) leading to the Apostrophe application root. You'd want to set that if you change Cypress root: cypress run --project some/path.
mongoURI undefined No Set to true for default mongodb connection (mongodb://localhost:27017) or to any valid mongodb connection string. The true boolean option is not supported for environment overrides. You need to set this if you plan to use any database related commands or tasks.
dbName test No Your ApostropheCMS application database name - it should be the same as the shortName configuration value in your app.js. You need to set this if you plan to use any database related commands or tasks.
assembly false No Either you are using the tools as a single site (false) or as an Apostrophe Assembly project. Used to adapt behavior when detecting public upload paths.
profiles {} No An object, where keys are the profile name and values are objects containing one or more overrides of apiKey, aposRoot, mongoURI, dbName, and baseUrl default configuration values.

What's next

TODO - API reference, Contributor guide

Updated

1 month ago

Version

1.0.0-beta.19

Report a bug