Working with Local Storage in Playwright

Master Local Storage in Playwright to create faster, reliable, and stateful automated tests across real-world web scenarios.

Written by Nithya Mani Nithya Mani
Reviewed by Ashwani Pathak Ashwani Pathak
Last updated: 23 July 2026 10 min read

Key Takeaways

  • Local Storage lets you start Playwright tests from a predefined application state, reducing repetitive setup and keeping test cases focused.
  • Reading, updating, and reusing Local Storage helps simulate real user sessions while improving test speed and maintainability.
  • Combining Playwright with BrowserStack Automate validates Local Storage behavior across real browsers and devices for more reliable test coverage.

One thing I quickly learned while writing Playwright tests is that logging in before every test gets repetitive. It slows the suite down and adds setup that has nothing to do with what I’m trying to test. That’s where Local Storage becomes useful.

Instead of recreating the same application state every time, I can read, update, and reuse data that’s already stored in the browser. I can keep a user logged in, save preferences, or start a test from a specific state without repeating the same steps.

In this guide, I’ll show you how to access, modify, and verify Local Storage in Playwright. You’ll also learn a few practical ways to use it to write faster and more reliable tests.

What is Local Storage?

Local Storage is a browser feature that lets websites save small amounts of data directly on a user’s device. It stores information as key-value pairs and keeps that data available even after the browser is closed or the computer is restarted.

When I’m writing Playwright tests, I think of Local Storage as a way to control the starting state of my application. Instead of logging in before every test or recreating the same user preferences, I can read or update the stored values and begin testing exactly where I need to. A few characteristics make Local Storage particularly useful:

  • The data persists across browser sessions: Unlike session storage, the values remain until they’re explicitly removed by the application or the user.
  • It can store more data than cookies: Most browsers allow around 5 MB of storage per origin, making it suitable for user preferences, application settings, and other client-side data.
  • The data stays in the browser: Since Local Storage isn’t sent with every HTTP request like cookies, it’s useful for storing information that only the client needs.
  • Everything is stored as key-value pairs: Both keys and values are saved as strings, making the API simple to read and update during automation.

Playwright Testing

Accessing Local Storage in Playwright

I’ve realised that the easiest way to access Local Storage in Playwright is with page.evaluate(). It lets me run JavaScript inside the browser, so I can read or inspect the values stored by the application. Here is how you can do it too:

Read All Local Storage Values

Start by opening the page you want to test. Then use page.evaluate() to loop through every Local Storage entry and return it as a JavaScript object.

await page.goto('https://example.com');



const localStorageData = await page.evaluate(() => {

  const data = {};



  for (let i = 0; i < localStorage.length; i++) {

    const key = localStorage.key(i);

    data[key] = localStorage.getItem(key);

  }



  return data;

});



console.log(localStorageData);

read all local storage values

This returns every stored key and value, making it easy to inspect the application’s current state or verify stored data in your assertions.

Read a Single Value

If you only need one item, you can retrieve it directly instead of reading everything.

const userRole = await page.evaluate(() =>

  localStorage.getItem('userRole')

);



console.log(userRole); // admin

read a single value

This approach is useful when your test depends on a specific value, such as a user role, theme preference, or authentication token.

Setting Local Storage Values

I’ll be honest, most of the time I update Local Storage just to skip the repetitive setup, not test the API itself.

For example, if every test starts by logging in, selecting a theme, or dismissing an onboarding screen, I can store those values before the page loads and begin testing the feature I’m actually interested in. I’ll help you with these values:

Add or Update Storage Values

You can write to Local Storage with page.evaluate() and localStorage.setItem().

await page.goto('https://example.com');



await page.evaluate(() => {

  localStorage.setItem('theme', 'dark');

  localStorage.setItem('isLoggedIn', 'true');

});

localstorage set values

Set Multiple Values at Once

If your application relies on several Local Storage entries, it’s easier to add them together instead of making multiple calls.

await page.evaluate(() => {

  const data = {

    userToken: 'abc123xyz',

    preferences: JSON.stringify({

      newsletter: true,

    }),

  };



  for (const [key, value] of Object.entries(data)) {

    localStorage.setItem(key, value);

  }

});

set multiple values

Setting these values directly makes the test shorter and keeps the focus on the feature you’re trying to validate, rather than the setup required to reach it.

Modifying and Removing Data from Local Storage

As your test suite grows, you’ll also need to update existing data or remove it completely to recreate different user scenarios. For making changes to removing data, you use the same page.evaluate() method.

Modify an Exisiting Value

Updating a value works the same way as creating one. If the key already exists, localStorage.setItem() replaces the previous value.

await page.evaluate(() => {

  localStorage.setItem('user_token', 'new_token_value');

});

localstorage modify existing

Remove a Single Item

If a test only depends on one value being removed, use localStorage.removeItem().

await page.evaluate(() => {

  localStorage.removeItem('user_token');

});

localstorage remove single

