chore: remove frontend/verify-pages-v2.cjs

This commit is contained in:
2026-04-29 02:08:58 +08:00
parent d0a78c096b
commit 482dfc7af5
-589
View File
@@ -1,589 +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}`);
// 获取页面文本
const pageText = await page.textContent('body');
console.log('\n页面文本片段:', pageText.substring(0, 500));
// 检查总余额显示
console.log('\n--- 检查总余额 ---');
const hasBalance = pageText.includes('当前余额') || pageText.includes('余额');
const hasAmount = /¥\s*[\d,]+\.?\d*/.test(pageText) || /\d{4,}/.test(pageText);
result.checks.push({
item: '总余额标题',
expected: '当前余额',
found: hasBalance,
status: hasBalance ? 'PASS' : 'FAIL'
});
result.checks.push({
item: '金额显示',
expected: '¥ 格式金额',
found: hasAmount,
status: hasAmount ? 'PASS' : 'FAIL'
});
if (hasBalance && hasAmount) {
console.log('[PASS] 总余额显示正确');
} else {
console.log('[FAIL] 总余额未正确显示');
result.issues.push('总余额未正确显示');
}
// 检查收支统计
console.log('\n--- 检查收支统计 ---');
const hasIncome = pageText.includes('本月收入') || pageText.includes('收入');
const hasExpense = pageText.includes('本月支出') || pageText.includes('支出');
result.checks.push({
item: '本月收入',
found: hasIncome,
status: hasIncome ? 'PASS' : 'FAIL'
});
result.checks.push({
item: '本月支出',
found: hasExpense,
status: hasExpense ? 'PASS' : 'FAIL'
});
if (hasIncome) console.log('[PASS] 本月收入显示');
if (hasExpense) console.log('[PASS] 本月支出显示');
// 检查预算进度
console.log('\n--- 检查预算进度 ---');
const hasBudget = pageText.includes('预算进度') || pageText.includes('预算');
const hasCategory = pageText.includes('餐饮') || pageText.includes('交通');
result.checks.push({
item: '预算进度区域',
found: hasBudget,
status: hasBudget ? 'PASS' : 'WARN'
});
result.checks.push({
item: '预算分类',
found: hasCategory,
status: hasCategory ? 'PASS' : 'WARN'
});
if (hasBudget) console.log('[PASS] 预算进度区域显示');
if (hasCategory) console.log('[PASS] 预算分类显示');
// 检查最近记录
console.log('\n--- 检查最近记录 ---');
const hasRecords = pageText.includes('最近记录') || pageText.includes('记录');
const hasRecordData = pageText.includes('午餐') ||
pageText.includes('地铁') ||
pageText.includes('工资') ||
pageText.includes('购物');
result.checks.push({
item: '最近记录区域',
found: hasRecords,
status: hasRecords ? 'PASS' : 'WARN'
});
result.checks.push({
item: '记录数据',
found: hasRecordData,
status: hasRecordData ? 'PASS' : 'WARN'
});
if (hasRecords) console.log('[PASS] 最近记录区域显示');
if (hasRecordData) console.log('[PASS] 记录数据显示');
} 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}`);
// 获取页面文本
const pageText = await page.textContent('body');
// 检查交易记录列表
console.log('\n--- 检查交易记录列表 ---');
// 预期记录数据
const expectedRecords = ['午餐', '地铁', '工资', '购物', '电影', '房租', '还款'];
let foundCount = 0;
for (const record of expectedRecords) {
if (pageText.includes(record)) {
foundCount++;
console.log(`[PASS] 找到记录: ${record}`);
}
}
result.checks.push({
item: '交易记录数据',
expected: `至少 5 条记录`,
found: foundCount >= 5,
status: foundCount >= 5 ? 'PASS' : 'FAIL'
});
if (foundCount < 5) {
result.issues.push(`只找到 ${foundCount} 条记录`);
}
// 检查记录类型(支出/收入)
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 foundButtons = [];
for (const button of switchButtons) {
const text = await button.textContent();
if (text && (text.includes('饼图') || text.includes('折线') || text.includes('柱状'))) {
foundButtons.push(text.trim());
}
}
console.log(`找到切换按钮: ${foundButtons.join(', ')}`);
result.checks.push({
item: '图表切换按钮',
expected: '饼图、折线图、柱状图',
found: foundButtons.length >= 3,
status: foundButtons.length >= 3 ? 'PASS' : 'WARN'
});
if (foundButtons.length >= 3) {
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 hasDataLabels = pageText.includes('餐饮') ||
pageText.includes('交通') ||
pageText.includes('购物') ||
pageText.includes('娱乐') ||
pageText.includes('支出') ||
pageText.includes('收入');
result.checks.push({
item: '数据标签',
found: hasDataLabels,
status: hasDataLabels ? 'PASS' : 'WARN'
});
if (hasDataLabels) {
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);