import { test, expect } from '@playwright/test' import fs from 'node:fs' import path from 'node:path' const evidenceDir = process.env.E2E_EVIDENCE_DIR ? path.resolve(process.env.E2E_EVIDENCE_DIR) : path.resolve(__dirname, '../../../evidence/run-unknown') const ensureDir = (dir: string) => { fs.mkdirSync(dir, { recursive: true }) } const appendLog = (filePath: string, line: string) => { ensureDir(path.dirname(filePath)) fs.appendFileSync(filePath, `${line}\n`, 'utf8') } const consoleLogPath = path.join(evidenceDir, 'e2e/console.log') const networkLogPath = path.join(evidenceDir, 'e2e/network.log') const logConsole = (type: string, text: string) => { appendLog(consoleLogPath, `[${new Date().toISOString()}] ${type}: ${text}`) } const logNetwork = (line: string) => { appendLog(networkLogPath, `[${new Date().toISOString()}] ${line}`) } test.beforeEach(async ({ page }) => { page.on('console', (msg) => logConsole(msg.type(), msg.text())) page.on('pageerror', (err) => logConsole('pageerror', err.message)) page.on('requestfailed', (req) => { logNetwork(`requestfailed ${req.method()} ${req.url()} ${req.failure()?.errorText ?? ''}`) }) page.on('response', (res) => { const url = res.url() if (url.includes('/api/')) { logNetwork(`response ${res.status()} ${res.request().method()} ${url}`) } }) }) test.describe.serial('Admin E2E (real backend)', () => { test('dashboard renders without demo banner', async ({ page }) => { await page.goto('/') await expect(page.getByRole('heading', { name: '运营概览' })).toBeVisible() await expect(page.getByText('演示模式')).toHaveCount(0) const screenshotPath = path.join(evidenceDir, 'e2e/screenshots/dashboard.png') ensureDir(path.dirname(screenshotPath)) await page.screenshot({ path: screenshotPath, fullPage: true }) }) test('activity users list reflects backend response', async ({ page }) => { await page.goto('/users') await page.locator('[data-test="tab-activity"]').click() const response = await page.waitForResponse((res) => res.url().includes('/api/v1/me/invited-friends') && res.request().method() === 'GET' ) let payload: any = {} try { payload = await response.json() } catch { payload = {} } const data = Array.isArray(payload?.data) ? payload.data : [] if (data.length > 0) { await expect(page.locator('[data-test="activity-users-list"]')).toBeVisible() const rows = page.locator('[data-test="activity-user-row"]') await expect(rows).toHaveCount(data.length) } else { await expect(page.locator('[data-test="activity-users-empty"]')).toBeVisible() } const screenshotPath = path.join(evidenceDir, 'e2e/screenshots/activity-users.png') ensureDir(path.dirname(screenshotPath)) await page.screenshot({ path: screenshotPath, fullPage: true }) }) test('forbidden page displays failure path', async ({ page }) => { await page.goto('/403') await expect(page.getByText('当前账号无权限访问该页面')).toBeVisible() const screenshotPath = path.join(evidenceDir, 'e2e/screenshots/forbidden.png') ensureDir(path.dirname(screenshotPath)) await page.screenshot({ path: screenshotPath, fullPage: true }) }) })