Cypress is a next generation front end testing tool built for the modern web.

Instead of using an external listener, such as Selenium, which can be 'flaky' at times waiting for responses, Cypress has been built to run in the browser so it can more accurately monitor and react to requests. More information can be found at Cypress.io

The following will install Cypress, give some configuration and organization recommendations, and show how to persist sessions. Writing the tests is up to you! (Write your first test)


Install
In the base of your application, make a tests directory, and a cypress directory, as you may have or end up using other test suites
> mkdir tests/cypress
> cd tests/cypress

Simple npm install
> npm install cypress --save-dev

run Cypress
> npx cypress open

Official docs Install Cypress


Organization
While the install of Cypress creates an example skeleton directory
test/cypress/cypress
It is recommended to create your own directory 'just in case' a npm update decides to do 'something' with those skeleton directories.

create an app or unique name under
tests/cypress/[app_abbrev]
You can copy from
tests/cypress/cypress
or create the directories:

  • integration
where you write and run tests 
  • fixtures
static data for testing
  • plugins
enable you to modify or extend Cypress
  • screenshots
if taken, storage
  • support
loaded automatically before your test files ie global tests configuration
    • commands
additional grouping of common executed test steps
    • callbacks
additional grouping of callbacks which can modify the behaviors of tests


Configuration
Under
tests/cypress
create three config files,
cypress.json
cypress.env.json
cypress.env.json.example

cypress.json contains global configuration related to Cypress
Add your [app_abbrev] location to the config:
{
"fixturesFolder": "[app_abbrev]/fixtures",
"integrationFolder": "[app_abbrev]/integration",
"pluginsFile": "[app_abbrev]/plugins",
"screenshotsFolder": "[app_abbrev]/screenshots",
"supportFile": "[app_abbrev]/support"
}

cypress.env.json contains environment dependent configuration, such as user names for logins
You should create and maintain a
cypress.env.json.example
with the available config options too
An example config:
{
"web_base_url": "http://app.dev.localhost:8088/",
"login_username": "This email address is being protected from spambots. You need JavaScript enabled to view it.",
"login_password": "randchars"
}

Note, while Cypress does have a baseUrl config option that can be added to cypress.json, doing so does not allow the url to change per environment/developer/tester. If you are using a defined centralized test environment, or defined containers, then this should not be an issue. But to allow the url the app uses during testing to vary between environment/developer/tester, you can add and use your own base url by adding it to cypress.env.json

So instead of
Cypress.config().baseUrl
You would use
Cypress.env("web_base_url")


Support
The index.js in support is called on every run of a test.
This is where you can add global tests configuration and behaviors
Note, for easier maintenance, try to keep functionality to one file.

Update
tests/cypress/[app_abbrev]/support/index.js
to contain
import './commands/login_ui';

import './callbacks/stop_on_failure';
import './callbacks/preserve_session';

Support Commands
An example of a common executed test step may be to log in to your app.

Login UI
support/commands/login_ui.js
Create and add the minimal steps to log into your app, which may look similar to:
// https://on.cypress.io/custom-commands
Cypress.Commands.add("login_ui", (email, password) => {
// minimal info to login via ui
cy.visit(Cypress.env("web_base_url"));
cy.url().should("include", "[app_abbrev]");

let el = cy.get('#login_form [name="username"]');
el.type(Cypress.env("login_username"));

el = cy.get('#login_form [name="password"]');
el.type(Cypress.env("login_password"));

el = cy.get('#login_submit');
el.click();
});

Note, instead of using your apps ui to log in for every test, you should create a token or api access to expedite the test

Now you can call the command using one consistent statement

describe("Select that Awesome Thing Test", () => {
describe("Can Login", () => {
it("Can login", () => {
cy.login_ui(Cypress.env("login_username"), Cypress.env("login_password"));
});
});
});

Support Callbacks/Behaviors

Stop on Failure:
support/callbacks/stop_on_failure.js
When on step of a test fails, it will often cause the next steps to fail.
So fail early so the problem can be found quicker.
Create and add
// after each test
// stop test after first failure
afterEach(function () {
if (this.currentTest.state === 'failed') {
Cypress.runner.stop()
}
});

Preserve Sessions:
support/callbacks/preserve_session.js
All tests are supposed to be isolated, so Cypress will often clean up your cookies.
While it would be nice if the cleanup happens after the first test, or the last test in a suite, the clean up will happen after a few tests, which can log you out of your app and make it seem like your app or the test are broken.
To persists your session, which is often stored in a session cookie, create and add:
// once before all tests
// preserve session cookie so don't get 'randomly' logged out after several specs
before(function () {
Cypress.Cookies.defaults({
preserve: ['your_sessionid_name']
});
});


Package.json
While you can run Cypress via
> npx cypress open

You can also add a more common alias to your package.json
"scripts": {
"test": "npx cypress open"
},

And run Cypress via
> npm run test


.gitignore
Update your .gitignore
/tests/cypress/node_modules
/tests/cypress/cypress
/tests/cypress/cypress.env.json


Hopefully the above information helps you setup and use Cypress in a more enjoyable and useful fashion.


-End of Document-
Thanks for reading