Skip to content

optimumqa/cypress-boilerplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Welcome to cypress-boilerplate πŸ‘‹

Quickly generate new projects, and start coding immediately with an already pre-configured project. While using this boilerplate you and your team can focus more on coding, and less wory about configuration. This boilerplate is full of useful plugins already configured, and much more! Good luck!

Release new version MIT

Cypress Mocha Typescript Javascript

Template for one or multiple products.
cypress-boilerplate saves you from all of the trouble when configuring.

Table of contents

Getting started

Installation

npx @optimumqa/cypress-boilerplate my-cypress-app

Install dependencies:

cd my-cypress-app
npm install

Add a new product

product refers to your project.

$ npm run add-project

It will ask you for your:

  • product name
  • baseUrl

The command from above would create the following structure and inject new scripts in package.json.

- configs/
  - foo/
    default.ts
- fixtures/
  - foo/
    - routes.json
    - users.json
- e2e/
  - foo/
    - default.cy.ts
- support/
  - foo/
    - commands.ts
    - index.ts

Run

$ npm run foo-staging

You can see that the generator has injected 3 default scripts into package.json

{
  ...
  "scripts": {
    "foo-staging": "cypress run -e product=foo,env=staging",
    "foo-release": "cypress run -e product=foo,env=release",
    "foo-production": "cypress run -e product=foo,env=production",
  }
  ...
}

When run, it will specify only the test files in cypress/e2e/foo.

How we use it

Follow all the steps above then:

Add a new command to scripts

// package.json
{
  ...
  "scripts": {
    ...
    "test": "npm run foo-staging"
    ...
  }
  ...
}

Then simply run:

$ npm test

When tests is finished, your reports will be generated also. Keeps the command line clean and simple.

Structure explained

configs/product

Here you can have different cypress configs per product. Which config is used is determined by the type argument while running cypress in the CLI.

For example if we add the following command to our package.json

{
  ...
  "foo-staging-daily: cypress open --env product=foo,env=staging,type=daily"
  ...
}

and then run it

$ npm run foo-staging-daily

then configs/foo/daily.ts is used and merged with ./cypress.config.ts.

This gives you an extra level of configuration for different test types where you need to target only specific spec files, all while keeping the package.json scripts part clean

fixtures/foo/routes.json

Here is the place to define your baseUrl and other URLs per each environment.

Preview

{
  "staging": {
    "baseUrl": "https://example.com",
    "admin": "https://example.com/admin"
  },
  "release": {
    "baseUrl": "https://example.com"
  },
  "production": {
    "baseUrl": "https://example.com"
  }
}

Usage:

import { routes } from '../../../support/helpers'

describe('Should visit admin', () => {
  it('Visit', () => {
    cy.visit(routes.admin)
  })
})

routes will always return routes from current set environment, which in this case, is staging.

fixtures/foo/users.json

Here is the place to define your primary, seconday, etc. users list for your tests.

By default, you can see

Preview

{
  "staging": {
    "primary": {
      "name": "User name",
      "email": "test@cypress_template_test.com",
      "password": "user password"
    }
  },
  "release": {
    "primary": {
      "name": "User name",
      "email": "test@cypress_template_test.com",
      "password": "user password"
    }
  },
  "production": {
    "primary": {
      "name": "User name",
      "email": "test@cypress_template_test.com",
      "password": "user password"
    }
  }
}

Usage:

import { routes, users } from '../../../support/helpers'

describe('Should visit admin', () => {
  it('Visit and log in with primary user', () => {
    cy.visit(routes.admin)
    cy.logIn(users.primary)
  })
})

users will always return users from current set environment, which in this case, is staging.

cypress/e2e/foo/

Here are your spec files as usual.

cypress/support/e2e/foo/

Your projects commands are here.

If you have multiple projects, keep in mind that you will have access only to the commands from the project you've run in the CLI. This is done so that commands from multiple products do not override each other if they're the same name.

cypress/support/e2e/commands.ts

Here are your global/shared commands.

cypress/support/helpers.ts

You can import current users or routes from this file. It will give you the routes from the specified product and from the specified environment.

