|

Playwright Authentication Storage: Skip Login in Every Test With storageState

Logging in before every single test is slow, flaky, and wasteful. Playwright’s storageState lets you authenticate once, save the session, and reuse it across your entire test suite. Here is exactly how to set it up.

Contents

How storageState Works

Playwright can save cookies and localStorage to a JSON file after login. Every subsequent test loads that file instead of navigating through the login form. Your 200-test suite goes from 200 login flows to 1.

Step 1: Create the Auth Setup

// auth.setup.ts
import { test as setup, expect } from '@playwright/test';

const authFile = 'playwright/.auth/user.json';

setup('authenticate', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('admin@example.com');
  await page.getByLabel('Password').fill('secure-password');
  await page.getByRole('button', { name: 'Sign in' }).click();

  await expect(page.getByText('Dashboard')).toBeVisible();

  await page.context().storageState({ path: authFile });
});

Step 2: Configure playwright.config.ts

import { defineConfig } from '@playwright/test';

export default defineConfig({
  projects: [
    { name: 'setup', testMatch: /.*\.setup\.ts/ },
    {
      name: 'chromium',
      use: {
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },
  ],
});

Multiple Roles: Admin, User, Guest

// admin.setup.ts
setup('admin auth', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('admin@example.com');
  await page.getByLabel('Password').fill('admin-pass');
  await page.getByRole('button', { name: 'Sign in' }).click();
  await page.context().storageState({ path: 'playwright/.auth/admin.json' });
});

// user.setup.ts
setup('user auth', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('user@example.com');
  await page.getByLabel('Password').fill('user-pass');
  await page.getByRole('button', { name: 'Sign in' }).click();
  await page.context().storageState({ path: 'playwright/.auth/user.json' });
});

CI/CD: Handle Token Expiry

# GitHub Actions - regenerate auth before tests
- name: Run auth setup
  run: npx playwright test --project=setup
- name: Run tests with cached auth
  run: npx playwright test --project=chromium

Important: Add playwright/.auth/ to your .gitignore. Never commit auth state files containing real credentials or session tokens.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.