|
@@ -0,0 +1,283 @@
|
|
|
|
|
+import { TIMEOUTS } from '../../utils/timeouts';
|
|
|
|
|
+import { test, expect } from '../../utils/test-setup';
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 数据统计页面下拉刷新功能测试
|
|
|
|
|
+ * 测试目标:验证数据统计页面的下拉刷新功能是否正常工作
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+const TEST_USER_PHONE = '13800138005';
|
|
|
|
|
+const TEST_USER_PASSWORD = process.env.TEST_ENTERPRISE_PASSWORD || 'password123';
|
|
|
|
|
+
|
|
|
|
|
+test.describe('数据统计页面下拉刷新功能测试', () => {
|
|
|
|
|
+ test.use({ storageState: undefined });
|
|
|
|
|
+
|
|
|
|
|
+ test.beforeEach(async ({ enterpriseMiniPage: miniPage }) => {
|
|
|
|
|
+ await miniPage.goto();
|
|
|
|
|
+ await miniPage.login(TEST_USER_PHONE, TEST_USER_PASSWORD);
|
|
|
|
|
+ await miniPage.expectLoginSuccess();
|
|
|
|
|
+ await miniPage.page.waitForTimeout(TIMEOUTS.MEDIUM);
|
|
|
|
|
+ await miniPage.navigateToStatisticsPage();
|
|
|
|
|
+ // 等待统计页面数据加载完成(不依赖 .stat-card 类名)
|
|
|
|
|
+ await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('应该能够下拉刷新统计数据', async ({ enterpriseMiniPage: miniPage }) => {
|
|
|
|
|
+ console.debug('[测试] 开始下拉刷新测试');
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 获取刷新前的统计页面文本内容
|
|
|
|
|
+ const beforeRefreshContent = await miniPage.page.textContent('body');
|
|
|
|
|
+ console.debug(`[测试] 刷新前页面内容长度: ${beforeRefreshContent?.length || 0}`);
|
|
|
|
|
+ expect(beforeRefreshContent).toBeTruthy();
|
|
|
|
|
+ expect(beforeRefreshContent).toContain('数据统计');
|
|
|
|
|
+ console.debug('[测试] ✓ 页面包含数据统计标题');
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 验证初始数据存在
|
|
|
|
|
+ const hasInitialData = beforeRefreshContent?.includes('在职人数') ||
|
|
|
|
|
+ beforeRefreshContent?.includes('平均薪资') ||
|
|
|
|
|
+ beforeRefreshContent?.includes('在职率');
|
|
|
|
|
+ expect(hasInitialData).toBe(true);
|
|
|
|
|
+ console.debug('[测试] ✓ 初始统计数据存在');
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 监听控制台错误
|
|
|
|
|
+ const consoleErrors: string[] = [];
|
|
|
|
|
+ miniPage.page.on('console', msg => {
|
|
|
|
|
+ if (msg.type() === 'error') {
|
|
|
|
|
+ consoleErrors.push(msg.text());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 执行下拉刷新动作
|
|
|
|
|
+ await miniPage.page.evaluate(async () => {
|
|
|
|
|
+ // 尝试找到可滚动元素并执行下拉刷新
|
|
|
|
|
+ const scrollableElements = [
|
|
|
|
|
+ document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
|
|
|
|
|
+ document.querySelector('[class*="overflow"]'),
|
|
|
|
|
+ document.querySelector('main'),
|
|
|
|
|
+ document.body
|
|
|
|
|
+ ].filter(el => el !== null) as HTMLElement[];
|
|
|
|
|
+
|
|
|
|
|
+ if (scrollableElements.length > 0) {
|
|
|
|
|
+ const scrollableElement = scrollableElements[0];
|
|
|
|
|
+ console.debug('[下拉刷新] 找到可滚动元素,执行刷新动作');
|
|
|
|
|
+
|
|
|
|
|
+ // 模拟下拉手势:先向下滚动,再快速滚回顶部
|
|
|
|
|
+ scrollableElement.scrollTop = 0;
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+
|
|
|
|
|
+ // 等待一小段时间后再次触发滚动事件
|
|
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.warn('[下拉刷新] 未找到可滚动元素');
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 等待刷新完成
|
|
|
|
|
+ await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 获取刷新后的页面内容
|
|
|
|
|
+ const afterRefreshContent = await miniPage.page.textContent('body');
|
|
|
|
|
+ console.debug(`[测试] 刷新后页面内容长度: ${afterRefreshContent?.length || 0}`);
|
|
|
|
|
+ expect(afterRefreshContent).toBeTruthy();
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 验证页面仍然包含统计数据
|
|
|
|
|
+ const hasDataAfterRefresh = afterRefreshContent?.includes('在职人数') ||
|
|
|
|
|
+ afterRefreshContent?.includes('平均薪资') ||
|
|
|
|
|
+ afterRefreshContent?.includes('在职率');
|
|
|
|
|
+ expect(hasDataAfterRefresh).toBe(true);
|
|
|
|
|
+ console.debug('[测试] ✓ 刷新后统计数据仍然存在');
|
|
|
|
|
+
|
|
|
|
|
+ // 8. 验证页面没有被破坏
|
|
|
|
|
+ expect(afterRefreshContent).toContain('数据统计');
|
|
|
|
|
+ console.debug('[测试] ✓ 页面结构完整');
|
|
|
|
|
+
|
|
|
|
|
+ console.debug('[测试] ✅ 下拉刷新功能测试通过');
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('下拉刷新后应该重新加载数据', async ({ enterpriseMiniPage: miniPage }) => {
|
|
|
|
|
+ console.debug('[测试] 开始数据重新加载测试');
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 等待初始数据加载
|
|
|
|
|
+ await miniPage.page.waitForTimeout(TIMEOUTS.MEDIUM);
|
|
|
|
|
+ const initialContent = await miniPage.page.textContent('body');
|
|
|
|
|
+ console.debug(`[测试] 初始页面内容长度: ${initialContent?.length || 0}`);
|
|
|
|
|
+ expect(initialContent).toContain('数据统计');
|
|
|
|
|
+ console.debug('[测试] ✓ 页面已加载');
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 验证初始统计图表标题存在
|
|
|
|
|
+ const expectedCharts = ['残疾类型分布', '性别分布', '年龄分布', '户籍省份分布'];
|
|
|
|
|
+ const initialChartsFound = expectedCharts.filter(chart => initialContent?.includes(chart));
|
|
|
|
|
+ console.debug(`[测试] 初始找到 ${initialChartsFound.length}/${expectedCharts.length} 个图表标题`);
|
|
|
|
|
+ expect(initialChartsFound.length).toBeGreaterThan(0);
|
|
|
|
|
+ console.debug('[测试] ✓ 统计图表标题存在');
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 截图 - 刷新前
|
|
|
|
|
+ await miniPage.page.screenshot({
|
|
|
|
|
+ path: 'test-results/statistics-before-refresh.png',
|
|
|
|
|
+ fullPage: true
|
|
|
|
|
+ });
|
|
|
|
|
+ console.debug('[测试] 已保存刷新前截图');
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 执行下拉刷新
|
|
|
|
|
+ await miniPage.page.evaluate(async () => {
|
|
|
|
|
+ const scrollableElements = [
|
|
|
|
|
+ document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
|
|
|
|
|
+ document.querySelector('[class*="overflow"]'),
|
|
|
|
|
+ document.querySelector('main'),
|
|
|
|
|
+ document.body
|
|
|
|
|
+ ].filter(el => el !== null) as HTMLElement[];
|
|
|
|
|
+
|
|
|
|
|
+ if (scrollableElements.length > 0) {
|
|
|
|
|
+ const scrollableElement = scrollableElements[0];
|
|
|
|
|
+ scrollableElement.scrollTop = 0;
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 等待数据重新加载
|
|
|
|
|
+ await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 验证数据仍然存在
|
|
|
|
|
+ const afterRefreshContent = await miniPage.page.textContent('body');
|
|
|
|
|
+ expect(afterRefreshContent).toContain('数据统计');
|
|
|
|
|
+
|
|
|
|
|
+ const afterRefreshChartsFound = expectedCharts.filter(chart => afterRefreshContent?.includes(chart));
|
|
|
|
|
+ console.debug(`[测试] 刷新后找到 ${afterRefreshChartsFound.length}/${expectedCharts.length} 个图表标题`);
|
|
|
|
|
+ expect(afterRefreshChartsFound.length).toBeGreaterThan(0);
|
|
|
|
|
+ console.debug('[测试] ✓ 刷新后图表标题仍然存在');
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 截图 - 刷新后
|
|
|
|
|
+ await miniPage.page.screenshot({
|
|
|
|
|
+ path: 'test-results/statistics-after-refresh.png',
|
|
|
|
|
+ fullPage: true
|
|
|
|
|
+ });
|
|
|
|
|
+ console.debug('[测试] 已保存刷新后截图');
|
|
|
|
|
+
|
|
|
|
|
+ console.debug('[测试] ✅ 数据重新加载测试通过');
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('下拉刷新不应该产生控制台错误', async ({ enterpriseMiniPage: miniPage }) => {
|
|
|
|
|
+ console.debug('[测试] 开始控制台错误检查');
|
|
|
|
|
+
|
|
|
|
|
+ const consoleErrors: string[] = [];
|
|
|
|
|
+
|
|
|
|
|
+ // 监听控制台错误
|
|
|
|
|
+ miniPage.page.on('console', msg => {
|
|
|
|
|
+ if (msg.type() === 'error') {
|
|
|
|
|
+ const errorText = msg.text();
|
|
|
|
|
+ consoleErrors.push(errorText);
|
|
|
|
|
+ console.debug(`[控制台错误] ${errorText}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 执行下拉刷新
|
|
|
|
|
+ await miniPage.page.evaluate(async () => {
|
|
|
|
|
+ const scrollableElements = [
|
|
|
|
|
+ document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
|
|
|
|
|
+ document.querySelector('[class*="overflow"]'),
|
|
|
|
|
+ document.querySelector('main'),
|
|
|
|
|
+ document.body
|
|
|
|
|
+ ].filter(el => el !== null) as HTMLElement[];
|
|
|
|
|
+
|
|
|
|
|
+ if (scrollableElements.length > 0) {
|
|
|
|
|
+ const scrollableElement = scrollableElements[0];
|
|
|
|
|
+ scrollableElement.scrollTop = 0;
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
|
|
|
|
|
+
|
|
|
|
|
+ // 验证没有控制台错误
|
|
|
|
|
+ // 过滤掉一些常见的非关键错误(如资源加载失败)
|
|
|
|
|
+ const criticalErrors = consoleErrors.filter(err => {
|
|
|
|
|
+ return !err.includes('net::ERR_FAILED') &&
|
|
|
|
|
+ !err.includes('404') &&
|
|
|
|
|
+ !err.includes('Failed to load resource');
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ if (criticalErrors.length > 0) {
|
|
|
|
|
+ console.debug(`[测试] 发现 ${criticalErrors.length} 个控制台错误`);
|
|
|
|
|
+ console.debug(`[测试] 错误详情: ${criticalErrors.join(', ')}`);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 只有关键错误才导致测试失败
|
|
|
|
|
+ expect(criticalErrors.length).toBe(0);
|
|
|
|
|
+ console.debug('[测试] ✅ 无关键控制台错误');
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ test('完整下拉刷新流程验证', async ({ enterpriseMiniPage: miniPage }) => {
|
|
|
|
|
+ console.debug('[测试] 开始完整下拉刷新流程验证');
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 验证初始状态
|
|
|
|
|
+ const initialContent = await miniPage.page.textContent('body');
|
|
|
|
|
+ console.debug(`[测试] 初始页面内容长度: ${initialContent?.length || 0}`);
|
|
|
|
|
+ expect(initialContent).toContain('数据统计');
|
|
|
|
|
+ console.debug('[测试] ✓ 页面标题正确');
|
|
|
|
|
+
|
|
|
|
|
+ // 验证初始统计数据
|
|
|
|
|
+ const initialDataExists = initialContent?.includes('在职人数') ||
|
|
|
|
|
+ initialContent?.includes('平均薪资') ||
|
|
|
|
|
+ initialContent?.includes('在职率');
|
|
|
|
|
+ expect(initialDataExists).toBe(true);
|
|
|
|
|
+ console.debug('[测试] ✓ 初始统计数据存在');
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 执行下拉刷新
|
|
|
|
|
+ await miniPage.page.evaluate(async () => {
|
|
|
|
|
+ const scrollableElements = [
|
|
|
|
|
+ document.querySelector('.h-\\[calc\\(100vh-120px\\)\\]'),
|
|
|
|
|
+ document.querySelector('[class*="overflow"]'),
|
|
|
|
|
+ document.querySelector('main'),
|
|
|
|
|
+ document.body
|
|
|
|
|
+ ].filter(el => el !== null) as HTMLElement[];
|
|
|
|
|
+
|
|
|
|
|
+ if (scrollableElements.length > 0) {
|
|
|
|
|
+ const scrollableElement = scrollableElements[0];
|
|
|
|
|
+ // 模拟下拉手势:先向下滚动,再快速滚回顶部
|
|
|
|
|
+ scrollableElement.scrollTop = 100;
|
|
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
|
+ scrollableElement.scrollTop = 0;
|
|
|
|
|
+
|
|
|
|
|
+ // 触发滚动事件
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
+ scrollableElement.dispatchEvent(new Event('scroll', { bubbles: true }));
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 等待刷新完成
|
|
|
|
|
+ await miniPage.page.waitForTimeout(TIMEOUTS.LONG);
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 验证刷新后状态
|
|
|
|
|
+ const afterRefreshContent = await miniPage.page.textContent('body');
|
|
|
|
|
+ console.debug(`[测试] 刷新后页面内容长度: ${afterRefreshContent?.length || 0}`);
|
|
|
|
|
+ expect(afterRefreshContent).toContain('数据统计');
|
|
|
|
|
+ console.debug('[测试] ✓ 刷新后页面标题正确');
|
|
|
|
|
+
|
|
|
|
|
+ // 验证刷新后统计数据仍然存在
|
|
|
|
|
+ const afterDataExists = afterRefreshContent?.includes('在职人数') ||
|
|
|
|
|
+ afterRefreshContent?.includes('平均薪资') ||
|
|
|
|
|
+ afterRefreshContent?.includes('在职率');
|
|
|
|
|
+ expect(afterDataExists).toBe(true);
|
|
|
|
|
+ console.debug('[测试] ✓ 刷新后统计数据仍然存在');
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 验证页面结构完整性
|
|
|
|
|
+ const expectedElements = ['残疾类型分布', '性别分布'];
|
|
|
|
|
+ const foundElements = expectedElements.filter(el => afterRefreshContent?.includes(el));
|
|
|
|
|
+ expect(foundElements.length).toBeGreaterThan(0);
|
|
|
|
|
+ console.debug(`[测试] ✓ 找到 ${foundElements.length}/${expectedElements.length} 个预期元素`);
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 最终截图
|
|
|
|
|
+ await miniPage.page.screenshot({
|
|
|
|
|
+ path: 'test-results/statistics-pull-refresh-complete.png',
|
|
|
|
|
+ fullPage: true
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ console.debug('[测试] ✅ 完整下拉刷新流程验证通过');
|
|
|
|
|
+ });
|
|
|
|
|
+});
|