journey-03-book-generate.spec.ts 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * 关键旅程 E2E 测试 03: 书籍生成完整流水线
  3. * Journey: 预估字数 → 检测书籍类型 → 创建书籍 → 查询进度 → 获取书籍列表
  4. */
  5. import { test, expect } from '@playwright/test';
  6. import { apiGet, apiPost, initApiClient, disposeApiClient, setAuthToken } from '../../../helpers/api-client';
  7. const FRONTEND_URL = process.env.FRONTEND_URL || 'http://localhost:5173';
  8. test.describe('关键旅程 03: 书籍生成流水线', () => {
  9. let phone: string;
  10. let authToken: string;
  11. let bookId: string;
  12. test.beforeAll(async () => {
  13. await initApiClient();
  14. phone = `138${String(Date.now()).slice(-8)}`;
  15. await apiPost('/api/auth/send-code', { phone });
  16. const loginRes = await apiPost('/api/auth/login', { phone, code: '123456' });
  17. authToken = loginRes.data?.token;
  18. setAuthToken(authToken);
  19. });
  20. test.afterAll(async () => {
  21. await disposeApiClient();
  22. });
  23. test('C03-1: 预估字数和时长', async () => {
  24. const res = await apiPost('/api/book-generator/langgraph/estimate', {
  25. topic: '人工智能发展史',
  26. wordCount: 50000,
  27. });
  28. expect(res.code).toBe(0);
  29. expect(res.data?.estimatedCost).toBeGreaterThan(0);
  30. expect(res.data?.estimatedDuration).toBeGreaterThan(0);
  31. });
  32. test('C03-2: 检测书籍类型', async () => {
  33. const res = await apiPost('/api/book-generator/langgraph/detect-book-type', {
  34. topic: '人工智能简史',
  35. });
  36. expect(res.code).toBe(0);
  37. expect(['技术', '科普', '学术', '其他']).toContain(res.data?.bookType);
  38. });
  39. test('C03-3: 创建书籍', async () => {
  40. const res = await apiPost('/api/book-generator/langgraph/create', {
  41. title: `自动化测试书籍_${Date.now()}`,
  42. topic: '人工智能发展史',
  43. wordCount: 30000,
  44. strategy: 'deep-plan-parallel',
  45. });
  46. expect(res.code).toBe(0);
  47. bookId = res.data?.bookId;
  48. expect(bookId).toBeDefined();
  49. });
  50. test('C03-4: 获取书籍详情', async () => {
  51. if (!bookId) return test.skip();
  52. const res = await apiGet(`/api/book-generator/langgraph/books/${bookId}`);
  53. expect(res.code).toBe(0);
  54. expect(res.data?.id).toBe(bookId);
  55. });
  56. test('C03-5: 获取章节列表', async () => {
  57. if (!bookId) return test.skip();
  58. const res = await apiGet(`/api/book-generator/langgraph/books/${bookId}/chapters`);
  59. expect(res.code).toBe(0);
  60. });
  61. test('C03-6: 获取用户书籍列表', async () => {
  62. const res = await apiGet('/api/book-generator/langgraph/books');
  63. expect(res.code).toBe(0);
  64. expect(Array.isArray(res.data?.books)).toBe(true);
  65. });
  66. test('C03-7: 书籍生成列表页可访问', async ({ page }) => {
  67. await page.goto(`${FRONTEND_URL}/#/pages/book-generator/index`, { waitUntil: 'networkidle', timeout: 30000 });
  68. await page.waitForTimeout(3000);
  69. await expect(page.locator('text=书籍生成').first()).toBeVisible();
  70. });
  71. test('C03-8: 书籍创建页可访问', async ({ page }) => {
  72. await page.goto(`${FRONTEND_URL}/#/pages/book-generator/create`, { waitUntil: 'networkidle', timeout: 30000 });
  73. await page.waitForTimeout(3000);
  74. await expect(page.locator('text=创建书籍').first()).toBeVisible();
  75. });
  76. });