journey-04-subscribe-play.spec.ts 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /**
  2. * 关键旅程 E2E 测试 04: 购买会员→解锁功能
  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('关键旅程 04: 订阅会员解锁功能', () => {
  9. let phone: string;
  10. let authToken: string;
  11. let orderNo: 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('C04-1: 获取可用套餐列表', async () => {
  24. const res = await apiGet('/api/subscription/plans');
  25. expect(res.code).toBe(0);
  26. expect(Array.isArray(res.data?.plans)).toBe(true);
  27. expect(res.data?.plans.length).toBeGreaterThan(0);
  28. });
  29. test('C04-2: 获取单个套餐详情', async () => {
  30. const res = await apiGet('/api/subscription/plans/2');
  31. expect(res.code).toBe(0);
  32. expect(res.data?.name).toBeDefined();
  33. });
  34. test('C04-3: 创建支付订单', async () => {
  35. const res = await apiPost('/api/payment/create', {
  36. planId: 2, // 专业版
  37. paymentMethod: 'mock',
  38. period: 'monthly',
  39. });
  40. expect(res.code).toBe(0);
  41. expect(res.data?.orderNo).toBeDefined();
  42. orderNo = res.data?.orderNo;
  43. });
  44. test('C04-4: 模拟支付成功回调', async () => {
  45. if (!orderNo) return test.skip();
  46. const callbackRes = await apiPost('/api/payment/mock', {
  47. orderNo,
  48. paymentId: `MOCK_${Date.now()}`,
  49. status: 'success',
  50. });
  51. expect(callbackRes.code).toBe(0);
  52. });
  53. test('C04-5: 会员等级已更新', async () => {
  54. const res = await apiGet('/api/auth/user-info');
  55. expect(res.code).toBe(0);
  56. // 支付后会员等级应该 >= 1 (专业版)
  57. expect(res.data?.memberLevel).toBeGreaterThanOrEqual(1);
  58. });
  59. test('C04-6: 会员中心页可访问', async ({ page }) => {
  60. await page.goto(`${FRONTEND_URL}/#/pages/member/index`, { waitUntil: 'networkidle', timeout: 30000 });
  61. await page.waitForTimeout(3000);
  62. await expect(page.locator('#app')).toBeVisible();
  63. });
  64. test('C04-7: 订单页可访问', async ({ page }) => {
  65. await page.goto(`${FRONTEND_URL}/#/pages/orders/index`, { waitUntil: 'networkidle', timeout: 30000 });
  66. await page.waitForTimeout(3000);
  67. await expect(page.locator('#app')).toBeVisible();
  68. });
  69. test('C04-8: 查询订单列表', async () => {
  70. const res = await apiGet('/api/payment/orders');
  71. expect(res.code).toBe(0);
  72. expect(Array.isArray(res.data?.list)).toBe(true);
  73. });
  74. });