Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/maximilianschmitt/cypress-routines
Easily write scalable Node.js setup code for Cypress
https://github.com/maximilianschmitt/cypress-routines
cypress integration-testing nodejs testing
Last synced: 2 months ago
JSON representation
Easily write scalable Node.js setup code for Cypress
- Host: GitHub
- URL: https://github.com/maximilianschmitt/cypress-routines
- Owner: maximilianschmitt
- License: mit
- Created: 2020-10-22T16:29:23.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2020-10-29T20:59:48.000Z (about 4 years ago)
- Last Synced: 2024-10-15T04:44:58.353Z (3 months ago)
- Topics: cypress, integration-testing, nodejs, testing
- Language: JavaScript
- Homepage:
- Size: 261 KB
- Stars: 44
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Easily write scalable Node.js setup code for Cypress---
![CI Badge](https://github.com/maximilianschmitt/cypress-routines/workflows/CI/badge.svg)
[![npm weekly downloads Badge](https://badgen.net/npm/dw/cypress-routines)](https://www.npmjs.com/package/cypress-routines)# cypress-routines
## Motivation
`cy.task()` allows Cypress users to run code in a Node.js process.
However, all Cypress tasks run in a global namespace and as your app and number of different test setups grow, relying on `cy.task()` for test setups can become hard to maintain.`cypress-routines` enables you to organize your test setups neatly per spec-file. Routines run in Node.js, so you can easily access things like databases and file systems in your test setups.
## Screencast
Using cypress-routines to write and organize test setups that run in Node.js## Installation
### 1. Install cypress-routines
```bash
# With yarn:
yarn add cypress-routines --dev# With npm:
npm install cypress-routines --save-dev
```### 2. Require plugin-file
In `cypress/plugins/index.js`:
```js
module.exports = async (on, config) => {
const db = await connectDb() // 👈 Example// After `on, config`, you can pass e.g. db 👇
require('cypress-routines/plugin')(on, config, db)
}
```### 3. Require support-file
In `cypress/support/index.js`:
```js
require('cypress-routines/support')
```### 4. Ignore \*.routines.js
In `cypress.json`:
```json
{
"ignoreTestFiles": ["*.routines.js"]
}
```## Usage guide
- [Where do I put my routines?](#where-do-i-put-my-routines-)
- [Writing routines](#writing-routines)
- [Giving routines access to the database](#giving-routines-access-to-the-database)
- [Calling routines](#calling-routines)
- [Sharing routines across spec-files](#sharing-routines-across-spec-files)
- [Global routines](#global-routines)
- [Sharing routine functions](#sharing-routine-functions)### Where do I put my routines?
Routines live next to their respective spec-file:
```
cypress/
integration/
login.spec.js
login.routines.js
signup.spec.js
signup.routines.js
```You can also define [global routines](#global-routines).
### Writing routines
A routines-file is a simple node.js module that exports a factory-function that returns an object with functions ("routines") attached to it:
```js
// cypress/integration/login.routines.jsfunction loginRoutines(db) {
return {
createUser(user) {
await db.collection('users').insertOne(user)return user
}
}
}module.exports = loginRoutines
```The return-value of the routine will be accessible from the spec-file in the browser context, so it must be JSON-serializable.
The `createUser` routine from `login.routines.js` can be used from `login.spec.js` like so:
```js
cy.routine('createUser', { email: '...' }).then(() => {
// ...
})
```### Giving routines access to the database
In your Cypress plugin-file, pass the `db` (or any other parameters you like) after `on, config` to the function that's required as `cypress-routines/plugin`.
```js
// cypress/plugin/index.jsmodule.exports = async (on, config) => {
const db = await connectDb()// All arguments after `on, config` are passed along
// to the routine-factories. In this case, we're passing
// `db` so that every routines-file can access the db
// if it needs to.
require('cypress-routines/plugin')(on, config, db, param2, param3 /* etc. */)
}
```The factory-functions in your routines files now have access to those params.
```js
// cypress/integration/login.routines.jsfunction loginRoutines(db, param2, param3 /* etc. */) {
return {
// ...
}
}module.exports = loginRoutines
```### Calling routines
Routines are called with `cy.routine(routineName: string, routineArg?: any)`. A routine can optionally take a single argument (must be JSON-serializable).
```js
// cypress/integration/login.spec.jsit('logs in the user', function () {
const routineArg = {
email: '[email protected]',
hashedPassword: hashPassword('123456'),
}cy.routine('createUser', routineArg).then(() => {
cy.visit('login')
// ...
})
})
````a.spec.js`, can only call routines defined in `a.routines.js` (not `b.routines.js`).
`cy.routine()`, like other Cypress commands, is asynchronous but cannot be used with async/await. Read here for [more info on async commands](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous).
### Sharing routines across spec-files
Routines are scoped to their spec-files. For 95% of cases, this is what you want because it introduces clean separations between test-setups and makes it easy to find a routine that is used in a certain spec-file.
In some cases, you might want to reuse certain routines. There are two options for this:
- Global routines
- Sharing routine functions### Global routines
Global routines can be defined in `cypress/integration/global-routines.js`. The global routines-file looks like any other routines-file:
```js
// cypress/global-routines.jsfunction globalRoutines(db) {
return {
async createDefaultUser() {
const defaultUser = {
email: '[email protected]',
hashedPassword: hashPassword('123456'),
}await db.collection('users').insertOne(defaultUser)
return defaultUser
},
}
}module.exports = globalRoutines
```Global routines are called like regular routines, but with a leading `'/'`:
```js
// cypress/integration/login.spec.jsit('logs in the user', function () {
// 👇 Leading '/'
cy.routine('/createDefaultUser').then((testUser) => {
cy.visit('login')
// ...
})
})
```### Sharing routine functions
You can always require other routines-files from any routines-file. You can then re-use and re-export functions with normal JavaScript:
```js
// cypress/integration/login.routines.js// Either export an entire other routines-file:
module.exports = require('./homepage.routines.js')// Or export single functions:
module.exports = (db) => {
const homepageRoutines = require('./homepage.routines.js')(db)return {
createUser: homepageRoutines.createUser,
}
}
```