Isolated Playwright test runner added
A new local test runner lets developers spin up isolated E2E tests with random ports and a throwaway database, enabling parallel execution without Docker or local environment conflicts.
Local Playwright E2E tests just got a significant upgrade. A new pnpm test:local:isolated command lets developers run tests against a local n8n build with complete isolation from the dev environment — no shared ports, no touching ~/.n8n, and no Docker required.
The runner allocates random free ports for both the HTTP server and task-runner broker, so multiple instances can run in parallel without collisions. A throwaway N8N_USER_FOLDER is created under the OS temp directory, guaranteeing a clean SQLite database for each run that gets removed on exit.
Two underlying environment levers can also be used independently: PLAYWRIGHT_ALLOW_CONTAINER_ONLY=true enables @capability:* and @licensed tests that normally require Docker, while PLAYWRIGHT_SKIP_WEBSERVER=true stops Playwright from racing to spawn its own n8n — useful when a wrapper script manages startup with custom env vars.
For instance-ai module testing, a dedicated pnpm test:local:instance-ai wrapper pre-fills the required env vars (model, API key, module flags) over the generic isolated runner, letting developers iterate against real Anthropic API calls without the docker proxy stack.
In the n8n Playwright test suite, developers can now choose between container mode (for CI with proxy recording/replay), the existing test:local (fixed port, shared DB), or the new isolated mode (fully ephemeral, parallel-safe).
View Original GitHub Description
Summary
Adds pnpm test:local:isolated for situations where the standard pnpm test:local defaults aren't enough.
What it gives you over test:local:
- Random free OS port for n8n's HTTP server and the task-runner broker, so multiple instances can run in parallel without colliding on
5678/5679. Pin a port withN8N_BASE_URL=http://localhost:5680 …if you need a stable URL for browser inspection. - Throwaway
N8N_USER_FOLDERunder the OS temp dir (cleaned up on exit). Itsdatabase.sqliteis fully isolated from your local~/.n8ninstall — no risk of clobbering a dev workflow store. - Container-only tests included. Sets
PLAYWRIGHT_ALLOW_CONTAINER_ONLY=trueso@capability:*/@licensed/@db:resettests are picked up by the locale2eproject. Their fixtures must detect the missing container and skip or fall back. - Self-managed n8n with a real readiness check against
/rest/e2e/reset(Playwright's defaultwebServerfavicon check is racy with slower module startups). SetsPLAYWRIGHT_SKIP_WEBSERVER=trueso Playwright doesn't race to spawn its own n8n. - Process-group cleanup via
detached: true+ group SIGTERM sonode ./n8nand the task-runner don't get orphaned to PID 1.
The two underlying levers are also usable independently of the script:
| Env var | Effect |
|---|---|
PLAYWRIGHT_ALLOW_CONTAINER_ONLY=true | Disables grepInvert so container-only tests run in the local e2e project. |
PLAYWRIGHT_SKIP_WEBSERVER=true | Stops Playwright from launching its own n8n via the webServer config. |
Usage
pnpm --filter=n8n-playwright test:local:isolated tests/e2e/credentials/crud.spec.ts
# Pass extra n8n env (same convention as test:local)
N8N_TEST_ENV='{"N8N_ENABLED_MODULES":"my-module"}' \
pnpm --filter=n8n-playwright test:local:isolated tests/e2e/my-module
# Run multiple instances in parallel
pnpm --filter=n8n-playwright test:local:isolated tests/e2e/foo &
pnpm --filter=n8n-playwright test:local:isolated tests/e2e/bar &
Related Linear tickets, Github issues, and Community forum posts
N/A — internal test tooling.
Review / Merge checklist
- I have seen this code, I have run this code, and I take responsibility for this code.
- PR title and summary are descriptive.
- Docs updated or follow-up ticket created. — N/A, internal test tooling, README updated in-repo.
- Tests included. — N/A, this is test tooling. Verified end-to-end by running the script against an instance-ai test branch (catches a real bug, both n8n and temp folder cleaned up correctly on exit).