Playwright中Basic Auth无法存入storageState致测试失败求助
问题:Playwright复用Basic Auth失败,Setup通过但测试用例报错
搭建Playwright项目时,尝试通过项目依赖复用Basic Auth用于测试,Setup测试始终通过,但示例测试用例报错:page.goto: net::ERR_INVALID_AUTH_CREDENTIALS at https://the-internet.herokuapp.com/basic_auth。
相关代码
配置文件
// @ts-check const {defineConfig, devices} = require('@playwright/test'); /** * Read environment variables from file. * https://github.com/motdotla/dotenv */ // require('dotenv').config(); /** * @see https://playwright.dev/docs/test-configuration */ module.exports = defineConfig({ testDir: './tests', /* Run tests in files in parallel */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: 'html', /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ baseURL: 'https://the-internet.herokuapp.com/basic_auth', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', }, /* Configure projects for major browsers */ projects: [ { name: 'setup', testDir: './', testMatch: 'globalSetup.js' }, { name: 'testrun', dependencies: ['setup'], use: { storageState: './LoginAuth.json' } }, ], }
globalSetup代码
test('setup', async ({ page }) => { const authHeaders = 'Basic ' + Buffer.from('admin:admin').toString('base64'); await page.setExtraHTTPHeaders({ Authorization : authHeaders }) await page.goto(''); await expect(page.getByText('Congratulations!')).toBeVisible(); await page.context().storageState({ path: './LoginAuth.json' }) })
测试用例
test('new fckn test', async ({page}) => { await page.goto(''); await expect(page.getByText('Congratulations!')).toBeVisible(); })
问题原因
storageState 只会存储Cookie、LocalStorage等浏览器存储数据,不会保存你通过setExtraHTTPHeaders设置的Authorization请求头。Setup测试中直接设置了请求头所以能成功,但测试用例读取storageState后并没有继承这个请求头,导致认证失败。
解决方案
方法一:在测试项目全局配置HTTP头
直接在testrun项目的配置中添加extraHTTPHeaders,让所有测试自动携带认证头:
// 配置文件中testrun项目部分修改为 { name: 'testrun', dependencies: ['setup'], use: { storageState: './LoginAuth.json', extraHTTPHeaders: { 'Authorization': 'Basic ' + Buffer.from('admin:admin').toString('base64') } } },
方法二:利用Playwright原生HTTP认证机制(推荐)
在globalSetup中创建带有Basic Auth的context,Playwright会将认证信息存入storageState,测试用例读取后自动复用:
修改globalSetup.js:
test('setup', async ({ browser }) => { // 创建携带Basic Auth的context const context = await browser.newContext({ httpCredentials: { username: 'admin', password: 'admin' } }); const page = await context.newPage(); await page.goto(''); await expect(page.getByText('Congratulations!')).toBeVisible(); // 保存context状态到文件 await context.storageState({ path: './LoginAuth.json' }); await context.close(); });
配置文件无需额外修改,testrun项目只需读取storageState即可自动携带认证信息。
方法三:在测试用例中直接设置认证
如果需要灵活控制,可以在测试用例中给当前context设置HTTP凭据:
test('new fckn test', async ({page, context}) => { await context.setHTTPCredentials({ username: 'admin', password: 'admin' }); await page.goto(''); await expect(page.getByText('Congratulations!')).toBeVisible(); });
内容的提问来源于stack exchange,提问作者Otis von Lilien
相关产品推荐
相关产品推荐

