October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk8 min

How to Save and Reuse Browser Sessions in Playwright

Use Playwright storageState to reuse authentication across test runs, with guidance for setup projects, parallel workers, multiple roles, sessionStorage, and safe credential handling.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Save an authenticated Playwright session with await page.context().storageState({ path: 'playwright/.auth/user.json' }) after login has completed. Reuse it by passing the file as storageState when creating a browser context or in a Playwright Test project’s use configuration. Treat the file like a password: it can contain cookies and other credentials, so keep it out of Git and restrict access.

Save a session after login

Playwright gives each test an isolated browser context. To avoid repeating a UI login, complete the login once, wait until the application confirms authentication, and save that context’s storage state.

As an Amazon Associate I earn from qualifying purchases.

  1. Install Playwright and its browser for your project, and create the login page or script.
  2. Complete the application’s login flow.
  3. Wait for the final destination or a reliable authenticated UI element. Do not save while redirects or login processing are still underway.
  4. Save the context state to a file:
import { chromium } from '@playwright/test';

const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();

await page.goto('https://example.com/login');
await page.getByLabel('Email').fill(process.env.TEST_EMAIL!);
await page.getByLabel('Password').fill(process.env.TEST_PASSWORD!);
await page.getByRole('button', { name: 'Sign in' }).click();

// Replace this URL or locator with a reliable signal from your application.
await page.waitForURL('**/dashboard');
await context.storageState({ path: 'playwright/.auth/user.json' });

await browser.close();

Use your own application’s URL, selectors, and post-login condition. Keep credentials in environment variables or another secret store rather than embedding them in the script.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep the state file out of source control

Create playwright/.auth for local state files and add it to .gitignore:

playwright/.auth

Authentication state can contain cookies and headers that let someone act as the saved test account. Do not commit it, even to a private repository; restrict who and what can read it, and regenerate it if it is exposed or no longer valid. The official Playwright authentication guide describes this security guidance and workflow.

Reuse the saved session in tests

Configure a project-wide state file

For a single account shared by a project’s tests, set storageState in the Playwright Test configuration. Tests still receive isolated contexts, initialized from the saved state.

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

export default defineConfig({
  use: {
    storageState: 'playwright/.auth/user.json',
  },
});

Load state in a specific context

For a standalone script, or when only some tests should use the session, pass the file when creating a context:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const context = await browser.newContext({
  storageState: 'playwright/.auth/user.json',
});
const page = await context.newPage();
await page.goto('https://example.com/dashboard');

The BrowserContext API also documents applying a state snapshot to an existing context with setStorageState; that method is marked as added in Playwright v1.59. Check your installed version before relying on it. See the BrowserContext API reference.

Run authentication setup before test projects

A setup project can refresh the state file before dependent browser projects run. This avoids requiring a developer to log in manually before every test run.

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

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

Put the login flow in a setup test such as tests/auth.setup.ts; after the authenticated condition is reached, call await page.context().storageState({ path: 'playwright/.auth/user.json' }). Configure the setup project and dependent projects in your own existing configuration as needed.

UI mode does not run the setup project by default. If the saved authentication expires, run the setup explicitly to create a fresh state file before relying on dependent tests. If you want Playwright to remove the state between runs, save it under the configured project outputDir, which Playwright cleans before each run. These lifecycle details are covered in the authentication guide.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose a reuse pattern that matches your tests

One shared account

A shared account is appropriate when tests can run concurrently without interfering through server-side state. It is a poor fit when tests mutate the same records, change account settings, or rely on browser-specific authentication. Context isolation does not isolate data stored on the server.

One account per parallel worker

If tests modify shared server-side data, use a distinct account and state file per parallel worker. The Playwright guide’s pattern keys the file by test.info().parallelIndex; provision unique accounts to avoid collisions not only among workers but also among developers or CI runs.

import { test as base } from '@playwright/test';
import path from 'path';

export const test = base.extend({
  storageState: async ({}, use, testInfo) => {
    const stateFile = path.join(
      'playwright/.auth',
      `worker-${testInfo.parallelIndex}.json`,
    );
    await use(stateFile);
  },
});

This illustrates how to derive a worker-specific filename; a complete worker-account setup must also create each account’s authenticated state and configure the relevant fixtures and projects. Follow the official worker authentication example for the full pattern rather than sharing one account among tests that change the same data.

