Answer
Global Setup and Teardown in Playwright
Global setup/teardown run once before and after the entire test suite — not per test or per file.
Configuration
TypeScript
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: './global-setup.ts',
globalTeardown: './global-teardown.ts',
// rest of config...
});
global-setup.ts
TypeScript
// global-setup.ts
import { chromium, FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
console.log('🚀 Running global setup...');
// 1. Seed test database
await seedTestDatabase();
// 2. Start local server (if needed)
// process.env.SERVER_PID = startServer();
// 3. Create auth state files — login once for all tests
const browser = await chromium.launch();
// Regular user auth
const userContext = await browser.newContext();
const userPage = await userContext.newPage();
const baseURL = config.projects[0].use.baseURL || 'http://localhost:3000';
await userPage.goto(`${baseURL}/login`);
await userPage.fill('#email', 'user@test.com');
await userPage.fill('#password', 'password123');
await userPage.click('#submit');
await userPage.waitForURL('**/dashboard');
await userContext.storageState({ path: '.auth/user.json' });
// Admin user auth
const adminContext = await browser.newContext();
const adminPage = await adminContext.newPage();
await adminPage.goto(`${baseURL}/admin/login`);
await adminPage.fill('#email', 'admin@test.com');
await adminPage.fill('#password', 'admin123');
await adminPage.click('#submit');
await adminPage.waitForURL('**/admin');
await adminContext.storageState({ path: '.auth/admin.json' });
await browser.close();
// 4. Set global env variables (accessible in tests via process.env)
process.env.GLOBAL_SETUP_DONE = 'true';
process.env.TEST_RUN_ID = `run-${Date.now()}`;
console.log('✅ Global setup complete');
}
async function seedTestDatabase() {
// Your DB seeding logic — REST call, direct DB, etc.
const res = await fetch('http://localhost:3001/test/seed', { method: 'POST' });
if (!res.ok) throw new Error('Failed to seed test database');
}
export default globalSetup;
global-teardown.ts
TypeScript
// global-teardown.ts
async function globalTeardown() {
console.log('🧹 Running global teardown...');
// 1. Clean test database
await fetch('http://localhost:3001/test/cleanup', { method: 'POST' });
// 2. Stop local server
// if (process.env.SERVER_PID) stopServer(process.env.SERVER_PID);
// 3. Remove auth files
// fs.unlinkSync('.auth/user.json');
console.log('✅ Global teardown complete');
}
export default globalTeardown;
Accessing Global Setup Data in Tests
TypeScript
// Tests can read env vars set in global setup
test('uses global setup data', async ({ page }) => {
console.log('Test run ID:', process.env.TEST_RUN_ID);
// ...
});
Global Setup vs beforeAll
| Global Setup | beforeAll | |
|---|---|---|
| Runs | Once per test suite | Once per describe/file |
| Scope | Across all workers | Within one worker |
| Browser access | Manual setup needed | Via browser fixture |
| Use for | Auth files, DB seed, server start | Suite-level state |
