Files
DevFlow/tests/e2e/smoke.spec.ts
T
lxy efdf1e0282 新增: playwright e2e 测试基建与 tauri 垫片
invoke 条件垫片使前端可在无 tauri 容器下直连 dev server 做端到端验证
2026-10-01 02:41:21 +08:00

49 lines
2.3 KiB
TypeScript

import { test, expect } from 'playwright/test'
// 冒烟用例:纯浏览器(无 Tauri 壳)打开 vite dev server,
// 验证 Tauri IPC 垫片(src/mocks/tauri-shim.ts)能让应用完整挂载并路由不白屏。
// 全程只读内存假数据,不接触任何真实数据库。
// 主路由取样:AI 首页(默认路由)、任务、项目、知识库,覆盖四条典型挂载链
const ROUTES = ['/ai-home', '/tasks', '/projects', '/knowledge']
for (const route of ROUTES) {
test(`路由 ${route} 挂载且无未捕获异常`, async ({ page }) => {
const pageErrors: string[] = []
page.on('pageerror', (err) => {
pageErrors.push(`${err.name}: ${err.message}`)
})
await page.goto(`/#${route}`)
// app 完成挂载:main.ts 等路由就绪后才 mount,#app 有元素子节点即视为挂载成功
await expect(page.locator('#app > *').first()).toBeVisible({ timeout: 20_000 })
// 白屏判定:挂载壳内应有实质内容(空壳 fallback 文案也会超过 0,取较高阈值)
const html = await page.innerHTML('#app')
expect(html.length).toBeGreaterThan(200)
// ResizeObserver 循环超限是浏览器布局抖动的良性告警,与业务逻辑无关,过滤
const realErrors = pageErrors.filter(msg => !/ResizeObserver loop/i.test(msg))
expect(realErrors, `路由 ${route} 出现未捕获异常: ${realErrors.join(' | ')}`).toEqual([])
})
}
test('垫片注入生效且假数据链路可用', async ({ page }) => {
await page.goto('/#/ai-home')
await expect(page.locator('#app > *').first()).toBeVisible({ timeout: 20_000 })
// 浏览器里垫片必须已注入(否则所有 invoke 同步 TypeError)
const injected = await page.evaluate(() => Boolean((window as unknown as Record<string, unknown>).__TAURI_INTERNALS__))
expect(injected).toBe(true)
// 假数据链路:经 window 上的垫片 invoke 会话列表命令,验证分发到内存 fixture。
// 不 import @tauri-apps/api,page.evaluate 内联脚本解析不了裸模块名
const convCount = await page.evaluate(async () => {
const internals = (window as unknown as {
__TAURI_INTERNALS__: { invoke: (cmd: string) => Promise<unknown> }
}).__TAURI_INTERNALS__
const list = (await internals.invoke('ai_conversation_list')) as unknown[]
return list.length
})
expect(convCount).toBeGreaterThan(0)
})