Cypress integration
Preface
Using the Cypress commands provided by the package @mocks-server/cypress-commands you'll be able to change the current collection
of Mocks Server or change any other server settings simply using a Cypress command. This means that you can develop solid tests, without the dependency of the real API, because you can control in every moment the responses that the API will return to your web page.
You'll be able to develop Cypress tests for error cases, slow requests and many other cases that are very hard to reproduce with a real API, with the advantage that you could reuse the same mock while you are developing the application, because in that case you can control it using any of the other integration tools, such as the interactive CLI.
Installation
This module is distributed via npm and should be installed as one of your project's devDependencies:
npm i --save-dev @mocks-server/cypress-commands
Registering commands
@mocks-server/cypress-commands
extends Cypress' cy commands.
At the top of your Cypress' support file (usually cypress/support/e2e.js
for e2e
testing type):
import { register } from "@mocks-server/cypress-commands";
register();
Read Cypress configuration docs for further info.
Registering commands in Cypress lower than 10.0
Add these lines to your project's cypress/support/index.js
:
import { register } from "@mocks-server/cypress-commands";
register();
Cypress Commands
cy.mocksSetCollection()
Set current collection:
cy.mocksSetCollection("admin-user");
cy.mocksUseRouteVariant()
Use specific route variant:
cy.mocksUseRouteVariant("get-users:error");
cy.mocksRestoreRouteVariants()
Restore route variants to those defined in current collection:
cy.mocksRestoreRouteVariants();
cy.mocksSetDelay()
Set delay time:
cy.mocksSetDelay(2000);
cy.mocksSetConfig()
Set any other configuration option:
cy.mocksSetConfig({
files: {
watch: false,
},
mock: {
routes: {
delay: 0,
},
collections: {
selected: "get-users-error"
},
},
});
cy.mocksConfigClient()
Configures the Mocks Server administration API client, used under the hood to communicate with the administration REST API.
configuration
<Object>
- It must be an object containing any of next properties:enabled
<Boolean>
- Enables or disables the API client.port
<Number>
- Changes the API client port.host
<String>
- Changes the API client host.https
<Boolean>
- Iftrue
, changes the client protocol to "https". Default isfalse
. Read "enabling HTTPS" for further info.
cy.mocksConfigClient({
port: 3110,
host: "127.0.0.1"
enabled: true,
https: true,
});
Example
describe("books page", () => {
describe("when there are two books", () => {
before(() => {
cy.mocksSetCollection("two-books"); // Use "two-books" collection
cy.visit("/");
});
it("should display two books", () => {
cy.get("#books li").should("have.length", 2);
});
});
describe("when there is an error loading data", () => {
before(() => {
cy.mocksUseRouteVariant("get-books:error"); // Use "get-books:error" route variant
cy.visit("/");
});
after(() => {
cy.mocksRestoreRouteVariants(); // Restore mock route variants after the test
});
it("should display error message", () => {
cy.get("#books .error").should("exist");
});
});
describe("when the API is slow", () => {
before(() => {
cy.mocksSetDelay(3000); // Set a delay of 3 seconds in API responses
cy.visit("/");
});
after(() => {
cy.mocksSetDelay(0); // Restore the delay to 0
});
it("should display loading", () => {
cy.get("#books .loading").should("exist");
});
it("should display two books", () => {
cy.get("#books li").should("have.length", 2);
});
});
});
Configuration
By default, the API client is configured to request to http://127.0.0.1:3110/api
, based in the default Mocks Server Plugin Admin Api options
Use next settings only if you changed the administration API configuration and you need to configure the client properly, or in case you also need to run your tests without starting the Mocks Server.
You can change both the host and port of the administration API using the cy.mocksConfigClient
command mentioned above, or the plugin environment variables:
MOCKS_SERVER_LOGS
: Log commands status on Cypress or not. Default istrue
.MOCKS_SERVER_ADMIN_API_PORT
: Modifies the admin API client port. Default is3110
.MOCKS_SERVER_ADMIN_API_HOST
: Modifies the admin API client host. Default is127.0.0.1
.MOCKS_SERVER_ADMIN_API_HTTPS
: Iftrue
, changes the admin API client protocol to "https". Default isfalse
. Read "enabling HTTPS" for further info.MOCKS_SERVER_ENABLED
: Disables requests to the Mocks Server admin API, so the commands will not fail even when Mocks Server is not running. This is useful to reuse same tests with a mocked API and a real API, because commands to change Mocks Server configuration will be ignored.
Note: These environment variables only affect to the default Mocks Server API client (except
MOCKS_SERVER_LOGS
). Read usage with multiple Mocks Servers bellow for further info.
Starting the application, Mocks Server and Cypress
For running tests, you'll need to start your application configured to make requests to the Mocks Server url, start Mocks server, and only then, start the execution of Cypress.
We recommend the usage of the start-server-and-test
package to start all needed dependencies before running tests.
The next example is based on a create-react-app
application which is using the REACT_APP_BASE_API
environment variable to set the api url:
{
"scripts": {
"mocks:ci": "mocks-server --no-plugins.inquirerCli.enabled",
"start": "REACT_APP_BASE_API=http://localhost:3100 react-scripts start",
"mocks:ci-and-start": "start-server-and-test mocks:ci tcp:3100 start",
"cypress:run": "cypress run",
"test": "start-server-and-test mocks:ci-and-start http-get://localhost:3000 cypress:run",
}
}
Now, when running npm run test
, Mocks Server will be started without the interactive CLI, then the application will be started configured to make requests to the Mocks Server url, and then the Cypress tests will be executed.
Usage with multiple Mocks Servers
This package can be used also to control multiple Mocks Server processes. All commands described above support passing an extra argument, which can be a different AdminApiClient
instance configured in a different way. When the commands receive a AdminApiClient
instance, it uses its configuration to perform requests to the Mocks Server administration API client instead of the default one.
Note that changing the plugin environment variables values don't affect to custom API clients created this way, so, if you want to configure them using environment variables you'll have to use your own.
AdminApiClient(configuration)
Returns a new Mocks Server Admin API client to be provided to this plugin's Cypress commands, so they use that client instead of the default one. Configuration options are the same than described for the cy.mocksConfigClient
command:
configuration
<Object>
- Optional (configuration can be changed also afterwards using thecy.mocksConfigClient
command and passing the client to be configured). It should be an object containing any of next properties:enabled
<Boolean>
- Enables or disables the API client.port
<Number>
- Changes the API client port.host
<String>
- Changes the API client host.https
<Boolean>
- Iftrue
, changes the client protocol to "https". Default isfalse
. Read "enabling HTTPS" for further info.
Commands API when using a custom client
cy.mocksSetCollection("users-error", adminApiClient)
- Set current collection using the provided client.cy.mocksUseRouteVariant("users:success", adminApiClient)
- Set a specific route variant using the provided client.cy.mocksRestoreRouteVariants(adminApiClient)
- Restore route variants using the provided client.cy.mocksSetDelay(2000, adminApiClient)
- Set routes default delay using the provided client.cy.mocksSetConfig(mocksServerConfiguration, adminApiClient)
- Set any Mocks Server setting using the provided client.cy.mocksConfigClient(clientConfiguration, adminApiClient)
- Configures the provided admin API client.
Example
import { AdminApiClient } from "@mocks-server/cypress-commands";
const usersApiClient = new AdminApiClient({
port: 3500,
host: "127.0.0.1"
});
const gravatarApiClient = new AdminApiClient({
port: 3200,
host: "localhost"
});
describe("users page", () => {
describe("When normal user is logged in and gravatar API does not work", () => {
before(() => {
cy.mocksSetCollection("normal-user", usersApiClient);
cy.mocksSetCollection("server-error", gravatarApiClient);
cy.visit("/");
});
it("should not see the users section link", () => {
cy.get("#users-section-link").should("not.be.visible");
});
it("should not display user avatars", () => {
cy.get(".user-avatar").should("not.be.visible");
});
});
});
Usage with TypeScript
For those writing TypeScript tests in Cypress, the package includes TypeScript declarations.
Add "@mocks-server/cypress-commands" to the types
property in the tsconfig.json
file. You may also need to set the TS allowSyntheticDefaultImports
option to true:
{
"compilerOptions": {
"types": ["cypress", "@mocks-server/cypress-commands"],
"allowSyntheticDefaultImports": true
}
}
Or reference the package in the files using it:
/// <reference types="@mocks-server/cypress-commands" />
Enabling HTTPS
The Mocks Server administration API supports enabling the HTTPS protocol. When it is enabled, the API client of this plugin must be configured properly in order to be able to connect.
First, use the MOCKS_SERVER_ADMIN_API_HTTPS
environment variable or the cy.mocksConfigClient
command to enable HTTPS in the client:
- cypress.json
- cypress.config.js
- Cypress command
{
"env": {
"MOCKS_SERVER_ADMIN_API_HTTPS": true,
}
}
const { defineConfig } = require('cypress')
module.exports = defineConfig({
env: {
MOCKS_SERVER_ADMIN_API_HTTPS: true,
}
})
cy.mocksConfigClient({
https: true,
});
Then, you'll probably also need to provide the Admin API SSL/TLS certificate file paths to Cypress, otherwise the requests could be rejected. Provide the same certificate that you provided to the AdminApi plugin for enabling HTTPS:
- cypress.json
- cypress.config.js
{
"clientCertificates": [
{
"url": "https://127.0.0.1",
"ca": [],
"certs": [
{
"cert": "certs/cert.pem",
"key": "certs/key.pem"
}
]
}
]
}
const { defineConfig } = require('cypress')
module.exports = defineConfig({
clientCertificates: [
{
url: "https://127.0.0.1",
ca: [],
certs: [
{
cert: "certs/cert.pem",
key: "certs/key.pem"
}
]
}
]
})
Read the "Enabling HTTPS" guide for further info about enabling HTTPS in the administration API