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

如何导出Playwright登录函数供其他测试文件复用登录态?

Playwright 登录函数复用、跨用例共享登录态实现

项目文件夹结构参考

改造login.js导出可复用登录逻辑

你当前写的Login函数存在两个问题:每次调用都会新开独立浏览器上下文、没有返回登录态相关对象、没有持久化认证信息,无法给其他用例复用。按如下代码修改即可:

// login.js
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');

async function Login(options = {}) {
  const defaultConfig = {
    persistState: true,
    stateSavePath: './auth/login-state.json',
    headless: false
  }
  const config = Object.assign(defaultConfig, options);

  // 自动创建登录态存储目录
  const authDir = path.dirname(config.stateSavePath);
  if (!fs.existsSync(authDir)) fs.mkdirSync(authDir, { recursive: true });

  const browser = await chromium.launch({
    headless: config.headless,
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
  });
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('http://test.local/');

  // 补全你的实际登录操作:输入账号密码、点击登录、等待登录成功标识加载
  // 示例:
  // await page.getByPlaceholder('请输入账号').fill('test001');
  // await page.getByPlaceholder('请输入密码').fill('test123456');
  // await page.getByRole('button', {name: '立即登录'}).click();
  // await page.waitForSelector('.user-avatar', { timeout: 10000 });

  // 持久化存储登录态(包含所有cookies、localStorage、sessionStorage认证信息)
  if (config.persistState) {
    await context.storageState({ path: config.stateSavePath });
  }

  return {
    browser,
    context,
    page,
    cookies: await context.cookies()
  }
}

module.exports = { Login };

测试用例复用登录态的两种方式

根据你的测试场景选对应方式即可。

方式1:直接调用Login函数接续操作

适合单文件调试、需要和登录流程在同一个上下文接续执行的场景,example.spec.js写法如下:

// example.spec.js
const { expect } = require('@playwright/test');
const { Login } = require('./login.js');

test('登录后访问个人中心', async () => {
  // 执行登录,拿到已带登录态的page、context实例
  const { page, browser, cookies } = await Login();
  // 此处可以直接打印cookies查看,所有登录相关cookie都已生成
  console.log('登录后cookies:', cookies);

  // 直接访问需要登录权限的页面,自动携带所有认证信息
  await page.goto('http://test.local/user/center');
  await expect(page.locator('.username')).toBeVisible();

  // 测试结束后关闭浏览器
  await browser.close();
})

如果需要自定义请求头,直接在context上设置即可,设置后该上下文下所有请求都会自动携带对应头信息:

const { context } = await Login();
await context.setExtraHTTPHeaders({
  'X-Test-Env': 'test',
  'Authorization': 'Bearer xxx'
})

方式2:持久化登录态全局复用(推荐多测试文件场景使用)

这种方式只需要执行一次登录,所有测试用例都可以共享登录结果,不用每个用例重复走登录流程,执行效率更高,是Playwright官方推荐的全局认证方案。

  1. 新增全局启动文件global-setup.js,在所有测试执行前自动完成登录、生成持久化登录态文件:
// global-setup.js
const { Login } = require('./login.js');

async function globalSetup() {
  const { browser } = await Login({ headless: true });
  await browser.close();
}

module.exports = globalSetup;
  1. 在playwright.config.js中配置全局登录态和启动逻辑:
// playwright.config.js
const { defineConfig } = require('@playwright/test');

module.exports = defineConfig({
  use: {
    baseURL: 'http://test.local',
    // 所有用例默认加载已存储的登录态
    storageState: './auth/login-state.json',
  },
  // 所有测试运行前自动执行一次登录
  globalSetup: require.resolve('./global-setup.js'),
})

配置完成后,你写所有测试用例时不需要额外写登录逻辑,默认拿到的page实例就已经携带全部cookies和登录态:

// example.spec.js 全局登录态下的用例写法
const { test, expect } = require('@playwright/test');

test('访问订单列表页', async ({ page }) => {
  // 无需手动登录,直接访问需要权限的页面
  await page.goto('/order/list');
  await expect(page.getByText('我的订单')).toBeVisible();
})

注意:如果需要在多个用例间复用同一个浏览器上下文不重启,把Login函数生成的browser、context实例挂在全局对象上复用即可,需要注意用例执行顺序,避免测试数据互相污染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:33:23