45 lines
1.4 KiB
JavaScript
45 lines
1.4 KiB
JavaScript
|
|
/**
|
||
|
|
* Worker-scoped auth: one API login per worker; persist rotated refresh cookies between tests.
|
||
|
|
*/
|
||
|
|
import { test as base, request } from '@playwright/test'
|
||
|
|
|
||
|
|
const BASE = (process.env.NEXUS_E2E_BASE || 'https://api.synaglobal.vip').replace(/\/$/, '')
|
||
|
|
const USER = process.env.NEXUS_E2E_USER || 'admin'
|
||
|
|
const PASS = process.env.NEXUS_E2E_PASSWORD || ''
|
||
|
|
|
||
|
|
/** @type {import('@playwright/test').StorageState | null} */
|
||
|
|
let workerStorageState = null
|
||
|
|
|
||
|
|
async function ensureWorkerStorageState() {
|
||
|
|
if (workerStorageState) return workerStorageState
|
||
|
|
if (!PASS) throw new Error('Set NEXUS_E2E_PASSWORD for E2E')
|
||
|
|
const ctx = await request.newContext({ baseURL: BASE, ignoreHTTPSErrors: true })
|
||
|
|
try {
|
||
|
|
const res = await ctx.post('/api/auth/login', {
|
||
|
|
data: { username: USER, password: PASS },
|
||
|
|
})
|
||
|
|
if (!res.ok()) {
|
||
|
|
throw new Error(`Worker login failed (${res.status()}): ${await res.text()}`)
|
||
|
|
}
|
||
|
|
workerStorageState = await ctx.storageState()
|
||
|
|
return workerStorageState
|
||
|
|
} finally {
|
||
|
|
await ctx.dispose()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export const test = base.extend({
|
||
|
|
context: async ({ browser }, use) => {
|
||
|
|
const storageState = await ensureWorkerStorageState()
|
||
|
|
const context = await browser.newContext({ storageState })
|
||
|
|
try {
|
||
|
|
await use(context)
|
||
|
|
} finally {
|
||
|
|
workerStorageState = await context.storageState()
|
||
|
|
await context.close()
|
||
|
|
}
|
||
|
|
},
|
||
|
|
})
|
||
|
|
|
||
|
|
export { expect } from '@playwright/test'
|