Merged
Size
L
Change Breakdown
Testing60%
CI/CD30%
Docs10%
#28427test: Add isolated local Playwright runner

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 with N8N_BASE_URL=http://localhost:5680 … if you need a stable URL for browser inspection.
  • Throwaway N8N_USER_FOLDER under the OS temp dir (cleaned up on exit). Its database.sqlite is fully isolated from your local ~/.n8n install — no risk of clobbering a dev workflow store.
  • Container-only tests included. Sets PLAYWRIGHT_ALLOW_CONTAINER_ONLY=true so @capability:* / @licensed / @db:reset tests are picked up by the local e2e project. 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 default webServer favicon check is racy with slower module startups). Sets PLAYWRIGHT_SKIP_WEBSERVER=true so Playwright doesn't race to spawn its own n8n.
  • Process-group cleanup via detached: true + group SIGTERM so node ./n8n and the task-runner don't get orphaned to PID 1.

The two underlying levers are also usable independently of the script:

Env varEffect
PLAYWRIGHT_ALLOW_CONTAINER_ONLY=trueDisables grepInvert so container-only tests run in the local e2e project.
PLAYWRIGHT_SKIP_WEBSERVER=trueStops 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).
© 2026 · via Gitpulse