How will we call a function written in a separate file from a Cypress test?

Cypress includes an external library file, located by default at (path to project)/support/index.js.

This file is included in all test files, so you can put shared code here.


You can also include other files in the support folder with the following code in index.js:

import './MySupportFile.js'

When including an external test file, simple function definitions do not seem to carry over. I'm not exactly sure why. Inserting functions into the cy object has worked for me:

cy.myFunction = greeting => {
    console.log(greeting);
};

cy.myNamespace = {};

cy.myNamespace.myNamespacedFunction = () => {
    console.log("hi");
};

These functions in the cy object will carry over into any /integration files you have.


Add a new file to cypress/support/, e.g. cypress/support/functions.js

cy.myproject = {
    makeUniqueUsername: () => {
        return 'cypress-test-' + Cypress.moment().format("YYMMDD-HHmmss");
    }
}

Include it by adding a reference to it in cypress/support/index.js

import './functions'

Then call your function from any test

describe('registration', function() {
    it('can register', function() {
        let username = cy.myproject.makeUniqueUsername();
        cy.visit('/register');
        cy.get('#username').type(username);
        // etc...
    })
});

When considering plain functions versus cypress "custom commands" note that the cypress documentation encourage plain functions where custom commands aren't necessary in single spec files, though I don't agree with them that you shouldn't DRY test code.


Thanks to the other answers for getting me to this. The main addition is making it step by step, and keeping custom functions out of the global cy.* namespace.


Note: By doing it this way as opposed to registering a command via Cypress.Commands.add you lose logging and time-travel in the Cypress UI. (Thanks @conny). It is up to you and your team which you value more for each case, the explicit steps or the IDE/linter/etc support from using plain js. Registering a command makes it an explicit step in the test rather than just a supporting function.


From https://docs.cypress.io/api/cypress-api/custom-commands.html

Put this in your support/commands.js file:

Cypress.Commands.add('subValues', (a, b) => { return a - b });

Put this in your support/index.js file, if it isn't already there (it should be):

import "./commands";

Call it in your test like so:

describe ('Calling a function', function(){
  it('Call the Subtract function and asert the calculation', function(){
    cy
      .subValues(15, 8)
      .should('eq', 7) // true        
    });
});