Florian F
Florian F

Reputation: 8875

How can I execute code before all tests suite with Cypress?

Basically, I want to login once before all my tests in all files are executed.

Should I call my login command in each test file using the before hook or is there any way to do it once before all tests?

Upvotes: 87

Views: 117310

Answers (7)

Aureuo
Aureuo

Reputation: 277

Now in Cypress v12 the appropriate way to do this is with the Before Run API.

cypress.config.js

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    setupNodeEvents(on, config) {
      on('before:run', (details) => {
        /* code that needs to run before all specs */
      })
    },
    experimentalInteractiveRunEvents: true,   // use for cypress open mode
  },
})

Upvotes: 17

Mike T
Mike T

Reputation: 614

Here is how I was able to work around the limitations of Cypress to get async code running in a beforeAll manner, in which it executes one time before all of the tests run.

  1. Create a new file named _beforeAll.spec.js in /e2e with a before block and at least one test (it can be as simple as logging something):
describe("_beforeAll", () => {
  describe("cypress setup", () => {
    before(() => {
      cy.seedApiDatabase();
    });
    
    // Note: It is important to have at least one test to trigger the before block
    it("seeds the database", () => {
      cy.log("Database seeded successfully.");
    });
  });
});

  1. Edit your cypress config (cypress.config.js/cypress.json) and add the _beforeAll.spec.js to the specPattern (See Cypress docs on E2E configuration for more info):
module.exports = defineConfig({
  ...,
  e2e: {
    ...,
    specPattern: [
      "./cypress/e2e/_beforeAll.spec.js",
      "./cypress/e2e/**/*.{feature,spec.js}",
    ],
  },
});

Anything added to the before block within _beforeAll.spec.js will be executed only one time before all of the tests run.

Note: This example requires a custom command "seedApiDatabase" to be added using Cypress.Commands.add("seedApiDatabase", () => {...}); within /support/commands.js to work properly.

Upvotes: -1

thisismydesign
thisismydesign

Reputation: 25172

cypress/support/e2e.ts

before(() => {
  // do stuff
})

Use before to run 1-time before every test or use beforeEach. to run before each individual test.

Upvotes: 3

Ethan Dowler
Ethan Dowler

Reputation: 137

I would login before EACH test because there could be things that happen in a previous test that affects the results of the current test. With a fresh login, you're starting with a clean state every time. If you want to test a "chain" of unrelated actions (action A THEN action B), then write that as a separate test, but have basic functionality in individual tests.

describe('/page'), () => {
  beforeEach(() => {
    cy.login()        // custom command that handles login w/o UI
    cy.visit('/page') // go to the page you are testing
  })

  // tests
})

You should include a beforeEach block in every test file. This block should login and navigate to the page in question.

Upvotes: 9

Armando Guarino
Armando Guarino

Reputation: 1631

I would wrap the function to execute in a before block, as others already suggested. Now, looking at the docs, I would make that happen in the cypress/support/index.js file. supportFile cypress docs section

Upvotes: 2

Hossam Mourad
Hossam Mourad

Reputation: 4659

describe('Hooks', function() {
    before(function() {
        // runs once before all tests in the block
    })
})

https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests.html#Hooks

Upvotes: 11

Jennifer Shehane
Jennifer Shehane

Reputation: 6915

Short answer: You can write your login command in a before hook within the supportFile (the file that is loaded automatically before your other spec files). This before hook will run before any of the code in your other test files.


Recommendations: That being said, this approach leaves little flexibility for variation in your individual test files that you may want in the future like:

  • What if you want to seed the database differently for one test?
  • What if you want to log in as a different user with different permissions?
  • What if you need to do something in onBeforeLoad once?

I would recommend just having the login command in a before hook in each individual spec file.

I would also further recommend having your login command in a beforeEach hook to avoid sharing any state in between tests.

Upvotes: 90

Related Questions