Reputation: 8875
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
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
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.
_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.");
});
});
});
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
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
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
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.
Upvotes: 2
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
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:
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