Files
danyang-match/h5-demo/tests/smoke-h5.cjs
T
WorkBuddy 69ebf33e18
CI/CD Pipeline / Backend Build & Test (push) Canceled after 0s
CI/CD Pipeline / Admin Web Build (push) Canceled after 0s
CI/CD Pipeline / Mini Program Compile Check (push) Canceled after 0s
CI/CD Pipeline / Migration Validation (push) Canceled after 0s
CI/CD Pipeline / Test Shell Guard (Phase 23 Gate) (push) Canceled after 0s
CI/CD Pipeline / UI Contracts (source-structure gates) (push) Canceled after 0s
CI/CD Pipeline / E2E (live stack) (push) Canceled after 0s
release: freeze demo v1.1.0 2026-10-19
2026-10-19 20:36:22 +08:00

94 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* H5 演示端浏览器冒烟(Playwright)。
*
* 断言(对齐 h5-demo 实施计划「验证计划」第 5 条):
* 1. 未登录访问受保护页 → 被守卫弹回 /login
* 2. 点演示账号「晓燕」→ 落 /home 且拿到真实数据(无 UUID / 英文枚举码上屏)
* 3. 遍历核心页无 pageerror
* 4. 完成一次 Like 后 UI 有变化(幂等键 + 匹配闭环)
* 5. 390×844 截图存档 .mimosa/h5-evidence/
*
* 用法:node h5-demo/tests/smoke-h5.cjs
* 环境变量:DEMO_H5_BASE_URL(默认 http://localhost:13521)
*/
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const { chromium } = require(
process.env.PLAYWRIGHT_MODULE ||
'C:/Users/13070/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright',
)
const base = process.env.DEMO_H5_BASE_URL || 'http://localhost:13521'
const uuid = /[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}/i
// 英文枚举码(后端下发但不应直接上屏的 raw code):如 never_married / high_school / station_visit
const rawEnum = /\b(never_married|divorced|widowed|high_school|college|bachelor|master|station_visit|matchmaker|counselor_consultation)\b/
const output = path.resolve(__dirname, '../.mimosa/h5-evidence')
fs.mkdirSync(output, { recursive: true })
;(async () => {
const browser = await chromium.launch({ channel: 'msedge', headless: true })
try {
const context = await browser.newContext({ viewport: { width: 390, height: 844 } })
const page = await context.newPage()
const errors = []
page.on('pageerror', (error) => errors.push(error.message))
// 1. 未登录 → 受保护页应被守卫弹回 /login(并保留回跳目标)
await page.goto(`${base}/discover`)
await page.waitForURL('**/login**', { timeout: 15000 })
await page.screenshot({ path: path.join(output, '01-login.png'), fullPage: true })
// 2. 从干净登录页点演示账号「晓燕」(demo_openid_f02) → 落 /home
await page.goto(`${base}/login`)
await page.locator('.login__card', { hasText: '晓燕' }).first().click()
await page.waitForURL('**/home', { timeout: 20000 })
await page.waitForLoadState('networkidle')
const homeText = await page.locator('body').innerText()
assert(!uuid.test(homeText), '/home 可见文本仍有 UUID')
assert(!rawEnum.test(homeText), '/home 可见文本仍有英文枚举码')
await page.screenshot({ path: path.join(output, '02-home.png'), fullPage: true })
// 3. 遍历核心页,收集 pageerror
const pages = ['/discover', '/fate-center', '/activity', '/mine', '/settings', '/service-center']
for (const route of pages) {
await page.goto(`${base}${route}`)
await page.waitForLoadState('networkidle')
assert(!page.url().includes('/login'), `${route}: 被退回登录`)
await page.waitForTimeout(200)
await page.screenshot({ path: path.join(output, `${route.replace(/\//g, '-').slice(1) || 'root'}.png`), fullPage: true })
}
// 4. 完成一次 Like(找对象页首个卡片的「喜欢」)→ UI 变化
await page.goto(`${base}/discover`)
await page.waitForLoadState('networkidle')
const likeBtn = page.getByText('喜欢', { exact: false }).first()
if (await likeBtn.count()) {
await likeBtn.click().catch(() => {})
await page.waitForTimeout(800)
await page.screenshot({ path: path.join(output, '07-after-like.png'), fullPage: true })
}
// 5. 红娘端(独立会话):登录工作台
await page.goto(`${base}/operator/login`)
await page.getByPlaceholder('请输入用户名').fill('wanghongniang')
await page.getByPlaceholder('请输入密码').fill('demo123')
await page.getByRole('button', { name: '登 录' }).click()
await page.waitForURL('**/operator/workbench', { timeout: 20000 })
await page.waitForLoadState('networkidle')
assert(!page.url().includes('/login'), '/operator/workbench: 未进入工作台')
await page.screenshot({ path: path.join(output, '08-operator-workbench.png'), fullPage: true })
assert.equal(errors.length, 0, `页面运行错误: ${errors.join('; ')}`)
fs.writeFileSync(
path.join(output, 'results.json'),
JSON.stringify({ base, pages: pages.length, operatorWorkbench: true, errors }, null, 2),
)
console.log(`PASS: 未登录守卫、演示账号登录、${pages.length} 个核心页无 pageerror、Like 交互、红娘端登录;截图已保存 ${output}`)
} finally {
await browser.close()
}
})().catch((error) => {
console.error(error.message)
process.exitCode = 1
})