Playwright Hooks and Lifecycle: beforeAll, afterEach, and test.step() Mastery
Hooks control test lifecycle: setup before, cleanup after, steps within. Master the execution order and scope to write maintainable tests.
🎠Want to master this with real projects? Join the Playwright Automation Mastery course at The Testing Academy.
Contents
Execution Order
test.beforeAll(async () => { /* Once before all tests in file */ });
test.beforeEach(async ({ page }) => { /* Before each test */ });
test('test 1', async ({ page }) => { /* Test runs here */ });
test('test 2', async ({ page }) => { /* Test runs here */ });
test.afterEach(async ({ page }, testInfo) => { /* After each test */ });
test.afterAll(async () => { /* Once after all tests in file */ });
🚀 Level Up Your Playwright
From locators to CI pipelines — build a production-grade Playwright + TypeScript framework step by step.
test.step() for Sub-Steps
test('complete purchase', async ({ page }) => {
await test.step('add to cart', async () => {
await page.goto('/products');
await page.getByRole('button', { name: 'Add' }).click();
});
await test.step('checkout', async () => {
await page.goto('/checkout');
await page.getByLabel('Address').fill('123 Main St');
});
await test.step('payment', async () => {
await page.getByRole('button', { name: 'Pay' }).click();
await expect(page.getByText('Confirmed')).toBeVisible();
});
});
Conditional Hooks
test.afterEach(async ({ page }, testInfo) => {
if (testInfo.status === 'failed') {
await page.screenshot({ path: 'failure-' + testInfo.title + '.png' });
console.log('FAILED:', testInfo.title, testInfo.error?.message);
}
});
🎓 Master Playwright End to End
Join hundreds of SDETs building real automation frameworks. Lifetime access, hands-on projects, and a job-ready portfolio.
