journey-01-register-login.spec.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /**
  2. * 关键旅程 E2E 测试 01: 注册→登录→首页浏览
  3. * Journey: 新用户注册 → 获取Token → 浏览首页
  4. *
  5. * 修复 BUG-12:原测试用 `138${Date.now().slice(-8)}` 生成手机号,
  6. * 可能与 global-setup.ts 中预创建用户 13800000001 冲突。
  7. * 现改用完全随机 11 位手机号(13x 开头)。
  8. */
  9. import { test, expect } from '@playwright/test';
  10. import { apiGet, apiPost, apiDelete, initApiClient, disposeApiClient, setAuthToken } from '../../../helpers/api-client';
  11. const FRONTEND_URL = process.env.FRONTEND_URL || 'http://localhost:5173';
  12. /** 生成唯一 11 位手机号(避开 13800000001 等固定测试号) */
  13. function generateUniquePhone(): string {
  14. // 11 位手机号:以 13 开头,后面 9 位完全随机
  15. const suffix = Math.floor(Math.random() * 1_000_000_000).toString().padStart(9, '0');
  16. return `13${suffix}`;
  17. }
  18. test.describe('关键旅程 01: 注册登录', () => {
  19. let phone: string;
  20. let authToken: string;
  21. test.beforeAll(async () => {
  22. await initApiClient();
  23. phone = generateUniquePhone();
  24. console.log('[Journey-01] 使用随机手机号:', phone);
  25. });
  26. test.afterAll(async () => {
  27. await disposeApiClient();
  28. });
  29. test('C01-1: 发送验证码', async () => {
  30. const res = await apiPost('/api/auth/send-code', { phone });
  31. expect(res.code).toBe(0);
  32. expect(res.data?.code).toBeDefined();
  33. });
  34. test('C01-2: 验证码登录/注册', async () => {
  35. const res = await apiPost('/api/auth/login', {
  36. phone,
  37. code: '123456', // 测试验证码
  38. });
  39. expect(res.code).toBe(0);
  40. expect(res.data?.token).toBeDefined();
  41. authToken = res.data?.token;
  42. setAuthToken(authToken);
  43. });
  44. test('C01-3: 获取用户信息', async () => {
  45. const res = await apiGet('/api/auth/user-info');
  46. expect(res.code).toBe(0);
  47. expect(res.data?.phone).toBe(phone);
  48. });
  49. test('C01-4: 新用户默认免费会员(memberLevel=0)', async () => {
  50. const res = await apiGet('/api/auth/user-info');
  51. expect(res.data?.memberLevel).toBe(0);
  52. });
  53. test('C01-5: 首页可正常访问', async ({ page }) => {
  54. await page.goto(`${FRONTEND_URL}/#/pages/index/index`, { waitUntil: 'networkidle', timeout: 30000 });
  55. await page.waitForTimeout(3000);
  56. await expect(page.locator('#app')).toBeVisible();
  57. });
  58. test('C01-6: 清理测试用户', async () => {
  59. // 如果后端支持删除账户则调用,否则跳过
  60. try {
  61. await apiDelete('/api/auth/account');
  62. } catch {
  63. // 跳过清理
  64. }
  65. });
  66. });