Nighttime Pachinko Marathon

    cypress-routines

    1.0.3 • Public • Published


    Easily write scalable Node.js setup code for Cypress


    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

    cypress-routines screencast
    Using cypress-routines to write and organize test setups that run in Node.js

    Installation

    1. Install cypress-routines

    # With yarn: 
    yarn add cypress-routines --dev
     
    # With npm: 
    npm install cypress-routines --save-dev

    2. Require plugin-file

    In cypress/plugins/index.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:

    require('cypress-routines/support')

    4. Ignore *.routines.js

    In cypress.json:

    {
        "ignoreTestFiles": ["*.routines.js"]
    }

    Usage guide

    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.

    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:

    // cypress/integration/login.routines.js
     
    function 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:

    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.

    // cypress/plugin/index.js
     
    module.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.

    // cypress/integration/login.routines.js
     
    function 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).

    // cypress/integration/login.spec.js
     
    it('logs in the user', function () {
        const routineArg = {
            email: 'max@maxschmitt.me',
            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.

    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:

    // cypress/global-routines.js
     
    function globalRoutines(db) {
        return {
            async createDefaultUser() {
                const defaultUser = {
                    email: 'maximilian.schmitt@googlemail.com',
                    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 '/':

    // cypress/integration/login.spec.js
     
    it('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:

    // 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,
        }
    }

    Keywords

    none

    Install

    npm i cypress-routines

    DownloadsWeekly Downloads

    6

    Version

    1.0.3

    License

    MIT

    Unpacked Size

    184 kB

    Total Files

    9

    Last publish

    Collaborators

    • maximilianschmitt