UNPKG

playwright-persona

Version:

Authentication in Playwright using personas.

65 lines (64 loc) 2.38 kB
import * as fs from "node:fs"; import * as path from "node:path"; import { invariant } from "outvariant"; //#region src/index.ts const STORAGE_STATE_DIRECTORY = path.join(process.cwd(), "./playwright/.auth/"); function definePersona(name, options) { return { name, createSession: options.createSession, verifySession: options.verifySession, destroySession: options.destroySession }; } function combinePersonas(...personas) { return async ({ browser, context, page }, use, testInfo) => { const createSessionFilePath = (persona) => { return path.join(STORAGE_STATE_DIRECTORY, `./${testInfo.testId}-${persona.name}.json`); }; const createSession = async (persona) => { const session = await persona.createSession({ page }, testInfo); const sessionFilePath = createSessionFilePath(persona); await context.storageState({ path: sessionFilePath }); const sessionFile = await readSessionFile(sessionFilePath); sessionFile.session = session; await fs.promises.writeFile(sessionFilePath, JSON.stringify(sessionFile, null, 2)); return session; }; await use(async (options) => { const persona = personas.find((persona) => { return persona.name === options.as; }); invariant(persona, "Failed to authenticate: cannot find persona by name \"%s\" (known personas: %s)", options.as, personas.join(", ")); const sessionFilePath = createSessionFilePath(persona); if (fs.existsSync(sessionFilePath)) { const sessionFile = await readSessionFile(sessionFilePath); const newContext = await browser.newContext({ storageState: sessionFile }); const newPage = await newContext.newPage(); await newContext.setStorageState(sessionFile); return persona.verifySession({ page: newPage, session: sessionFile.session }, testInfo).then(async () => { await context.setStorageState(sessionFile); return sessionFile.session; }).catch(async () => { await persona.destroySession?.({ page, session: sessionFile.session }, testInfo); return createSession(persona); }).finally(async () => { await newContext.close(); }); } return createSession(persona); }); }; } async function readSessionFile(filePath) { const textContent = await fs.promises.readFile(filePath, "utf8"); return JSON.parse(textContent); } //#endregion export { combinePersonas, definePersona };