library-picturebook-activity/frontend/e2e/leai/generating.spec.ts
En 922f650365 feat: 添加乐读派(leai)集成模块及E2E测试基础设施
后端:
- 新增 leai 模块:认证、Webhook、数据同步、定时对账
- 新增 LeaiConfig/RestTemplateConfig/SchedulingConfig 配置
- 新增 FlywayRepairConfig 处理迁移修复
- 新增 V5__leai_integration.sql 迁移脚本
- 扩展所有实体类添加 tenantId 等字段
- 更新 SecurityConfig 放行 leai 公开接口
- 添加 application-test.yml 测试环境配置

前端:
- 添加乐读派认证 API (public.ts)
- 优化 Generating.vue 生成页
- 添加 Playwright E2E 测试配置及依赖
- 添加测试 fixtures、utils、mock-h5.html
- 添加 leai 模块完整 E2E 测试套件

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 21:52:32 +08:00

267 lines
8.7 KiB
TypeScript
Raw Permalink 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.

import { test, expect } from '@playwright/test'
/**
* P2: 生成进度页测试
*
* 测试 frontend/src/views/public/create/Generating.vue
* - INT 类型状态判断(-1=失败, 1/2=生成中, 3+=完成)
* - progress 百分比显示
* - 按钮跳转
*/
const API_BASE = process.env.API_BASE_URL || 'http://localhost:8580/api'
test.describe('生成进度页', () => {
test.describe('状态显示', () => {
test('status=1 PENDING — 显示生成中', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
code: 200,
data: {
id: 100,
status: 1,
progress: 0,
progressMessage: null,
remoteWorkId: 'wk_test_001',
title: '',
coverUrl: null,
},
}),
})
})
await page.goto('/p/create/generating/100')
// 应显示生成中
await expect(page.locator('text=正在生成你的绘本')).toBeVisible({ timeout: 10_000 })
// 不应显示进度条progress=0
await expect(page.locator('.progress-bar')).not.toBeVisible()
})
test('status=2 PROCESSING — 显示进度条和百分比', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
code: 200,
data: {
id: 101,
status: 2,
progress: 50,
progressMessage: '正在绘制插画...',
remoteWorkId: 'wk_test_002',
title: '',
coverUrl: null,
},
}),
})
})
await page.goto('/p/create/generating/101')
await expect(page.locator('text=正在绘制插画')).toBeVisible({ timeout: 10_000 })
await expect(page.locator('.progress-bar')).toBeVisible()
await expect(page.locator('text=50%')).toBeVisible()
})
test('status=3 COMPLETED — 显示完成', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
code: 200,
data: {
id: 102,
status: 3,
progress: 100,
progressMessage: null,
remoteWorkId: 'wk_test_003',
title: '测试绘本',
coverUrl: 'https://cdn.example.com/cover.png',
},
}),
})
})
await page.goto('/p/create/generating/102')
await expect(page.locator('text=绘本生成完成')).toBeVisible({ timeout: 10_000 })
await expect(page.locator('text=测试绘本')).toBeVisible()
await expect(page.locator('button:has-text("查看绘本")')).toBeVisible()
await expect(page.locator('button:has-text("继续创作")')).toBeVisible()
})
test('status=4 CATALOGED — 显示完成status>=3', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
code: 200,
data: {
id: 103,
status: 4,
progress: 100,
progressMessage: null,
remoteWorkId: 'wk_test_004',
title: '已编目绘本',
coverUrl: null,
},
}),
})
})
await page.goto('/p/create/generating/103')
await expect(page.locator('text=绘本生成完成')).toBeVisible({ timeout: 10_000 })
})
test('status=5 DUBBED — 显示完成status>=3', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
code: 200,
data: {
id: 104,
status: 5,
progress: 100,
progressMessage: null,
remoteWorkId: 'wk_test_005',
title: '已配音绘本',
coverUrl: null,
},
}),
})
})
await page.goto('/p/create/generating/104')
await expect(page.locator('text=绘本生成完成')).toBeVisible({ timeout: 10_000 })
})
test('status=-1 FAILED — 显示失败', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
code: 200,
data: {
id: 105,
status: -1,
progress: 30,
progressMessage: null,
remoteWorkId: 'wk_test_failed',
title: '',
coverUrl: null,
failReason: '图片处理失败',
},
}),
})
})
await page.goto('/p/create/generating/105')
await expect(page.locator('text=生成失败')).toBeVisible({ timeout: 10_000 })
await expect(page.locator('text=图片处理失败')).toBeVisible()
await expect(page.locator('button:has-text("重新创作")')).toBeVisible()
})
})
test.describe('状态轮询', () => {
test('从 PROCESSING → COMPLETED 自动更新', async ({ page }) => {
let callCount = 0
await page.route(`**/public/creation/*/status`, async (route) => {
callCount++
if (callCount <= 2) {
await route.fulfill({
status: 200,
body: JSON.stringify({
code: 200,
data: { id: 200, status: 2, progress: 60, progressMessage: 'AI正在创作...', title: '', coverUrl: null },
}),
})
} else {
await route.fulfill({
status: 200,
body: JSON.stringify({
code: 200,
data: { id: 200, status: 3, progress: 100, title: '轮询测试绘本', coverUrl: 'https://cdn.example.com/cover.png' },
}),
})
}
})
await page.goto('/p/create/generating/200')
// 先看到生成中
await expect(page.locator('text=AI正在创作')).toBeVisible({ timeout: 10_000 })
// 等待状态变为完成轮询间隔3秒
await expect(page.locator('text=绘本生成完成')).toBeVisible({ timeout: 15_000 })
await expect(page.locator('text=轮询测试绘本')).toBeVisible()
})
})
test.describe('按钮跳转', () => {
test('"查看绘本" 跳转到作品详情', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify({
code: 200,
data: { id: 300, status: 3, progress: 100, title: '跳转测试', coverUrl: null },
}),
})
})
await page.goto('/p/create/generating/300')
await expect(page.locator('text=绘本生成完成')).toBeVisible({ timeout: 10_000 })
await page.locator('button:has-text("查看绘本")').click()
await expect(page).toHaveURL(/\/p\/works\/300/, { timeout: 5000 })
})
test('"继续创作" 跳转到创作页', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify({
code: 200,
data: { id: 301, status: 3, progress: 100, title: '测试', coverUrl: null },
}),
})
})
await page.goto('/p/create/generating/301')
await expect(page.locator('text=绘本生成完成')).toBeVisible({ timeout: 10_000 })
await page.locator('button:has-text("继续创作")').click()
await expect(page).toHaveURL(/\/p\/create/, { timeout: 5000 })
})
test('"重新创作" 跳转到创作页', async ({ page }) => {
await page.route(`**/public/creation/*/status`, async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify({
code: 200,
data: { id: 302, status: -1, failReason: '测试失败' },
}),
})
})
await page.goto('/p/create/generating/302')
await expect(page.locator('text=生成失败')).toBeVisible({ timeout: 10_000 })
await page.locator('button:has-text("重新创作")').click()
await expect(page).toHaveURL(/\/p\/create/, { timeout: 5000 })
})
})
})