import { test as base, expect, type Page } from '@playwright/test'; async function attachFrontFailureArtifacts( page: Page, testInfo: { status?: string; attach: (name: string, body: Buffer) => Promise; } ) { const st = testInfo.status; if (st === 'passed' || st === 'skipped') return; try { const snap = await page.evaluate(() => ({ OrgSwitchDebug: window.localStorage.getItem('OrgSwitchDebug'), CurrentOrgId: window.localStorage.getItem('CurrentOrgId'), path: window.location.pathname, })); await testInfo.attach( 'front-localstorage-snapshot.json', Buffer.from(JSON.stringify(snap, null, 2), 'utf8') ); } catch { /* 页面可能已关闭 */ } } /** * auto fixture:挂载 console / PageError / requestfailed(含 vConsole 镜像到 console 的输出), * 仅在用例失败时附加 browser-console-tail.txt 与 OrgSwitchDebug 快照。 */ export const test = base.extend<{ _frontLogs: void }>({ _frontLogs: [ async ({ page }, use, testInfo) => { const lines: string[] = []; const push = (line: string) => { lines.push(line); if (lines.length > 400) lines.splice(0, lines.length - 400); }; page.on('console', (msg) => { const loc = msg.location(); const where = loc.url && loc.lineNumber != null ? ` ${loc.url}:${loc.lineNumber}` : ''; push(`[browser:${msg.type()}] ${msg.text()}${where}`); }); page.on('pageerror', (err) => { push(`[pageerror] ${err.stack || err.message}`); }); page.on('requestfailed', (req) => { push( `[requestfailed] ${req.method()} ${req.url()} ${req.failure()?.errorText ?? ''}` ); }); await use(undefined); await attachFrontFailureArtifacts(page, testInfo); if (testInfo.status !== 'passed' && testInfo.status !== 'skipped') { const tail = lines.slice(-200).join('\n'); if (tail.length > 0) { await testInfo.attach( 'browser-console-tail.txt', Buffer.from(tail, 'utf8') ); } } }, { auto: true }, ], }); export { expect };