Modern web systems often require users to login first and then allow those, who are login successfully, start to use. If these systems are built with concept of single page application, it’s good to try Cypress for automatic UI end-to-end testing. The login is first one need to be solved for Cypress testing.
Notice: The content of this article has been tested at cypress version 5.6.0, 6.2.0, angular version 6.1.10, 7.1.10 and 7.2.4
Cypress recommends login feature need to be tested separately from other features of to-be-tested web system. “Fully test the login flow, but only once!" Other features will use necessary things that login flow provide for accessing API such as secret token, credential, resource identifiers, ……etc.
You often use account and password to login modern web system. If you use recaptcha v2
as anti-spam mechanism for robots, you need to use its well-known settings for testing login flow and test environments.
Site key: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
Secret key: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
Notice: You should put site key at environment setting of frontend framework and secret key to backend framework/service.
Since now, You can start to test your login and logout flow for your modern web system, which is built by single page application concept.
After you can success go through whole login and logout UI end-tot-end testing flow, let’s get started to test major part of features of your modern web system.
Before we start to test UI end-to-end testing about a feature, I recommend you to check and decide to prepare necessary things before starting test such as creating commands for localStorage and necessary data at localStorage.
If you wish run a setup once for the whole testing procedure, cypress recommends you put related things under cypress/support
directory and import them to the file cypress/support/index.js
.
Due to Cypress doesn’t have native-supported and easy commands for localStorage store and recovery , we can create our own. From this workaround from github cypress, we can create following in file: cypress/support/commands.js
.
let LOCAL_STORAGE_MEMORY = {};
Cypress.Commands.add("saveLocalStorage", () => {
Object.keys(localStorage).forEach((key) => {
LOCAL_STORAGE_MEMORY[key] = localStorage[key];
});
});
Cypress.Commands.add("restoreLocalStorage", () => {
Object.keys(LOCAL_STORAGE_MEMORY).forEach((key) => {
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
});
});
Inside cypress/support/index.js
, you can provide login flow without login-UI component interaction. Based on this content in cypress/support/index.js
, features with UI interaction, which are you want to test for web system, can simply be focused on core part for testing.
Sample content of cypress/support/index.js
:
/**
* import commands.js herem even you don't use its commands in this file, these commands still can be used in UI-feature end-to-end testcases.
*/
import "./commands";
let token = "";
before(function fetchToken() {
// prepare access token if the system requires
/**
* Notice: If the system's access token is needed to preserve at cookie with related name, you can use Cypress.Cookies.defaults() such as below.
*/
Cypress.Cookies.default({
preserve: ["YOUR_ACCESS_TOKEN"],
});
// send request to login API
cy.request({
method: "POST",
url: "YOUR_TEST_API",
body: {
/**
* Change YOUR_ACCOUNT_FIELD and YOUR_PASSWORD_FIELD to fit your need.
* And we will describe how to load values of environment variables for cypress. You can put values to cypress.json in your web project's home directory
*/
YOUR_ACCOUNT_FIELD: Cypress.env("YOUR_ACCOUNT_ENV_NAME"),
YOUR_PASSWORD_FIELD: Cypress.env("YOUR_PASSWORD_ENV_NAME"),
},
enconding: "utf8",
}).then((resp) => {
token = resp.body["data"];
// set received token to cookie's related attribute name
cy.setCookie("YOUR_ACCESS_TOKEN", token);
/**
* save necessary and related things to localStorage
* The following are examples:
* 1. account
* 2. FCM device id
* 3. push token
* 4. Nebular auth token
* 5. Cached user data
*/
// account name at localStorage
cy.fixture("localStorage/account_name.txt").then((content) => {
localStorage.setItem("account", content);
});
// FCM device id at localStorage
cy.fixture("localStorage/fcm_device_id.txt").then((content) => {
localStorage.setItem("fcm_device_id", content);
});
// push token at localStorage
cy.fixture("localStorage/push_token.txt").then((content) => {
localStorage.setItem("push_token", content);
});
// Nebular auth token at localStorage
cy.fixture("localStorage/nebular_auth_token.json").then((content) => {
localStorage.setItem("nebular_auth_token", JSON.stringify(content));
});
// cached user data at localStorage
cy.fixture("localStorage/cached_user_data.json").then((content) => {
localStorage.setItem("user", JSON.stringify(content));
});
});
});
Value inside files' name suffixed .txt
under cypress/fixtures
folder must be double quoted. Content inside files' name suffixed .json
under cypress/fixtures
folder must be formatted as Javascript’s object.
cypress/fixtures
folder can be put files with content whose are predefined and used for automatic testings. You can put data into separated files for easily management and these data can be used in the process of a single test case or multiple test cases. In above example, we put data needed by login flow in cypress/fixtures
folder and data is loaded by cypress/support/index.js
.
Examples:
Content of cypress/fixtures/localStorage/account_name.txt
:
"user"
Content of cypress/fixtures/localStorage/fcm_device.txt
:
"123456-1234134abcdefg1234-4321123"
Content of cypress/fixtures/localStorage/push_token.txt
:
"qwerqerqwer:eqwqeqerqwdsfsdfwqersfd"
Content of cypress/fixtures/localStorage/nebular_auth_token.json
:
{
"ownerStrategyName": "account",
"value": "abc3345678",
"createdAt": 12345678912,
"name": "abc123456"
}
Content of cypress/fixtures/localStorage/cached_user_data.json
:
{
"name": "normal person",
"updateTime": "2018-01-01T01:00:00.123Z"
}
Cypress has predefined values for settings. If you want to change some values for fitting need of your modern web system, you put related ones at file: cypress.json
. cypress.json
file is usually at home directory of your web system project at development environment.
Following are sample content:
{
"baseUrl": "https://localhost", // your testing site for cypress
"env": {
/**
* This section can be loaded by Cypress.env() with attribute name.
*/
"YOUR_ACCOUNT_ENV_NAME": "abc", // you can change attribute name and value to fit your need.
"YOUR_PASSWORD_ENV_NAME": "123" // you can change attribute name and value to fit your need.
},
/* clean assets within folders set by setting: `downloadsFolder`,
`screenshotsFolder` and `videosFolder` before tests run with command: `cypress run`, */
"trashAssetsBeforeRuns": true,
"video": true, // capture a video when running a test with command: `cypress run`,
"scrollBehavior": "center" // make an element to be centered at viewport during process of testing
}
From cypress support typescript environment, you can follow instructions at that link.
If you still want to write js testcases in typescript environment, you can create tsconfig.json
file under cypress
folder and put following sample content in tsconfig.json
:
{
"compilerOptions": {
"allowJs": true,
"types": ["cypress"]
},
"include": ["**/*.*"]
}
Setup for feature testing is complete
You can start to create your feature test cases now, cypress recommends you put them under cypress/integration
folder. It’s recommended organize test cases under cypress/integration
folder, this means you can create subfolders under that folder.