</>

Technology

Playwright

Difficulty

Advanced

Interview Question

How do you implement global setup and teardown in Playwright?

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 SetupbeforeAll
RunsOnce per test suiteOnce per describe/file
ScopeAcross all workersWithin one worker
Browser accessManual setup neededVia browser fixture
Use forAuth files, DB seed, server startSuite-level state

Follow AutomateQA

Related Topics