You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何跨测试用例保存localStorage状态,避免重复身份验证?

Persisting LocalStorage Across Test Cases to Skip Repetitive Authentication

Absolutely, you can pull this off—persisting localStorage across test cases to avoid re-running auth flows is totally feasible, especially when API workarounds aren’t an option. Let’s break down how to implement your desired workflow for the most common testing frameworks:

Core Workflow Recap (Matched to Your Request)

First, let’s align with exactly what you want:

  1. Run a one-time login flow to populate localStorage with session data
  2. Save that localStorage state to a persistent file
  3. Load the saved state before every subsequent test to stay authenticated

Cypress (Super Straightforward)

Cypress has built-in tools to handle this with minimal code—here’s how:

  1. Save auth state once before all tests
    // In cypress/support/e2e.js or a dedicated setup spec
    before(() => {
      // Only run login if we don't already have saved state
      cy.readFile('cypress/fixtures/auth-state.json').catch(async () => {
        cy.visit('/login');
        cy.get('#username').type('your-valid-username');
        cy.get('#password').type('your-secure-password');
        cy.get('button[type="submit"]').click();
        // Wait for auth to fully complete (critical!)
        cy.url().should('include', '/dashboard');
        // Save entire localStorage to a fixture file
        cy.window().then(win => {
          const authState = {};
          for (let i = 0; i < win.localStorage.length; i++) {
            const key = win.localStorage.key(i);
            authState[key] = win.localStorage.getItem(key);
          }
          cy.writeFile('cypress/fixtures/auth-state.json', authState);
        });
      });
    });
    
  2. Load state before each test
    beforeEach(() => {
      cy.readFile('cypress/fixtures/auth-state.json').then(authState => {
        cy.window().then(win => {
          // Restore every key-value pair from the saved state
          Object.entries(authState).forEach(([key, value]) => {
            win.localStorage.setItem(key, value);
          });
        });
        // Navigate to the app to use the restored auth state
        cy.visit('/dashboard');
      });
    });
    
    Pro tip: Use Cypress’s session command (v12+) for even cleaner state management—it handles persistence under the hood with less boilerplate!

Playwright

Playwright uses contexts to isolate browser states, but you can serialize localStorage between contexts easily:

  1. Save auth state in a global setup
    // global-setup.js
    const { chromium } = require('playwright');
    const fs = require('fs');
    
    module.exports = async () => {
      const browser = await chromium.launch();
      const context = await browser.newContext();
      const page = await context.newPage();
      
      // Run login flow
      await page.goto('/login');
      await page.locator('#username').fill('your-username');
      await page.locator('#password').fill('your-password');
      await page.locator('button[type="submit"]').click();
      await page.waitForURL('/dashboard');
    
      // Extract and save localStorage
      const localStorage = await page.evaluate(() => {
        const state = {};
        for (let i = 0; i < localStorage.length; i++) {
          const key = localStorage.key(i);
          state[key] = localStorage.getItem(key);
        }
        return state;
      });
      fs.writeFileSync('./auth-state.json', JSON.stringify(localStorage));
    
      await browser.close();
    };
    
  2. Load state in your test file
    // your-test.spec.js
    const { test } = require('@playwright/test');
    const authState = require('./auth-state.json');
    
    test.beforeEach(async ({ page }) => {
      // Navigate to app first to initialize localStorage
      await page.goto('/');
      // Restore saved state
      await page.evaluate((state) => {
        Object.entries(state).forEach(([key, value]) => {
          localStorage.setItem(key, value);
        });
      }, authState);
      // Now you're authenticated—navigate to your target page
      await page.goto('/dashboard');
    });
    
    Bonus: Playwright’s storageState method can save/load full browser state (cookies + localStorage) if you need a more comprehensive solution.

Selenium WebDriver

For Selenium, you’ll handle serialization manually using JavaScript execution:

  1. Save auth state after login
    // Java example
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import com.google.gson.Gson;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class AuthUtils {
      public static void saveAuthState(WebDriver driver) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        // Extract all localStorage items
        Object localStorage = js.executeScript("""
          const state = {};
          for (let i = 0; i < localStorage.length; i++) {
            const key = localStorage.key(i);
            state[key] = localStorage.getItem(key);
          }
          return state;
        """);
        // Write to JSON file
        try (FileWriter writer = new FileWriter("auth-state.json")) {
          new Gson().toJson(localStorage, writer);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    
  2. Load state before tests
    import com.google.gson.Gson;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Map;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    
    public class TestSetup {
      public static void loadAuthState(WebDriver driver) {
        try (FileReader reader = new FileReader("auth-state.json")) {
          Map<String, String> authState = new Gson().fromJson(reader, Map.class);
          JavascriptExecutor js = (JavascriptExecutor) driver;
          // Restore each localStorage item
          for (Map.Entry<String, String> entry : authState.entrySet()) {
            js.executeScript("localStorage.setItem(arguments[0], arguments[1]);", 
                            entry.getKey(), entry.getValue());
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
        driver.get("/dashboard");
      }
    }
    

Key Things to Keep in Mind

  • Wait for auth completion: Always wait for a reliable signal (like the dashboard URL or an authenticated user element) before saving localStorage—race conditions will break your flow.
  • Token expiration: If your auth tokens have short lifespans, add logic to re-run the login setup periodically (e.g., once per test suite run).
  • Test isolation: For tests that need unauthenticated users, clear localStorage at the start of those tests to avoid cross-test contamination.

内容的提问来源于stack exchange,提问作者Arash Outadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:14:42