Shipping features without E2E tests is like deploying without monitoring — you'll find out about problems from your users instead of your CI pipeline. We added 40 Playwright tests across 5 spec files to Boottify, and the result is a massive boost in deployment confidence.
WHY PLAYWRIGHT
We evaluated Cypress, Playwright, and plain Puppeteer. Playwright won for three reasons:
- Multi-browser out of the box — Chromium, Firefox, WebKit without plugins
- Auto-wait — No more
cy.wait(3000)hacks. Playwright auto-waits for elements to be actionable - Native ESM + TypeScript — First-class support without transpilation hacks
THE SESSION INJECTION TRICK
Here's the problem: our auth routes have strict rate limiting (5 requests per 15 minutes on sign-in). Running 40 tests that each need to log in would hit the rate limiter after the 5th test.
Our solution: inject sessions directly into the database and set cookies programmatically.
// e2e/helpers/seed.ts
async function createTestSession(userId: string) {
const sessionId = generateSessionId();
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000);
await prisma.sessions.create({
data: { id: sessionId, userId, expiresAt },
});
return { sessionId, expiresAt };
}
The seed script creates users, sessions, and test data, then writes session cookies to a JSON file that Playwright's storageState can load:
// playwright.config.ts
export default defineConfig({
projects: [
{
name: "admin",
use: {
storageState: "e2e/helpers/sessions.json",
},
},
],
});
This approach bypasses the login form entirely — tests start already authenticated, saving time and avoiding rate limiter conflicts.
5 SPEC FILES, 40 TESTS
We organized tests by domain:
| Spec File | Tests | Coverage |
|---|---|---|
| auth.spec.ts | 10 | Sign-in form, sign-up, password reset, 2FA flows |
| admin.spec.ts | 12 | Dashboard, user management, blog CRUD, settings |
| client.spec.ts | 8 | App management, billing, orders |
| blog.spec.ts | 6 | Public blog listing, post pages, comments, search |
| public.spec.ts | 4 | Landing page, pricing, careers, status page |
SEED SCRIPT DESIGN
Every test run starts fresh. The seed script creates:
- 3 test users (admin, client, developer) with pre-hashed passwords
- Active sessions for each user (valid for 24 hours)
- 1 app template and 1 plan for testing app creation flows
- Blog posts for testing the public blog
# Run before tests
npx tsx e2e/helpers/seed.ts
# Run all tests
npx playwright test
# Run specific suite
npx playwright test e2e/admin.spec.ts
# Debug mode (opens browser)
npx playwright test --debug
LESSONS LEARNED
- Session cookie
secure: truemeans tests must run against HTTPS. We use the dev server with the actual domain for E2E - Database seeding is fast — our seed script runs in under 2 seconds
- Playwright's
test.describewith sharedbeforeEachkeeps specs DRY - Screenshot on failure is invaluable — saves hours of debugging
40 tests might not sound like a lot, but they cover the critical paths that matter most. Every deployment now runs through these tests, catching regressions before they reach production.



