From e557217cd05a7563e3df6988f2735fb4d7744009 Mon Sep 17 00:00:00 2001 From: snowgitea Date: Wed, 29 Apr 2026 02:08:59 +0800 Subject: [PATCH] chore: remove frontend/verify-pages.cjs --- frontend/verify-pages.cjs | 573 -------------------------------------- 1 file changed, 573 deletions(-) delete mode 100644 frontend/verify-pages.cjs diff --git a/frontend/verify-pages.cjs b/frontend/verify-pages.cjs deleted file mode 100644 index 5ef565e..0000000 --- a/frontend/verify-pages.cjs +++ /dev/null @@ -1,573 +0,0 @@ -/** - * 前端页面数据验证测试脚本 - * 验证 4 个页面的数据是否正确显示 - * - * 测试环境: - * - 前端地址: http://localhost:5173 - * - 数据库用户 ID: 6 - */ - -const { chromium } = require('@playwright/test'); -const path = require('path'); -const fs = require('fs'); - -// 配置 -const BASE_URL = 'http://localhost:5173'; -const SCREENSHOT_DIR = path.join(__dirname, 'test-screenshots'); - -// 测试结果 -const testResults = { - summary: { - total: 0, - passed: 0, - failed: 0, - warnings: 0 - }, - pages: {} -}; - -// 确保截图目录存在 -if (!fs.existsSync(SCREENSHOT_DIR)) { - fs.mkdirSync(SCREENSHOT_DIR, { recursive: true }); -} - -/** - * 延迟函数 - */ -function delay(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -/** - * 测试首页 (/) - */ -async function testDashboard(page) { - console.log('\n========== 测试首页 (/) =========='); - const result = { - url: `${BASE_URL}/`, - checks: [], - issues: [], - screenshot: null - }; - - try { - // 导航到首页 - await page.goto(BASE_URL, { waitUntil: 'networkidle' }); - await delay(2000); // 等待数据加载 - - // 截图 - const screenshotPath = path.join(SCREENSHOT_DIR, '01-dashboard.png'); - await page.screenshot({ path: screenshotPath, fullPage: true }); - result.screenshot = screenshotPath; - console.log(`截图已保存: ${screenshotPath}`); - - // 检查账户余额 - console.log('\n--- 检查账户余额 ---'); - const balanceCards = await page.locator('[class*="card"], [class*="balance"]').all(); - console.log(`找到 ${balanceCards.length} 个卡片元素`); - - // 检查是否有金额显示 - const pageText = await page.textContent('body'); - - // 预期数据 - const expectedBalances = [ - { name: '支付宝', amount: 5000 }, - { name: '微信', amount: 3000 }, - { name: '银行卡', amount: 10000 } - ]; - - for (const balance of expectedBalances) { - const hasName = pageText.includes(balance.name); - const hasAmount = pageText.includes(balance.amount.toString()) || - pageText.includes(balance.amount.toLocaleString()); - - const check = { - item: `账户余额 - ${balance.name}`, - expected: `${balance.name}: ${balance.amount}`, - found: hasName && hasAmount, - status: (hasName && hasAmount) ? 'PASS' : 'FAIL' - }; - result.checks.push(check); - - if (hasName && hasAmount) { - console.log(`[PASS] ${balance.name} 余额显示正确`); - } else { - console.log(`[FAIL] ${balance.name} 余额未找到`); - result.issues.push(`${balance.name} 余额未正确显示`); - } - } - - // 检查收支统计 - console.log('\n--- 检查收支统计 ---'); - const incomePattern = /收入|Income/i; - const expensePattern = /支出|Expense/i; - - const hasIncome = incomePattern.test(pageText); - const hasExpense = expensePattern.test(pageText); - - result.checks.push({ - item: '收支统计 - 收入', - found: hasIncome, - status: hasIncome ? 'PASS' : 'WARN' - }); - - result.checks.push({ - item: '收支统计 - 支出', - found: hasExpense, - status: hasExpense ? 'PASS' : 'WARN' - }); - - if (hasIncome) console.log('[PASS] 收入统计显示'); - if (hasExpense) console.log('[PASS] 支出统计显示'); - - if (!hasIncome || !hasExpense) { - result.issues.push('收支统计可能未正确显示'); - } - - // 检查是否有数据加载错误 - const hasError = pageText.includes('加载失败') || - pageText.includes('错误') || - pageText.includes('Error'); - - if (hasError) { - result.issues.push('页面存在加载错误'); - console.log('[FAIL] 页面存在加载错误'); - } - - } catch (error) { - result.issues.push(`测试异常: ${error.message}`); - console.error(`[ERROR] 首页测试失败: ${error.message}`); - } - - return result; -} - -/** - * 测试记账页面 (/record) - */ -async function testRecord(page) { - console.log('\n========== 测试记账页面 (/record) =========='); - const result = { - url: `${BASE_URL}/record`, - checks: [], - issues: [], - screenshot: null - }; - - try { - // 导航到记账页面 - await page.goto(`${BASE_URL}/record`, { waitUntil: 'networkidle' }); - await delay(2000); - - // 截图 - const screenshotPath = path.join(SCREENSHOT_DIR, '02-record.png'); - await page.screenshot({ path: screenshotPath, fullPage: true }); - result.screenshot = screenshotPath; - console.log(`截图已保存: ${screenshotPath}`); - - // 检查交易记录列表 - console.log('\n--- 检查交易记录列表 ---'); - - // 查找记录元素 - const recordItems = await page.locator('tr, [class*="record"], [class*="item"]').all(); - console.log(`找到 ${recordItems.length} 个可能的记录元素`); - - // 获取页面文本 - const pageText = await page.textContent('body'); - - // 预期有 7 条记录 - const expectedRecordCount = 7; - - // 检查是否有记录数据显示 - const hasRecords = pageText.includes('早餐') || - pageText.includes('午餐') || - pageText.includes('工资') || - pageText.includes('地铁') || - pageText.includes('购物') || - pageText.includes('电影') || - pageText.includes('晚餐'); - - result.checks.push({ - item: '交易记录数据', - expected: `至少 ${expectedRecordCount} 条记录`, - found: hasRecords, - status: hasRecords ? 'PASS' : 'FAIL' - }); - - if (hasRecords) { - console.log('[PASS] 交易记录数据存在'); - } else { - console.log('[FAIL] 未找到交易记录数据'); - result.issues.push('交易记录列表无数据'); - } - - // 检查记录类型(支出/收入) - console.log('\n--- 检查记录类型 ---'); - const hasExpense = pageText.includes('支出'); - const hasIncome = pageText.includes('收入'); - - result.checks.push({ - item: '记录类型 - 支出', - found: hasExpense, - status: hasExpense ? 'PASS' : 'WARN' - }); - - result.checks.push({ - item: '记录类型 - 收入', - found: hasIncome, - status: hasIncome ? 'PASS' : 'WARN' - }); - - if (hasExpense) console.log('[PASS] 支出类型显示'); - if (hasIncome) console.log('[PASS] 收入类型显示'); - - // 检查金额显示 - const hasAmount = /\d+\.?\d*/.test(pageText); - result.checks.push({ - item: '金额显示', - found: hasAmount, - status: hasAmount ? 'PASS' : 'FAIL' - }); - - if (hasAmount) { - console.log('[PASS] 金额数据存在'); - } else { - console.log('[FAIL] 未找到金额数据'); - result.issues.push('金额数据未显示'); - } - - } catch (error) { - result.issues.push(`测试异常: ${error.message}`); - console.error(`[ERROR] 记账页面测试失败: ${error.message}`); - } - - return result; -} - -/** - * 测试预算页面 (/budget) - */ -async function testBudget(page) { - console.log('\n========== 测试预算页面 (/budget) =========='); - const result = { - url: `${BASE_URL}/budget`, - checks: [], - issues: [], - screenshot: null - }; - - try { - // 导航到预算页面 - await page.goto(`${BASE_URL}/budget`, { waitUntil: 'networkidle' }); - await delay(2000); - - // 截图 - const screenshotPath = path.join(SCREENSHOT_DIR, '03-budget.png'); - await page.screenshot({ path: screenshotPath, fullPage: true }); - result.screenshot = screenshotPath; - console.log(`截图已保存: ${screenshotPath}`); - - // 获取页面文本 - const pageText = await page.textContent('body'); - - // 检查预算数据 - console.log('\n--- 检查预算数据 ---'); - - // 预期预算类别 - const expectedCategories = ['餐饮', '交通', '购物', '娱乐']; - - for (const category of expectedCategories) { - const hasCategory = pageText.includes(category); - - result.checks.push({ - item: `预算类别 - ${category}`, - found: hasCategory, - status: hasCategory ? 'PASS' : 'WARN' - }); - - if (hasCategory) { - console.log(`[PASS] 预算类别 "${category}" 显示`); - } else { - console.log(`[WARN] 预算类别 "${category}" 未找到`); - } - } - - // 检查预算进度 - console.log('\n--- 检查预算进度 ---'); - - // 查找进度条元素 - const progressBars = await page.locator('[class*="progress"], [role="progressbar"]').all(); - console.log(`找到 ${progressBars.length} 个进度条元素`); - - const hasProgress = progressBars.length > 0 || - pageText.includes('%') || - pageText.includes('进度'); - - result.checks.push({ - item: '预算进度显示', - found: hasProgress, - status: hasProgress ? 'PASS' : 'WARN' - }); - - if (hasProgress) { - console.log('[PASS] 预算进度显示'); - } else { - console.log('[WARN] 预算进度可能未正确显示'); - result.issues.push('预算进度显示可能有问题'); - } - - // 检查预算金额 - const hasBudgetAmount = /\d+/.test(pageText); - result.checks.push({ - item: '预算金额显示', - found: hasBudgetAmount, - status: hasBudgetAmount ? 'PASS' : 'FAIL' - }); - - if (hasBudgetAmount) { - console.log('[PASS] 预算金额数据存在'); - } else { - console.log('[FAIL] 未找到预算金额数据'); - result.issues.push('预算金额数据未显示'); - } - - } catch (error) { - result.issues.push(`测试异常: ${error.message}`); - console.error(`[ERROR] 预算页面测试失败: ${error.message}`); - } - - return result; -} - -/** - * 测试统计页面 (/statistics) - */ -async function testStatistics(page) { - console.log('\n========== 测试统计页面 (/statistics) =========='); - const result = { - url: `${BASE_URL}/statistics`, - checks: [], - issues: [], - screenshot: null - }; - - try { - // 导航到统计页面 - await page.goto(`${BASE_URL}/statistics`, { waitUntil: 'networkidle' }); - await delay(3000); // 图表加载需要更多时间 - - // 截图 - const screenshotPath = path.join(SCREENSHOT_DIR, '04-statistics.png'); - await page.screenshot({ path: screenshotPath, fullPage: true }); - result.screenshot = screenshotPath; - console.log(`截图已保存: ${screenshotPath}`); - - // 获取页面文本 - const pageText = await page.textContent('body'); - - // 检查图表显示 - console.log('\n--- 检查图表显示 ---'); - - // 查找图表容器 - const chartContainers = await page.locator('[class*="chart"], [id*="chart"], canvas').all(); - console.log(`找到 ${chartContainers.length} 个图表元素`); - - const hasChart = chartContainers.length > 0; - - result.checks.push({ - item: '图表容器', - expected: '至少 1 个图表', - found: hasChart, - status: hasChart ? 'PASS' : 'FAIL' - }); - - if (hasChart) { - console.log('[PASS] 图表容器存在'); - } else { - console.log('[FAIL] 未找到图表容器'); - result.issues.push('图表未正确渲染'); - } - - // 检查图表切换按钮 - console.log('\n--- 检查图表切换功能 ---'); - - // 查找切换按钮 - const switchButtons = await page.locator('button').all(); - let hasSwitchButtons = false; - - for (const button of switchButtons) { - const text = await button.textContent(); - if (text && (text.includes('饼图') || text.includes('折线') || text.includes('柱状'))) { - hasSwitchButtons = true; - console.log(`找到切换按钮: ${text.trim()}`); - } - } - - result.checks.push({ - item: '图表切换按钮', - found: hasSwitchButtons, - status: hasSwitchButtons ? 'PASS' : 'WARN' - }); - - if (hasSwitchButtons) { - console.log('[PASS] 图表切换按钮存在'); - - // 测试切换功能 - console.log('\n--- 测试图表切换 ---'); - - // 尝试点击饼图按钮 - const pieButton = await page.locator('button:has-text("饼图")').first(); - if (await pieButton.isVisible()) { - await pieButton.click(); - await delay(1000); - console.log('[INFO] 点击了饼图按钮'); - - // 截图 - const pieScreenshot = path.join(SCREENSHOT_DIR, '04-statistics-pie.png'); - await page.screenshot({ path: pieScreenshot, fullPage: true }); - } - - // 尝试点击折线图按钮 - const lineButton = await page.locator('button:has-text("折线")').first(); - if (await lineButton.isVisible()) { - await lineButton.click(); - await delay(1000); - console.log('[INFO] 点击了折线图按钮'); - - // 截图 - const lineScreenshot = path.join(SCREENSHOT_DIR, '04-statistics-line.png'); - await page.screenshot({ path: lineScreenshot, fullPage: true }); - } - - // 尝试点击柱状图按钮 - const barButton = await page.locator('button:has-text("柱状")').first(); - if (await barButton.isVisible()) { - await barButton.click(); - await delay(1000); - console.log('[INFO] 点击了柱状图按钮'); - - // 截图 - const barScreenshot = path.join(SCREENSHOT_DIR, '04-statistics-bar.png'); - await page.screenshot({ path: barScreenshot, fullPage: true }); - } - - result.checks.push({ - item: '图表切换功能', - found: true, - status: 'PASS' - }); - console.log('[PASS] 图表切换功能正常'); - - } else { - console.log('[WARN] 未找到图表切换按钮'); - result.issues.push('图表切换按钮未找到'); - } - - // 检查是否有数据 - const hasDataIndicators = pageText.includes('餐饮') || - pageText.includes('交通') || - pageText.includes('购物') || - pageText.includes('娱乐'); - - result.checks.push({ - item: '统计数据', - found: hasDataIndicators, - status: hasDataIndicators ? 'PASS' : 'WARN' - }); - - if (hasDataIndicators) { - console.log('[PASS] 统计数据存在'); - } else { - console.log('[WARN] 统计数据可能未正确显示'); - } - - } catch (error) { - result.issues.push(`测试异常: ${error.message}`); - console.error(`[ERROR] 统计页面测试失败: ${error.message}`); - } - - return result; -} - -/** - * 主测试函数 - */ -async function runTests() { - console.log('========================================'); - console.log(' 前端页面数据验证测试'); - console.log(' 测试时间:', new Date().toLocaleString()); - console.log(' 前端地址:', BASE_URL); - console.log('========================================'); - - // 启动浏览器 - const browser = await chromium.launch({ - headless: false, // 可视化模式,方便观察 - slowMo: 100 - }); - - const context = await browser.newContext({ - viewport: { width: 1280, height: 800 } - }); - - const page = await context.newPage(); - - try { - // 测试首页 - testResults.pages.dashboard = await testDashboard(page); - - // 测试记账页面 - testResults.pages.record = await testRecord(page); - - // 测试预算页面 - testResults.pages.budget = await testBudget(page); - - // 测试统计页面 - testResults.pages.statistics = await testStatistics(page); - - } finally { - await browser.close(); - } - - // 统计结果 - console.log('\n========================================'); - console.log(' 测试结果汇总'); - console.log('========================================'); - - for (const [pageName, result] of Object.entries(testResults.pages)) { - console.log(`\n【${pageName.toUpperCase()}】`); - console.log(` URL: ${result.url}`); - console.log(` 截图: ${result.screenshot || '无'}`); - - const passed = result.checks.filter(c => c.status === 'PASS').length; - const failed = result.checks.filter(c => c.status === 'FAIL').length; - const warned = result.checks.filter(c => c.status === 'WARN').length; - - console.log(` 检查项: ${passed} 通过, ${failed} 失败, ${warned} 警告`); - - if (result.issues.length > 0) { - console.log(` 问题列表:`); - result.issues.forEach(issue => console.log(` - ${issue}`)); - } - - testResults.summary.total += result.checks.length; - testResults.summary.passed += passed; - testResults.summary.failed += failed; - testResults.summary.warnings += warned; - } - - console.log('\n----------------------------------------'); - console.log(`总计: ${testResults.summary.passed}/${testResults.summary.total} 通过`); - console.log(`失败: ${testResults.summary.failed}`); - console.log(`警告: ${testResults.summary.warnings}`); - console.log('----------------------------------------'); - - // 保存测试报告 - const reportPath = path.join(SCREENSHOT_DIR, 'test-report.json'); - fs.writeFileSync(reportPath, JSON.stringify(testResults, null, 2)); - console.log(`\n测试报告已保存: ${reportPath}`); - - return testResults; -} - -// 执行测试 -runTests().catch(console.error);