Welcome to cypress-boilerplate 👋
Template for one or multiple products.
cypress-boilerplate
saves you from all of the trouble when configuring.
Table of contents
- Getting started
- Run
- How we use it
- Project flow
- Hygen part
- Reporting
- Build & Delpoy
- What's inside?
- Benefits of using this boilerplate project
- Summary
- 🤝 Contributing
- Show your support
- 📝 License
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 theproduct
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
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
orspecPattern
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!
📝 License
This project is MIT licensed.