98 lines
3.5 KiB
JavaScript
98 lines
3.5 KiB
JavaScript
// round2 现状截图基线:本地真实栈(5174 -> 18080 Java),登录后逐页截图 + 收集 pageerror/console error。
|
|
// 用法:cd admin-frontend-vue && node scripts/round2-shots.mjs
|
|
import { chromium } from '@playwright/test'
|
|
import { mkdirSync } from 'node:fs'
|
|
|
|
const BASE = process.env.BASE_URL || 'http://localhost:5174/admin-vue'
|
|
const OUT = 'test-results/round2-baseline'
|
|
mkdirSync(OUT, { recursive: true })
|
|
|
|
const PAGES = [
|
|
['account-users', 'account/users'],
|
|
['account-menus', 'account/menus'],
|
|
['account-groups', 'account/groups'],
|
|
['asin-registry', 'asin-center/registry'],
|
|
['asin-invalid', 'asin-center/invalid'],
|
|
['asin-query', 'asin-center/query'],
|
|
['asin-categories', 'asin-center/categories'],
|
|
['asin-skip-price', 'asin-center/skip-price'],
|
|
['shop-keys', 'shop-center/keys'],
|
|
['shop-shops', 'shop-center/shops'],
|
|
['shop-data-tasks', 'shop-center/data-tasks'],
|
|
['records-history', 'records/history'],
|
|
['records-software-version', 'records/software-version'],
|
|
['records-digital-human-version', 'records/digital-human-version'],
|
|
['records-image-video-tasks', 'records/image-video-tasks'],
|
|
]
|
|
|
|
const browser = await chromium.launch({ channel: 'msedge', headless: true })
|
|
const context = await browser.newContext({ viewport: { width: 1440, height: 900 }, locale: 'zh-CN' })
|
|
const page = await context.newPage()
|
|
|
|
const problems = new Map() // page -> string[]
|
|
page.on('pageerror', (e) => {
|
|
const key = page.url()
|
|
const list = problems.get(key) || []
|
|
list.push(`pageerror: ${e.message}`)
|
|
problems.set(key, list)
|
|
})
|
|
page.on('console', (m) => {
|
|
if (m.type() === 'error') {
|
|
const key = page.url()
|
|
const list = problems.get(key) || []
|
|
list.push(`console.error: ${m.text().slice(0, 300)}`)
|
|
problems.set(key, list)
|
|
}
|
|
})
|
|
|
|
// 登录(真实 UI 表单)
|
|
async function ensureLoggedIn() {
|
|
await page.goto(`${BASE}/`, { waitUntil: 'networkidle' })
|
|
await page.waitForTimeout(600)
|
|
const loginVisible = await page.locator('#loginUsername').isVisible().catch(() => false)
|
|
if (loginVisible) {
|
|
await page.locator('#loginUsername').fill('admin')
|
|
await page.locator('#loginPassword').fill('admin123')
|
|
await page.locator('.btn-login').click()
|
|
// 等离开登录页(进入后台)
|
|
await page.waitForURL(/admin-vue\/(account|asin|shop|records)/, { timeout: 20000 }).catch(() => {})
|
|
await page.waitForTimeout(1200)
|
|
}
|
|
}
|
|
|
|
await ensureLoggedIn()
|
|
console.log('logged-in url:', page.url())
|
|
|
|
const report = []
|
|
for (const [name, path] of PAGES) {
|
|
const url = `${BASE}/${path}`
|
|
try {
|
|
await page.goto(url, { waitUntil: 'domcontentloaded' })
|
|
// 等页头或内容出现(不同页标题不同,抓第一个标题/内容容器)
|
|
await page.locator('.page-heading').first().waitFor({ state: 'visible', timeout: 12000 }).catch(() => {})
|
|
await page.waitForLoadState('networkidle').catch(() => {})
|
|
await page.waitForTimeout(500)
|
|
await page.screenshot({ path: `${OUT}/${name}.jpg`, type: 'jpeg', quality: 82 })
|
|
report.push(`ok ${name} ${url}`)
|
|
} catch (e) {
|
|
report.push(`FAIL ${name} ${url} :: ${String(e).slice(0, 200)}`)
|
|
}
|
|
}
|
|
|
|
console.log('\n=== screenshots ===')
|
|
console.log(report.join('\n'))
|
|
|
|
console.log('\n=== page errors (运行时异常,供排查) ===')
|
|
let anyError = false
|
|
for (const [url, list] of problems) {
|
|
const clean = url.replace(BASE, '')
|
|
if (list.length) {
|
|
anyError = true
|
|
console.log(`-- ${clean}`)
|
|
for (const l of [...new Set(list)]) console.log(' ', l)
|
|
}
|
|
}
|
|
if (!anyError) console.log('(无 pageerror/console.error)')
|
|
|
|
await browser.close()
|