## TL;DR
Put the reset in a `globalSetup` file referenced from `playwright.config.js`; it runs once per `playwright test` invocation, before any worker starts. Truncate tables (or re-run migrations) with a privileged connection string read from the environment, never hard-coded. Keep it fast: truncating beats migrate-from-scratch for iteration speed.

## Problem
You need each Playwright run to start from a known database state, and the reset must happen exactly once before any test file runs.

## Steps
1. Create `global-setup.js` that connects with the connection string from `process.env.DATABASE_URL` and truncates the tables your tests touch. Expected: running the file standalone resets the tables.
2. Point the config at it: `globalSetup: require.resolve('./global-setup')`. Expected: the config loads with no errors.
3. Run the suite and log a line from the setup so you can see it in CI output. Expected: tables are empty before test 1, and the suite passes against clean state.
4. In CI, point the env var at the CI database service and run migrations first if the schema may be stale. Expected: the CI run starts from a migrated, empty schema.

```js
// global-setup.js
const { Client } = require('pg');

module.exports = async function () {
  const client = new Client({ connectionString: process.env.DATABASE_URL });
  await client.connect();
  await client.query('TRUNCATE users, orders RESTART IDENTITY CASCADE');
  await client.end();
  console.log('database reset complete');
};
```

## When to use
- The suite assumes an empty (or freshly migrated) database at the start of a run.
- Test files pass alone but fail together because of leftover rows.
- You want one reset point instead of reset logic scattered across files.

## When not to use
- You need isolation between individual tests (use fixtures that create and clean up per test).
- Designing what seed data the tests need (that is test data design, not reset mechanics).
- Choosing a migration tool (run whatever migrator you already use before the truncate).

## Tool compatibility
- Playwright 1.40 through 1.5x (`globalSetup` config key, capital S).
- Any Node database client (`pg`, `mysql2`, `mongodb`, Prisma); the pattern is client-agnostic.

## Variant phrasings
### reset database once before playwright test run
Same pattern: globalSetup is the hook that runs exactly once.
### playwright clean database between test runs
If "between runs" means once per invocation, globalSetup; per-test cleanup needs fixtures instead.

## Why it happens
Without a single reset point, each test file silently depends on leftover state from the last run, so suites pass in isolation and fail together. globalSetup is the only hook that runs exactly once before workers fan out, which makes it the right place for the reset.

## Edge cases
- Parallel workers against one database: truncating per file causes cross-talk; keep one reset in globalSetup and give each test unique data.
- Reset is slow: truncate only the tables the suite touches instead of rebuilding the schema.
- globalSetup never ran: the config key is `globalSetup` (capital S) and the path must resolve from the config file.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_aVwABxTsYImEbkVFCuMC1w