import { users, routes } from '../../helpers'

describe('Example usage of helpers module', () => {
  it('Should log current main user and baseUrl', () => {
    cy.log(users.main) // object
    cy.log(users.main.email) // random email generated every time you run Cypress
    // This ensures your concurent jobs wont use the same user every run
  })
})

You can also import other stuff like this:

import { product, env, type, baseUrl, getFixture, getUrl } from '../../helpers'

describe('Example usage of helpers module', () => {
  it('Should do something', () => {
    // These below helpers are pre-configured to look for directoris depending on your current setup/run
    // Below example shows what would be logged if you've run the project with "npm run foo-staging"
    // And you've set the baseUrl to "http://foo.example.com"

    cy.log(product) // foo
    cy.log(env) // staging
    cy.log(type) // default
    cy.log(baseUrl) // http://foo.example.com
    cy.log(getFixture('foo')) // JSON Object
    cy.log(getUrl('baseUrl')) // http://foo.example.com
  })
})

Local config

Create a file cypress.local.ts inside ./cypress/configs/. Your local config will be then merged with the global config and product config.

Here you can place your overrides.

If you need to temporarily disable this file, just rename it. Example: cypress.local.ts -> cypress.local-tmp.ts

It is ignored by GIT.

Project flow

Adding new custom commands to package.json

Arguments

name type default description
product String Product name
env String staging Any environment you support
type String default Used for targeting specific config inside configs/product/. Daily, weekly, smoke, you name it.

Follow the command naming convention

  • product+environment+type

Here are some example commands:

{
  "scripts": {
    "foo-staging": "cypress run -e product=foo,env=staging",
    "foo-staging.open": "cypress open -e product=foo,env=staging",
    "foo-master-daily": "cypress run -e product=foo,env=master,type=daily",
    "foo-staging-weekly": "cypress run -e product=foo,env=staging,type=weekly"
  }
}

There is no need to specify specPattern. If they're are not specified they'll be automatically set(depending on the product from CLI).

Reporting

Two reporters are enabled

Mochawesome

Location: cypress/reports/mochawesome

Reports will only be generated with the command:

npm run mocha.combine-reports
npm run mocha.generate-reports

Make sure to clear previous reports before running your tests with the command:

npm run mocha.clear

Allure

Location: allure-results

Report will be created automatically if you have allure: true inside your cypress.config.js.

To view the latest report you can run

npm run allure.start

To preserve the history trend, run:

Be careful not deleting the allure-results/history when preserving it.

npm run allure.report
npm run allure.history

Then start the allure

npm run allure.start

What's inside?

Here is a list of plugins and libraries that come with this boilerplate:

Prettier

Keeps the code clean and same style for everyone working on the project. Make sure you have the prettier extension installed in VSCode for it to work.

Modify the config in ./.prettierrc

cypress-iframe

See the documentation.

You can use the commands like described here

cypress-localstorage-commands

See documentation.

Example usage:

beforeEach(() => {
  cy.restoreLocalStorage()
  cy.visit('/')
})

afterEach(() => {
  cy.saveLocalStorage()
})

Benefits of using this boilerplate project

No configuring the project

With a clean, intuitive, and same project structure we keep everyone consistent across all projects.

Renovate

Delete renovate.json if you don't use it.

Hygen part

Hygen is used to generate templates and inject code into your structure when running npm run add-project.

You can modify the generator in ./_templates/project/with-prompt/.

If you need to change default environments, they're declared in these files:

  • ./_templates/project/with-prompt/fixtureRoutes.ejs.t
  • ./_templates/project/with-prompt/fixtureUsers.ejs.t
  • ./_templates/project/with-prompt/package.ejs.t

Summary

  • Project is dynamically set up based on the three arguments above
  • If you specify baseURL or specPattern in configs, they will not be overwritten.
  • We can't imagine to work without this template, and hope you will feel the same :)

🀝 Contributing

Contributions, issues and feature requests are welcome.
Feel free to check issues page if you want to contribute.

Show your support

Please ⭐️ this repository if this project helped you!

Stargazers
Forkers

πŸ“ License

This project is MIT licensed.