Clear Everything

Sometimes it’s easier to start with a clean browser state. Instead of deleting keys one by one, you can clear the entire Local Storage for the current origin.

await page.evaluate(() => {

  localStorage.clear();

});

localstorage clear all

I usually do this at the beginning of a test when I want to make sure no data from previous runs affects the result. It creates a predictable starting point and helps avoid failures caused by leftover browser state.

Reusing Browser State Across Playwright Tests

If multiple tests need the same logged-in user or application state, I don’t recreate it every time. Instead, I save the browser state once and reuse it across the rest of the suite.

Playwright’s storageState() makes this easy by saving cookies, Local Storage, and IndexedDB together. The next test can load that state and start exactly where the previous one left off.

Save the Current Browser State

After completing actions such as signing in or setting up user preferences, save the current browser state to a file.

The file contains everything needed to recreate the same session later, including Local Storage values and authentication cookies.

await context.storageState({

  path: 'localStorageState.json',

});

save browser state

Start a New Test from the Saved State

Instead of repeating the same setup, create a new browser context and load the saved state.

const context = await browser.newContext({

  storageState: 'localStorageState.json',

});

start from saved state

I usually save and reuse browser state when:

  • Most tests require the same authenticated user.
  • Setting up the application takes longer than the feature I’m testing.
  • I want every test to begin from a consistent state without repeating UI actions.
  • Running larger test suites where reducing setup time has a noticeable impact on execution time.

How Can You Use These Local Storage Values?

Now that you have learned all actions with Playwright’s local storage values, you can access, edit or delete, and reuse these values. Now is a good time to understand the best use cases for these values:

  • Skipping Repetitive Logins: This is why I use it the most. You can store authentication tokens or session data in Local Storage to bypass login steps, helping you save time and improve efficiency.
  • Testing User Preferences: You can use Local Storage to store user-specific settings like theme, language, or layout preferences to validate personalized experiences.
  • Simulating Authenticated User Flows: Preserve Local Storage data to test features that are accessible only to your logged-in users.
  • Maintaining Application State Across Tests: Mimic real user interactions into your testing suite by reusing Local Storage to carry over states like cart items or form progress between test steps.
  • Bypassing Intro or Consent Screens: Save Local Storage after dismissing cookie consent or onboarding modals to skip them in future tests and focus on core functionality.
  • Testing Role-Based Access: Store and reuse different Local Storage states for various user roles (like admin or user) to test access control and role-specific features.

How to Build More Reliable Playwright Tests with Local Storage

The way you manage Local Storage can have a noticeable impact on the stability of your test suite. A few good practices will help you reduce flaky tests, shorten execution time, and make failures easier to investigate as your automation grows:

  • Start Every Test from a Predictable State: Sharing Local Storage between tests often leads to inconsistent results. Create a fresh browser context or reset Local Storage before each test to ensure every test begins with the same conditions.
  • Reuse Browser State Instead of Repeating Setup: If multiple tests require the same logged-in user or application configuration, save the browser state with storageState() and reuse it across the suite.
  • Test with Realistic Data: Add your Local Storage with values your application would normally create instead of artificial test data. Tests that mirror real user behaviour are more likely to catch issues before they reach production.
  • Verify the Data Your Application Stores: Don’t assume values are written correctly. Check that Local Storage contains the expected keys and values after important user actions.
  • Keep Test Data Isolated: Only read or update Local Storage for the application you’re testing. Keeping data isolated to the correct browser context and origin prevents unexpected interactions between different applications or environments.
  • Avoid Storing Sensitive Information: Even in test environments, avoid placing passwords, personal information, or other sensitive data in Local Storage. Since browser storage is easily accessible through JavaScript, using temporary or masked test data is a safer approach.

Talk to an Expert

Conclusion

One of the biggest advantages I’ve found with Local Storage is that it lets me spend less time preparing a test and more time validating the feature I actually care about. Instead of repeating the same login flow or user setup, I can start from the exact application state I need and keep my tests focused.

As your Playwright suite grows, that small change has a noticeable impact. Tests become faster, easier to maintain, and less prone to failures caused by repetitive setup. Pairing this with BrowserStack Automate lets you run those same tests across real browsers and devices, so you’re not just saving time locally. You’re building confidence that your application behaves consistently for every user.

Try BrowserStack Now

Version History

  1. Jul 22, 2026 Current Version

    Added key takeaways, references and sections on building reliable tests, how to use storage value etc.

    Ashwani Pathak
    Reviewed by Ashwani Pathak Automation Expert
Tags
Automation Testing Real Device Cloud Website Testing
Nithya Mani
Nithya Mani

Lead Engineer

Nithya Mani is a Lead Engineer with 8+ years of experience in customer solutions. She specializes in creating tailored testing solutions that address real customer needs and optimize workflows.

Automation Tests on Real Devices & Browsers
Seamlessly Run Automation Tests on 3500+ real Devices & Browsers