5
votes

Is there any way to execute code once before all tests in Cypress? I need it to run only once before all specs. The problem I want to solve is to create some file needed for tests, prepare user permissions and so on.

I have tried 'before' hook in the support index.js file but it runs every test spec.

I have also tried to run conditional 'before' hook in index.js based on env variable which I set in the cypress.json file like so:

  "env": {
    "cypress_setup": false
  },

I am changing the variable in the hook:

before(function () {
  // Set user permissions
  if (Cypress.env('cypress_admin') === false) {
    // do some stuff
    cy.log('o some stuff')
    // Change the variable to mark the hook as executed
    cy.exec('export cypress_admin="true"')
  }
})

but seems Cypress sets original env variable value before each test.

I expect Cypress to support this type of action is some way.

2

2 Answers

4
votes

As of Cypress 6.2.0, you can listen to the before:run event in the plugins file and run any piece of code you'd like within that event handler. The event will fire each time cypress run executes.

*This feature is currently experimental and requires setting the experimentalRunEvents configuration option to true.

See the before:run API doc for more details: https://on.cypress.io/before-run-api

3
votes

If I'm correct, your need is to have a Global setup script which executes only once before execution of your actual test suites. Currently,I don't think such option exist with Cypress.

But, we can handle this with a workaround. Also, please make a note that running test in an order is considered to be Antipattern (Based on - https://github.com/cypress-io/cypress/issues/390). Here are the steps to follow,

  1. Have the setup script in cypress/support as a function
  2. Call the setup function from your test (Idea - Run the setup script as a test)
  3. We need to make this test execute first. As of now, there is now default ordering of tests in Cypress; hence, would request to rename the file as 1_***.spec.js, 2_***.spec.js

Hope this helps; it's just a workaround though.