This page covers browser-based E2E tests with Playwright. For unit and integration tests, see
the Test Runner guide. For type-safe server tests without a browser, see
Server Testing.
Prerequisites
Install Playwright and its browser binaries:Playwright configuration
Createplaywright.config.ts at your project root:
webServer option starts your dev server before tests run and shuts it down after. In local development, reuseExistingServer skips startup if the server is already running.
Database setup
For E2E tests, use a file-based SQLite database. Each dev server run creates its own database file, and tests run against that instance.authModels provides the table definitions Vertz needs for sessions, users, and OAuth accounts. When you call app.initialize(), auth tables are created automatically.
Test isolation
Each test creates a unique user (via a timestamped email), so tests don’t interfere with each other. For seed data, insert it once on server startup:Authenticating test users
Vertz auth usesHttpOnly cookies, so you can’t set tokens from browser JavaScript. Instead, call the auth endpoints from your test setup and pass the cookies to Playwright’s browser context.
Enable email/password auth
TheemailPassword: {} option in createAuth() enables the POST /api/auth/signup and POST /api/auth/signin endpoints. This is the simplest way to create test users programmatically:
Set
cookie: { secure: false } for local development and testing. Without this, cookies won’t be sent over plain HTTP.Cookie extraction helper
Auth responses includeSet-Cookie headers. Parse them into the format Playwright expects:
Authenticate helper
Sign up a unique test user and return cookies ready for Playwright:X-VTZ-Request: 1 header is required — Vertz uses it for CSRF protection on mutation endpoints.
Using it in tests
Callauthenticate() in beforeEach and add cookies to the browser context:
Multi-tenant apps
If your app uses tenant scoping, the session JWT needs atenantId. After signup, call the switch-tenant endpoint:
tenant.verifyMembership callback in your server config. For testing, you can accept all tenants or check against a seed list.
Writing tests
Wait for data, not timers
Use Playwright’s built-in assertions with timeouts instead ofpage.waitForTimeout():
Use unique data per test
Timestamp your test data to avoid collisions:Use data-testid for stable selectors
Prefer data-testid attributes over CSS classes or text content for elements that tests interact with:
Running tests
Add scripts to yourpackage.json:
webServer config ensures the dev server starts fresh.
Next steps
Test Runner
Built-in test runner with Vitest-compatible API, watch mode, and coverage.
Server Testing
Type-safe test client for entity CRUD, service actions, and raw HTTP requests.
Authentication
Full auth configuration — sessions, stores, rate limiting, and access control.
Entities
Define entities with models, access rules, and hooks.