statistics-pull-refresh.spec.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import { TIMEOUTS } from '../../utils/timeouts';
  2. import { test, expect } from '../../utils/test-setup';
  3. /**
  4. * 数据统计页面下拉刷新功能测试
  5. * 测试目标:验证数据统计页面的下拉刷新功能是否正常工作
  6. */
  7. const TEST_USER_PHONE = '13800138005';
  8. const TEST_USER_PASSWORD = process.env.TEST_ENTERPRISE_PASSWORD || 'password123';
  9. test.describe('数据统计页面下拉刷新功能测试', () => {
  10. test.use({ storageState: undefined });
  11. test.beforeEach(async ({ enterpriseMiniPage: miniPage }) => {
  12. await miniPage.goto();
  13. await miniPage.login(TEST_USER_PHONE, TEST_USER_PASSWORD);
  14. await miniPage.expectLoginSuccess();
  15. await miniPage.page.waitForTimeout(TIMEOUTS.MEDIUM);
  16. await miniPage.navigateToStatisticsPage();
  17. // 等待统计页面数据加载完成(不依赖 .stat-card 类名)
  18. await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
  19. });
  20. test('应该能够下拉刷新统计数据', async ({ enterpriseMiniPage: miniPage }) => {
  21. console.debug('[测试] 开始下拉刷新测试');
  22. // 1. 获取刷新前的统计页面文本内容
  23. const beforeRefreshContent = await miniPage.page.textContent('body');
  24. console.debug(`[测试] 刷新前页面内容长度: ${beforeRefreshContent?.length || 0}`);
  25. expect(beforeRefreshContent).toBeTruthy();
  26. expect(beforeRefreshContent).toContain('数据统计');
  27. console.debug('[测试] ✓ 页面包含数据统计标题');
  28. // 2. 验证初始数据存在
  29. const hasInitialData = beforeRefreshContent?.includes('在职人数') ||
  30. beforeRefreshContent?.includes('平均薪资') ||
  31. beforeRefreshContent?.includes('在职率');
  32. expect(hasInitialData).toBe(true);
  33. console.debug('[测试] ✓ 初始统计数据存在');
  34. // 3. 监听控制台错误
  35. const consoleErrors: string[] = [];
  36. miniPage.page.on('console', msg => {
  37. if (msg.type() === 'error') {
  38. consoleErrors.push(msg.text());
  39. }
  40. });
  41. // 4. 执行下拉刷新动作
  42. await miniPage.page.evaluate(async () => {
  43. // 尝试找到可滚动元素并执行下拉刷新
  44. const scrollableElements = [
  45. document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
  46. document.querySelector('[class*="overflow"]'),
  47. document.querySelector('main'),
  48. document.body
  49. ].filter(el => el !== null) as HTMLElement[];
  50. if (scrollableElements.length > 0) {
  51. const scrollableElement = scrollableElements[0];
  52. console.debug('[下拉刷新] 找到可滚动元素,执行刷新动作');
  53. // 模拟下拉手势:先向下滚动,再快速滚回顶部
  54. scrollableElement.scrollTop = 0;
  55. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  56. // 等待一小段时间后再次触发滚动事件
  57. await new Promise(resolve => setTimeout(resolve, 100));
  58. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  59. } else {
  60. console.warn('[下拉刷新] 未找到可滚动元素');
  61. }
  62. });
  63. // 5. 等待刷新完成
  64. await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
  65. // 6. 获取刷新后的页面内容
  66. const afterRefreshContent = await miniPage.page.textContent('body');
  67. console.debug(`[测试] 刷新后页面内容长度: ${afterRefreshContent?.length || 0}`);
  68. expect(afterRefreshContent).toBeTruthy();
  69. // 7. 验证页面仍然包含统计数据
  70. const hasDataAfterRefresh = afterRefreshContent?.includes('在职人数') ||
  71. afterRefreshContent?.includes('平均薪资') ||
  72. afterRefreshContent?.includes('在职率');
  73. expect(hasDataAfterRefresh).toBe(true);
  74. console.debug('[测试] ✓ 刷新后统计数据仍然存在');
  75. // 8. 验证页面没有被破坏
  76. expect(afterRefreshContent).toContain('数据统计');
  77. console.debug('[测试] ✓ 页面结构完整');
  78. console.debug('[测试] ✅ 下拉刷新功能测试通过');
  79. });
  80. test('下拉刷新后应该重新加载数据', async ({ enterpriseMiniPage: miniPage }) => {
  81. console.debug('[测试] 开始数据重新加载测试');
  82. // 1. 等待初始数据加载
  83. await miniPage.page.waitForTimeout(TIMEOUTS.MEDIUM);
  84. const initialContent = await miniPage.page.textContent('body');
  85. console.debug(`[测试] 初始页面内容长度: ${initialContent?.length || 0}`);
  86. expect(initialContent).toContain('数据统计');
  87. console.debug('[测试] ✓ 页面已加载');
  88. // 2. 验证初始统计图表标题存在
  89. const expectedCharts = ['残疾类型分布', '性别分布', '年龄分布', '户籍省份分布'];
  90. const initialChartsFound = expectedCharts.filter(chart => initialContent?.includes(chart));
  91. console.debug(`[测试] 初始找到 ${initialChartsFound.length}/${expectedCharts.length} 个图表标题`);
  92. expect(initialChartsFound.length).toBeGreaterThan(0);
  93. console.debug('[测试] ✓ 统计图表标题存在');
  94. // 3. 截图 - 刷新前
  95. await miniPage.page.screenshot({
  96. path: 'test-results/statistics-before-refresh.png',
  97. fullPage: true
  98. });
  99. console.debug('[测试] 已保存刷新前截图');
  100. // 4. 执行下拉刷新
  101. await miniPage.page.evaluate(async () => {
  102. const scrollableElements = [
  103. document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
  104. document.querySelector('[class*="overflow"]'),
  105. document.querySelector('main'),
  106. document.body
  107. ].filter(el => el !== null) as HTMLElement[];
  108. if (scrollableElements.length > 0) {
  109. const scrollableElement = scrollableElements[0];
  110. scrollableElement.scrollTop = 0;
  111. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  112. await new Promise(resolve => setTimeout(resolve, 100));
  113. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  114. }
  115. });
  116. // 5. 等待数据重新加载
  117. await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
  118. // 6. 验证数据仍然存在
  119. const afterRefreshContent = await miniPage.page.textContent('body');
  120. expect(afterRefreshContent).toContain('数据统计');
  121. const afterRefreshChartsFound = expectedCharts.filter(chart => afterRefreshContent?.includes(chart));
  122. console.debug(`[测试] 刷新后找到 ${afterRefreshChartsFound.length}/${expectedCharts.length} 个图表标题`);
  123. expect(afterRefreshChartsFound.length).toBeGreaterThan(0);
  124. console.debug('[测试] ✓ 刷新后图表标题仍然存在');
  125. // 7. 截图 - 刷新后
  126. await miniPage.page.screenshot({
  127. path: 'test-results/statistics-after-refresh.png',
  128. fullPage: true
  129. });
  130. console.debug('[测试] 已保存刷新后截图');
  131. console.debug('[测试] ✅ 数据重新加载测试通过');
  132. });
  133. test('下拉刷新不应该产生控制台错误', async ({ enterpriseMiniPage: miniPage }) => {
  134. console.debug('[测试] 开始控制台错误检查');
  135. const consoleErrors: string[] = [];
  136. // 监听控制台错误
  137. miniPage.page.on('console', msg => {
  138. if (msg.type() === 'error') {
  139. const errorText = msg.text();
  140. consoleErrors.push(errorText);
  141. console.debug(`[控制台错误] ${errorText}`);
  142. }
  143. });
  144. // 执行下拉刷新
  145. await miniPage.page.evaluate(async () => {
  146. const scrollableElements = [
  147. document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
  148. document.querySelector('[class*="overflow"]'),
  149. document.querySelector('main'),
  150. document.body
  151. ].filter(el => el !== null) as HTMLElement[];
  152. if (scrollableElements.length > 0) {
  153. const scrollableElement = scrollableElements[0];
  154. scrollableElement.scrollTop = 0;
  155. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  156. await new Promise(resolve => setTimeout(resolve, 100));
  157. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  158. }
  159. });
  160. await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
  161. // 验证没有控制台错误
  162. // 过滤掉一些常见的非关键错误(如资源加载失败)
  163. const criticalErrors = consoleErrors.filter(err => {
  164. return !err.includes('net::ERR_FAILED') &&
  165. !err.includes('404') &&
  166. !err.includes('Failed to load resource');
  167. });
  168. if (criticalErrors.length > 0) {
  169. console.debug(`[测试] 发现 ${criticalErrors.length} 个控制台错误`);
  170. console.debug(`[测试] 错误详情: ${criticalErrors.join(', ')}`);
  171. }
  172. // 只有关键错误才导致测试失败
  173. expect(criticalErrors.length).toBe(0);
  174. console.debug('[测试] ✅ 无关键控制台错误');
  175. });
  176. test('完整下拉刷新流程验证', async ({ enterpriseMiniPage: miniPage }) => {
  177. console.debug('[测试] 开始完整下拉刷新流程验证');
  178. // 1. 验证初始状态
  179. const initialContent = await miniPage.page.textContent('body');
  180. console.debug(`[测试] 初始页面内容长度: ${initialContent?.length || 0}`);
  181. expect(initialContent).toContain('数据统计');
  182. console.debug('[测试] ✓ 页面标题正确');
  183. // 验证初始统计数据
  184. const initialDataExists = initialContent?.includes('在职人数') ||
  185. initialContent?.includes('平均薪资') ||
  186. initialContent?.includes('在职率');
  187. expect(initialDataExists).toBe(true);
  188. console.debug('[测试] ✓ 初始统计数据存在');
  189. // 2. 执行下拉刷新
  190. await miniPage.page.evaluate(async () => {
  191. const scrollableElements = [
  192. document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
  193. document.querySelector('[class*="overflow"]'),
  194. document.querySelector('main'),
  195. document.body
  196. ].filter(el => el !== null) as HTMLElement[];
  197. if (scrollableElements.length > 0) {
  198. const scrollableElement = scrollableElements[0];
  199. // 模拟下拉手势:先向下滚动,再快速滚回顶部
  200. scrollableElement.scrollTop = 100;
  201. await new Promise(resolve => setTimeout(resolve, 50));
  202. scrollableElement.scrollTop = 0;
  203. // 触发滚动事件
  204. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  205. await new Promise(resolve => setTimeout(resolve, 100));
  206. scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
  207. }
  208. });
  209. // 3. 等待刷新完成
  210. await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
  211. // 4. 验证刷新后状态
  212. const afterRefreshContent = await miniPage.page.textContent('body');
  213. console.debug(`[测试] 刷新后页面内容长度: ${afterRefreshContent?.length || 0}`);
  214. expect(afterRefreshContent).toContain('数据统计');
  215. console.debug('[测试] ✓ 刷新后页面标题正确');
  216. // 验证刷新后统计数据仍然存在
  217. const afterDataExists = afterRefreshContent?.includes('在职人数') ||
  218. afterRefreshContent?.includes('平均薪资') ||
  219. afterRefreshContent?.includes('在职率');
  220. expect(afterDataExists).toBe(true);
  221. console.debug('[测试] ✓ 刷新后统计数据仍然存在');
  222. // 5. 验证页面结构完整性
  223. const expectedElements = ['残疾类型分布', '性别分布'];
  224. const foundElements = expectedElements.filter(el => afterRefreshContent?.includes(el));
  225. expect(foundElements.length).toBeGreaterThan(0);
  226. console.debug(`[测试] ✓ 找到 ${foundElements.length}/${expectedElements.length} 个预期元素`);
  227. // 6. 最终截图
  228. await miniPage.page.screenshot({
  229. path: 'test-results/statistics-pull-refresh-complete.png',
  230. fullPage: true
  231. });
  232. console.debug('[测试] ✅ 完整下拉刷新流程验证通过');
  233. });
  234. });