unified-audit-center.spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /**
  2. * ================================================================
  3. * 场景:统一审核中心 E2E 测试
  4. * ================================================================
  5. * 用户故事:管理员在统一审核中心查看和处理所有待审核事项,
  6. * 包括文章审核、服务商审核、管家审核、提现审核等。
  7. *
  8. * 流程步骤:
  9. * 1. 管理员登录后台
  10. * 2. 进入统一审核中心
  11. * 3. 查看待审核事项列表
  12. * 4. 审核不同类型的事项
  13. * 5. 查看审核记录
  14. *
  15. * 关键里程碑:
  16. * - [Milestone-1] 审核中心页面加载成功
  17. * - [Milestone-2] 待审核事项列表加载正常
  18. * - [Milestone-3] 审核操作成功
  19. * - [Milestone-4] 审核记录可查询
  20. *
  21. * 运行:npx playwright test tests/e2e/unified-audit-center.spec.js
  22. * ================================================================
  23. */
  24. const { test, expect } = require('@playwright/test');
  25. test.describe('【场景流程】统一审核中心', () => {
  26. test.beforeEach(async ({ page }) => {
  27. // 管理员登录(admin 后台)
  28. await page.goto('http://cfc.iwintrue.com/admin/login');
  29. await page.waitForLoadState('networkidle');
  30. const adminPhone = '13701366188';
  31. const phoneInput = page.locator('input[placeholder="请输入手机号"]');
  32. await phoneInput.fill(adminPhone);
  33. await page.locator('.login-btn, button:has-text("登录")').click();
  34. await page.waitForTimeout(1500);
  35. // 验证登录成功
  36. try {
  37. await page.waitForSelector('.admin-tab, .admin-menu, .admin-layout', { timeout: 10000 });
  38. } catch (e) {
  39. if (await page.url().includes('/login')) {
  40. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  41. await page.waitForLoadState('networkidle');
  42. }
  43. }
  44. });
  45. /**
  46. * 场景1:审核中心页面加载
  47. * 角色:管理员
  48. * 触发条件:进入统一审核中心
  49. * 校验:页面加载成功,tab 切换到待审核
  50. */
  51. test('[场景1] 审核中心页面加载 — 期望 tab 切换到待审核', async ({ page }) => {
  52. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  53. await page.waitForLoadState('networkidle');
  54. // 验证页面标题
  55. const title = page.locator('.el-card__header, .tab-header, h2:has-text("审核中心")');
  56. expect(await title.isVisible()).toBeTruthy();
  57. // 验证默认选中"待审核" tab
  58. const pendingTab = page.locator('.nav-item.active, .el-tab-pane.is-active, text="待审核"');
  59. expect(await pendingTab.isVisible()).toBeTruthy();
  60. });
  61. /**
  62. * 场景2:待审核事项列表加载
  63. * 角色:管理员
  64. * 触发条件:进入待审核 tab
  65. * 校验:列表加载正常数据
  66. */
  67. test('[场景2] 待审核事项列表 — 期望加载正常', async ({ page }) => {
  68. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  69. await page.waitForLoadState('networkidle');
  70. // 切换到待审核 tab
  71. const pendingTab = page.locator('.nav-item:has-text("待审核"), .tab-item:has-text("待审核")');
  72. await pendingTab.click();
  73. await page.waitForTimeout(1000);
  74. // 验证列表加载
  75. const rows = page.locator('.el-table__row, .review-item');
  76. const rowCount = await rows.count();
  77. expect(rowCount).toBeGreaterThanOrEqual(0);
  78. // 验证列数
  79. if (rowCount > 0) {
  80. const firstRow = rows.first();
  81. const cells = firstRow.locator('.el-table__cell, .review-cell');
  82. expect(await cells.count()).toBeGreaterThanOrEqual(5);
  83. }
  84. });
  85. /**
  86. * 场景3:审核文章
  87. * 角色:管理员
  88. * 触发条件:选择待审核文章,点击通过
  89. * 校验:审核成功,状态变为已发布
  90. */
  91. test('[场景3] 审核文章 — 期望通过成功', async ({ page }) => {
  92. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  93. await page.waitForLoadState('networkidle');
  94. // 切换到文章审核 tab
  95. const articleTab = page.locator('.nav-item:has-text("文章审核"), .tab-item:has-text("文章")');
  96. await articleTab.click();
  97. await page.waitForTimeout(1000);
  98. // 查找待审核文章
  99. const pendingArticles = page.locator('.el-table__row:has-text("待审核")');
  100. const articleCount = await pendingArticles.count();
  101. if (articleCount > 0) {
  102. // 点击通过按钮
  103. const approveBtn = pendingArticles.first().locator('button:has-text("通过")');
  104. await approveBtn.click();
  105. await page.waitForTimeout(500);
  106. // 提交
  107. const submitBtn = page.locator('.el-dialog__footer button:has-text("确定"), button.el-button--primary');
  108. await submitBtn.click();
  109. await page.waitForTimeout(1000);
  110. // 验证提示
  111. const successTip = page.locator('.toast-success, text="审核通过"');
  112. expect(await successTip.isVisible().catch(() => false)).toBeTruthy();
  113. } else {
  114. // 无待审核文章,跳过
  115. expect(true).toBeTruthy();
  116. }
  117. });
  118. /**
  119. * 场景4:审核服务商
  120. * 角色:管理员
  121. * 触发条件:选择待审核服务商,点击通过
  122. * 校验:审核成功,状态变为已入驻
  123. */
  124. test('[场景4] 审核服务商 — 期望通过成功', async ({ page }) => {
  125. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  126. await page.waitForLoadState('networkidle');
  127. // 切换到服务商审核 tab
  128. const vendorTab = page.locator('.nav-item:has-text("服务商审核"), .tab-item:has-text("服务商")');
  129. await vendorTab.click();
  130. await page.waitForTimeout(1000);
  131. // 查找待审核服务商
  132. const pendingVendors = page.locator('.el-table__row:has-text("待审核")');
  133. const vendorCount = await pendingVendors.count();
  134. if (vendorCount > 0) {
  135. // 点击通过按钮
  136. const approveBtn = pendingVendors.first().locator('button:has-text("通过")');
  137. await approveBtn.click();
  138. await page.waitForTimeout(500);
  139. // 提交
  140. const submitBtn = page.locator('.el-dialog__footer button:has-text("确定"), button.el-button--primary');
  141. await submitBtn.click();
  142. await page.waitForTimeout(1000);
  143. // 验证提示
  144. const successTip = page.locator('.toast-success, text="审核通过"');
  145. expect(await successTip.isVisible().catch(() => false)).toBeTruthy();
  146. } else {
  147. // 无待审核服务商,跳过
  148. expect(true).toBeTruthy();
  149. }
  150. });
  151. /**
  152. * 场景5:审核提现申请
  153. * 角色:管理员
  154. * 触发条件:选择待审核提现,点击通过
  155. * 校验:审核成功,状态变为已打款
  156. */
  157. test('[场景5] 审核提现申请 — 期望通过成功', async ({ page }) => {
  158. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  159. await page.waitForLoadState('networkidle');
  160. // 切换到提现审核 tab
  161. const withdrawTab = page.locator('.nav-item:has-text("提现审核"), .tab-item:has-text("提现")');
  162. await withdrawTab.click();
  163. await page.waitForTimeout(1000);
  164. // 查找待审核提现
  165. const pendingWithdraws = page.locator('.el-table__row:has-text("待审核")');
  166. const withdrawCount = await pendingWithdraws.count();
  167. if (withdrawCount > 0) {
  168. // 点击通过按钮
  169. const approveBtn = pendingWithdraws.first().locator('button:has-text("通过")');
  170. await approveBtn.click();
  171. await page.waitForTimeout(500);
  172. // 提交
  173. const submitBtn = page.locator('.el-dialog__footer button:has-text("确定"), button.el-button--primary');
  174. await submitBtn.click();
  175. await page.waitForTimeout(1000);
  176. // 验证提示
  177. const successTip = page.locator('.toast-success, text="审核通过"');
  178. expect(await successTip.isVisible().catch(() => false)).toBeTruthy();
  179. } else {
  180. // 无待审核提现,跳过
  181. expect(true).toBeTruthy();
  182. }
  183. });
  184. /**
  185. * 场景6:审核管家申请
  186. * 角色:管理员
  187. * 触发条件:选择待审核管家,点击通过
  188. * 校验:审核成功,状态变为已开通
  189. */
  190. test('[场景6] 审核管家申请 — 期望通过成功', async ({ page }) => {
  191. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  192. await page.waitForLoadState('networkidle');
  193. // 切换到管家审核 tab
  194. const butlerTab = page.locator('.nav-item:has-text("管家审核"), .tab-item:has-text("管家")');
  195. await butlerTab.click();
  196. await page.waitForTimeout(1000);
  197. // 查找待审核管家
  198. const pendingButlers = page.locator('.el-table__row:has-text("待审核")');
  199. const butlerCount = await pendingButlers.count();
  200. if (butlerCount > 0) {
  201. // 点击通过按钮
  202. const approveBtn = pendingButlers.first().locator('button:has-text("通过")');
  203. await approveBtn.click();
  204. await page.waitForTimeout(500);
  205. // 提交
  206. const submitBtn = page.locator('.el-dialog__footer button:has-text("确定"), button.el-button--primary');
  207. await submitBtn.click();
  208. await page.waitForTimeout(1000);
  209. // 验证提示
  210. const successTip = page.locator('.toast-success, text="审核通过"');
  211. expect(await successTip.isVisible().catch(() => false)).toBeTruthy();
  212. } else {
  213. // 无待审核管家,跳过
  214. expect(true).toBeTruthy();
  215. }
  216. });
  217. /**
  218. * 场景7:查看审核记录
  219. * 角色:管理员
  220. * 触发条件:切换到审核记录 tab
  221. * 校验:记录加载正常
  222. */
  223. test('[场景7] 查看审核记录 — 期望加载正常', async ({ page }) => {
  224. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  225. await page.waitForLoadState('networkidle');
  226. // 切换到审核记录 tab
  227. const recordTab = page.locator('.nav-item:has-text("审核记录"), .tab-item:has-text("记录")');
  228. await recordTab.click();
  229. await page.waitForTimeout(1000);
  230. // 验证记录加载
  231. const records = page.locator('.el-table__row, .review-record');
  232. const recordCount = await records.count();
  233. expect(recordCount).toBeGreaterThanOrEqual(0);
  234. // 验证记录包含关键字段(类型/操作人/时间/状态)
  235. if (recordCount > 0) {
  236. const firstRecord = records.first();
  237. const cells = firstRecord.locator('.el-table__cell');
  238. expect(await cells.count()).toBeGreaterThanOrEqual(5);
  239. }
  240. });
  241. /**
  242. * 场景8:审核中心统计概览
  243. * 角色:管理员
  244. * 触发条件:进入审核中心首页
  245. * 校验:统计数据加载正常
  246. */
  247. test('[场景8] 审核中心统计概览 — 期望数据加载', async ({ page }) => {
  248. await page.goto('http://cfc.iwintrue.com/admin/review-center');
  249. await page.waitForLoadState('networkidle');
  250. // 验证统计卡片加载
  251. const statCards = page.locator('.stat-card, .summary-card, .overview-card');
  252. const cardCount = await statCards.count();
  253. expect(cardCount).toBeGreaterThanOrEqual(3);
  254. // 验证各类型待审核数量
  255. const pendingCount = page.locator('.pending-count, .review-count');
  256. expect(await pendingCount.isVisible()).toBeTruthy();
  257. });
  258. });