Export your suite as a Playwright project
One download gives you a plain Playwright project with every test the app would run. It needs no TestWatch account to run. Export is on every plan.
Download it
Choose Export suite on the app’s Scenarios page, or use the “Run locally” card on CI & deploys. Pick the environment and, optionally, tags. The dialog previews how many tests go in per device and lists any that are left out, with the reason. Quarantined tests are included only if you switch them on.
The export contains the tests a run would run. Tests that need review, are out of date or are drafts are listed as skipped instead. Exporting also works while a workspace is suspended, so your tests stay yours.
What’s in the zip
| Path | Contents |
|---|---|
tests/<name>.<device>.spec.ts | Each test’s code, exactly as it runs in TestWatch. The device suffix sends it to the matching Playwright project. |
fixtures.ts | The same helpers the tests use in TestWatch, made to run without it. |
email-provider.ts | Where you connect your own email service, for tests that read email. |
playwright.config.ts | One project per device the tests use; loads .env; one retry; trace, video and screenshot kept on failure. |
package.json | An exact @playwright/test version, the one TestWatch runs. |
.env.example | The variable names the suite reads. TARGET_BASE_URL is filled in; every secret is left empty. |
.github/workflows/playwright.yml | A workflow that installs, runs the suite with your repository secrets and uploads the report. |
README.md | How to run it, what the fixtures do, and anything left out. |
testwatch.json | A manifest of every test with its TestWatch ids and version, so two exports can be compared. |
files/ | The files the tests upload, at their current version. Files over the size limit are listed in the README to download separately. |
tsconfig.json, .gitignore | The usual. |
No password, token or secret is ever written into the zip.
Run it locally
npm install
npx playwright install chromium webkit # the README lists the browsers your suite needs
cp .env.example .env # then fill in TARGET_EMAIL / TARGET_PASSWORD
npx playwright testYou need Node 20.12 or newer. Open the report with npx playwright show-report. Each device is its own project, so npx playwright test --project=desktop-chrome runs one. Tests run one at a time, because they may share the same login.
Before each test the fixtures open TARGET_BASE_URL, accept a cookie banner if one shows, turn off CSS animations and block a few chat and marketing widgets. Set TESTWATCH_VENDOR_BLOCK=off if your app needs one of them. Set TW_INCLUDE_QUARANTINED=1 to run quarantined tests too.
Protected staging after export
Protection comes from environment variables. .env.example names only the kinds your environment uses:
TARGET_BASE_URL=https://staging.example.com
TARGET_EMAIL=
TARGET_PASSWORD=
# Only when the environment is protected; headers go only to TARGET_BASE_URL
TARGET_BASIC_USER=
TARGET_BASIC_PASSWORD=
TARGET_VERCEL_BYPASS=
TARGET_CF_ACCESS_CLIENT_ID=
TARGET_CF_ACCESS_CLIENT_SECRET=
TARGET_EXTRA_HEADERS={"x-staging-key":""}As in TestWatch, these headers go only to the exact origin of TARGET_BASE_URL, never to another site and never on a redirect.
Email after export
In TestWatch, tests that read email use TestWatch’s own inboxes. An exported suite reads mail through a provider you connect in email-provider.ts. Until you do, those tests fail with EMAIL_PROVIDER_NOT_CONFIGURED and the rest run normally. The README names the tests that read email.
A provider has two functions: address(tag) returns a fresh address you can receive at, and list({ to, since }) returns the messages sent to it since a time. Links and one-time codes are extracted for you, as in TestWatch. The README has a complete example for a hosted test-email service; plus-addressing on a mailbox you own works too:
// email-provider.ts, using plus-addressing on a mailbox you own
export const emailProvider = {
// A fresh address. tag is unique per call, e.g. "tw-l1a2b3c-x9k2m4".
address: (tag: string) => `qa+${tag}@yourcompany.com`,
// The messages sent to `to` since `since`: subject, from, html or text, receivedAt.
async list({ to, since }: { to: string; since: Date }) {
return fetchMessagesFromYourProvider(to, since);
},
};Without a match within 45 seconds, waitForEmail() fails with EMAIL_NOT_RECEIVED. Set TW_EMAIL_WAIT_MS to change the wait, up to 120 seconds.
Test data after export
unique(), testEmail() and track() work the same way. Every value from one npx playwright test shares a tw-<tag> prefix, so you can find and delete what a run created. testEmail() uses TW_TEST_EMAIL_DOMAIN, default example.com. See Test fixtures.
What stays in TestWatch
Writing new tests, checking failures and proposing fixes, schedules, alerts, run history and evidence stay in TestWatch. The export is a snapshot: export again after tests change.