Multiple roles in a test

Save separate state files for roles such as administrator and customer, then select the appropriate file for each test or group. If a single test needs both roles interacting, create two browser contexts with their respective state files; separate contexts keep each role’s browser state distinct.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Authenticate through an API

If the application exposes a suitable authentication endpoint, use Playwright’s API request context to authenticate and save its state instead of automating the login UI. This can remove UI steps from setup, but it depends on the application’s API and authentication flow. The official authentication guide includes an API-based approach.

Know which browser data is saved

A storage-state file is not a complete copy of a browser profile. Its coverage depends on the data type, Playwright version, and browser support.

Data or capability What to know
Cookies and local storage Part of the documented reusable storage-state workflow for authentication.
IndexedDB IndexedDB inclusion is an option added in Playwright v1.51. Enable it when your application stores authentication tokens there, and check the API for the option supported by your installed version.
Session storage Not restored by a normal storage-state file. It is origin-specific and does not persist across page loads; Playwright’s authentication guide documents a workaround using an initialization script.
WebAuthn/passkey credentials The BrowserContext API documents virtual WebAuthn credentials in storage snapshots. Verify the relevant API and browser support for your installed version.
Origin private file system (OPFS) Snapshot support is marked added in Playwright v1.63. OPFS is not supported in ephemeral WebKit contexts.
WebStorage API methods Marked as added in Playwright v1.61; check the WebStorage reference before using them.
Apply state to an existing context BrowserContext.setStorageState is marked as added in Playwright v1.59.

Version annotations above are those displayed by the official API pages on October 3, 2026. They are not a guarantee that a particular browser supports every capability. Consult the BrowserContext API reference and WebStorage API reference for details.

Restore session storage with an initialization script

Session storage requires a separate workaround. Read it in the authenticated page, serialize the values, and add an initialization script that restores them only for the intended hostname before the application code runs. The script must be installed before navigating to the app.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// Run on the authenticated page before closing its context.
const sessionStorageData = await page.evaluate(() => {
  const items: Record<string, string> = {};
  for (let i = 0; i < window.sessionStorage.length; i++) {
    const key = window.sessionStorage.key(i);
    if (key) items[key] = window.sessionStorage.getItem(key)!;
  }
  return items;
});

// Persist sessionStorageData securely alongside your other auth state.

// In the context that will reuse the session, before page.goto(...):
await context.addInitScript(({ hostname, items }) => {
  if (window.location.hostname !== hostname) return;
  for (const [key, value] of Object.entries(items)) {
    window.sessionStorage.setItem(key, String(value));
  }
}, { hostname: 'example.com', items: sessionStorageData });

This is a workaround, not an extension of the storage-state file format. Protect the serialized data as carefully as the state file. The limitation and initialization-script approach are documented in the authentication guide.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot expired or incomplete sessions

  • The test returns to the login page. The saved state may have expired or been captured before login finished. Rerun the setup flow, wait for the final URL or authenticated UI, and save a fresh file.
  • The application appears logged out despite loading the file. Check where the application stores its token. If it uses IndexedDB, enable the supported IndexedDB snapshot option; if it depends on session storage, use the initialization-script workaround.
  • Tests fail only when run in parallel. Shared server-side records or a shared account may be interfering. Allocate unique accounts and state files per worker.
  • UI mode does not refresh credentials. UI mode does not run the setup project by default. Run that project explicitly when authentication has expired.
  • An API or storage option is unavailable. Check the installed Playwright version against the API’s “Added in” annotation and verify target-browser support, especially for OPFS and ephemeral WebKit contexts.
  • The state file appears in a Git change. Remove it from tracking, add its directory to .gitignore, and regenerate the session if the file may have been shared. A repository’s ignore rule does not remove a file already committed.

Or skip the browser setup

If what you need is a website screenshot rather than a reusable Playwright test session, ScreenshotNeo offers a one-request screenshot API and an MCP server for AI agents. It is not a replacement for Playwright’s authenticated test-context workflow.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I use the same saved state file for Chromium and Firefox?

Playwright documents reusing storage state, but authentication can be browser-specific. Validate the saved state in each target browser instead of assuming one file works everywhere.

Can Playwright save a browser session without logging in through the UI?

Yes. If the application has a suitable authentication endpoint, use an API request context to authenticate and save its state.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.