Skip to main content
End-to-End Testing with Playwright: 40 Tests & Counting

End-to-End Testing with Playwright: 40 Tests & Counting

Andrius LukminasAndrius LukminasFebruary 3, 20267 min read19 views

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 FileTestsCoverage
auth.spec.ts10Sign-in form, sign-up, password reset, 2FA flows
admin.spec.ts12Dashboard, user management, blog CRUD, settings
client.spec.ts8App management, billing, orders
blog.spec.ts6Public blog listing, post pages, comments, search
public.spec.ts4Landing 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: true means 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.describe with shared beforeEach keeps 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.

Related Articles

Comments

0/5000 characters

Comments from guests require moderation.