Global setup and teardown
There are two ways to run code once before all tests: project dependencies (recommended) and globalSetup in config. I always use project dependencies — it shows in the HTML report, records traces, and supports fixtures. The main use case: log in once, save storageState, every test starts already authenticated.
When I need global setup
The most common reason I use global setup: authentication. Logging in before every test is slow — on a suite of 200 tests it adds 200 login flows. Instead I log in once in global setup, save the browser storage state (cookies + localStorage) to a file, and every test starts already authenticated by loading that file.
Other use cases: seeding a test database, creating fixtures in an API, setting environment variables that tests read.
Two approaches — and which to pick
Option 1: Project dependencies — I create a special 'setup' project in playwright.config.ts and list it as a dependency of my main test projects. The setup project runs first, then the tests run.
Option 2: globalSetup config option — I point globalSetup in the config to a file that exports a function. That function runs once before all tests.
I always use Option 1. Here's why:
| Feature | Project dependencies | globalSetup |
|---|---|---|
| Visible in HTML report | ✅ As separate project | ❌ Not shown |
| Trace recording | ✅ Full trace | ❌ Not supported |
| Playwright fixtures | ✅ Supported | ❌ Not supported |
| Browser via fixture | ✅ { browser } fixture | ❌ Manual browserType.launch() |
Project dependencies — login once pattern
This is the pattern I use for authentication in every project. The 'setup' project runs the login script, saves storageState to a file. The 'chromium' project depends on 'setup', so setup always runs first, and the chromium tests load the saved state.
Option 2: globalSetup config (when fixtures don't matter)
If I only need to set environment variables or call an API without browser interaction, I use globalSetup in the config. It's simpler for non-browser work but doesn't get traces or HTML report visibility.
Test filtering with dependencies
When I filter tests with --grep or run a specific file, Playwright still runs the setup project first if the selected tests depend on it. This is the expected behavior — I can't run tests that need auth without the auth setup.
To skip dependencies (for debugging or when I know the state is already set up): --no-deps. This runs only the directly selected tests without any dependent projects.