before and after hooks in Cypress - Build an Automation Script
describe('User Login and Logout Tests with Hooks', () => { before(() => { // Runs once before all tests cy.visit('https://example.com/login'); }); beforeEach(() => { // Ensure user is logged out before each test cy.get('body').then(($body) => { if ($body.find('#logout-button').length) { cy.get('#logout-button').click(); cy.url().should('include', '/login'); } }); }); it('should log in successfully', () => { cy.get('#username').clear().type('testuser'); cy.get('#password').clear().type('Test@1234'); cy.get('#login-button').click(); cy.url().should('eq', 'https://example.com/dashboard'); cy.get('#logout-button').should('be.visible'); }); afterEach(() => { // Log out after each test if logged in cy.get('body').then(($body) => { if ($body.find('#logout-button').length) { cy.get('#logout-button').click(); cy.url().should('include', '/login'); } }); }); after(() => { // Cleanup if needed after all tests // For Cypress, usually no action needed here }); });
The before() hook runs once before all tests to open the login page.
The beforeEach() hook checks if the user is logged in by looking for the logout button. If found, it clicks logout to ensure a clean state before each test.
The test case enters username and password, clicks login, then verifies the URL and logout button visibility.
The afterEach() hook logs out the user after each test if logged in, ensuring no leftover session affects other tests.
The after() hook is included for completeness but is empty because Cypress handles cleanup automatically.
This structure keeps tests independent and reliable by managing setup and cleanup with hooks.
Now add data-driven testing with 3 different username and password combinations
Practice
before and after hooks in Cypress testing?Solution
Step 1: Understand the role of hooks
Hooks likebeforeandafterrun code automatically before or after tests.Step 2: Identify their scope
beforeandafterrun once per test suite, ideal for setup and cleanup.Final Answer:
To run setup and cleanup code once per test suite -> Option DQuick Check:
Hooks run code around tests = D [OK]
- Confusing before with beforeEach
- Thinking hooks run inside tests
- Using hooks to skip tests
Solution
Step 1: Identify the hook that runs once before all tests
beforeruns once before the entire suite;beforeEachruns before each test.Step 2: Match the syntax
before(() => { cy.visit('/') })is the correct syntax to run once before all tests.Final Answer:
before(() => { cy.visit('/') }) -> Option AQuick Check:
Run once before all tests = before() = A [OK]
- Using beforeEach instead of before for once-per-suite setup
- Confusing after with before
- Incorrect arrow function syntax
describe('My Suite', () => {
before(() => {
cy.log('Setup once')
})
beforeEach(() => {
cy.log('Setup before each test')
})
it('Test 1', () => {
cy.log('Running Test 1')
})
it('Test 2', () => {
cy.log('Running Test 2')
})
})What is the order of logs printed during test execution?
Solution
Step 1: Understand hook execution order
beforeruns once before all tests,beforeEachruns before each test.Step 2: Trace the logs
Logs print in this order: 'Setup once' (before all), then for Test 1: 'Setup before each test', 'Running Test 1', then for Test 2: 'Setup before each test', 'Running Test 2'.Final Answer:
Setup once, Setup before each test, Running Test 1, Setup before each test, Running Test 2 -> Option BQuick Check:
before runs once, beforeEach runs before each test = A [OK]
- Thinking beforeEach runs only once
- Mixing order of logs
- Ignoring before hook
describe('Test Suite', () => {
beforeEach(() => {
cy.visit('/home')
})
after(() => {
cy.clearCookies()
})
it('Test A', () => {
cy.get('#btn').click()
})
it('Test B', () => {
cy.get('#btn').click()
})
})But the
cy.clearCookies() is not running after each test as expected. What is the problem?Solution
Step 1: Understand the difference between after and afterEach
afterruns once after all tests;afterEachruns after each test.Step 2: Identify the problem
afterruns once after all tests, not after each test.Final Answer:
afterruns once after all tests, not after each test -> Option AQuick Check:
after runs once per suite = A [OK]
- Using after instead of afterEach for per-test cleanup
- Expecting after to run multiple times
- Manually clearing cookies inside tests
Solution
Step 1: Assign setup and cleanup hooks
Setup runs once before all tests usingbefore, cleanup runs once after all tests usingafter.Step 2: Assign login before each test
Login runs before each test usingbeforeEach.Step 3: Verify correct order and usage
before(() => { cy.setup() }); after(() => { cy.cleanup() }); beforeEach(() => { cy.login() }); correctly usesbefore,after, andbeforeEachfor these steps.Final Answer:
before(() => { cy.setup() }); after(() => { cy.cleanup() }); beforeEach(() => { cy.login() }); -> Option CQuick Check:
Setup once before, cleanup once after, login before each = B [OK]
- Mixing beforeEach with once-per-suite hooks
- Placing login in before or after hooks incorrectly
- Swapping setup and cleanup hooks
Ready to prove it?
Pass the test and this pattern moves unknown
