feat: strengthen backup and mobile workflows
ci / gitleaks (push) Successful in 1m19s
ci / docker (push) Successful in 5m48s

This commit is contained in:
2026-09-16 21:12:52 +08:00
parent 6f38190c92
commit 6c234d7d82
64 changed files with 5059 additions and 635 deletions
+37
View File
@@ -0,0 +1,37 @@
import { chromium, type FullConfig } from '@playwright/test'
import { mkdirSync } from 'node:fs'
import path from 'node:path'
export default async function globalSetup(config: FullConfig) {
const projectName = process.env.DODO_E2E_PROJECT
if (!projectName) throw new Error('DODO_E2E_PROJECT is required')
const baseURL = config.projects[0]?.use.baseURL as string
const storageState = path.resolve('playwright-runtime', projectName, 'auth.json')
mkdirSync(path.dirname(storageState), { recursive: true })
const browser = await chromium.launch()
try {
const context = await browser.newContext({ baseURL })
const page = await context.newPage()
const readyDeadline = Date.now() + 90_000
let ready = false
while (Date.now() < readyDeadline) {
try {
const [health, frontend, proxy] = await Promise.all([
page.request.get('/health/ready'), page.request.get('/'), page.request.get('/api/v1/setup/status'),
])
if (health.ok() && frontend.ok() && proxy.ok()) { ready = true; break }
} catch {}
await new Promise(resolve => setTimeout(resolve, 250))
}
if (!ready) throw new Error('isolated frontend/backend/proxy did not become ready')
const initialized = await page.request.get('/api/v1/setup/status')
if (!initialized.ok()) throw new Error(`setup status failed: ${initialized.status()}`)
if ((await initialized.json()).initialized) throw new Error(`isolated ${projectName} runtime was already initialized`)
const response = await page.request.post('/api/v1/setup/initialize', { data: { username: `e2e-owner-${projectName}`, password: 'e2e-password-1234' } })
if (!response.ok()) throw new Error(`initialize failed: ${response.status()} ${await response.text()}`)
await context.storageState({ path: storageState })
} finally {
await browser.close()
}
}