diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index f095639de1..6ceade1fc6 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -38,6 +38,7 @@ import type { BrowserType } from './browserType'; import { Artifact } from './artifact'; import { APIRequestContext } from './fetch'; import { createInstrumentation } from './clientInstrumentation'; +import { rewriteErrorMessage } from '../utils/stackTrace'; export class BrowserContext extends ChannelOwner implements api.BrowserContext { _pages = new Set(); @@ -347,6 +348,17 @@ export class BrowserContext extends ChannelOwner } } +async function prepareStorageState(options: BrowserContextOptions): Promise { + if (typeof options.storageState !== 'string') + return options.storageState; + try { + return JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')); + } catch (e) { + rewriteErrorMessage(e, `Error reading storage state from ${options.storageState}:\n` + e.message); + throw e; + } +} + export async function prepareBrowserContextParams(options: BrowserContextOptions): Promise { if (options.videoSize && !options.videosPath) throw new Error(`"videoSize" option requires "videosPath" to be specified`); @@ -357,7 +369,7 @@ export async function prepareBrowserContextParams(options: BrowserContextOptions viewport: options.viewport === null ? undefined : options.viewport, noDefaultViewport: options.viewport === null, extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined, - storageState: typeof options.storageState === 'string' ? JSON.parse(await fs.promises.readFile(options.storageState, 'utf8')) : options.storageState, + storageState: await prepareStorageState(options), }; if (!contextParams.recordVideo && options.videosPath) { contextParams.recordVideo = { diff --git a/tests/browsercontext-storage-state.spec.ts b/tests/browsercontext-storage-state.spec.ts index 59aa16a296..c6975f00bf 100644 --- a/tests/browsercontext-storage-state.spec.ts +++ b/tests/browsercontext-storage-state.spec.ts @@ -194,3 +194,20 @@ it('should not restore localStorage twice', async ({ contextFactory }) => { await context.close(); }); + +it('should handle missing file', async ({ contextFactory }, testInfo) => { + const file = testInfo.outputPath('does-not-exist.json'); + const error = await contextFactory({ + storageState: file, + }).catch(e => e); + expect(error.message).toContain(`Error reading storage state from ${file}:\nENOENT`); +}); + +it('should handle malformed file', async ({ contextFactory }, testInfo) => { + const file = testInfo.outputPath('state.json'); + fs.writeFileSync(file, 'not-json', 'utf-8'); + const error = await contextFactory({ + storageState: file, + }).catch(e => e); + expect(error.message).toContain(`Error reading storage state from ${file}:\nUnexpected token o in JSON at position 1`); +});