主要更新: - 🎯 新增综合分析仪表板,包含关键指标卡片、预算对比、智能洞察等组件 - 📊 增强数据可视化能力,新增标签云分析、时间维度分析等图表 - 📱 优化移动端响应式设计,改进触控交互体验 - 🔧 新增多个API模块(base、budget、tag),完善数据管理 - 🗂️ 重构路由结构,新增贷款、快速添加、设置、统计等独立模块 - 🔄 优化数据导入导出功能,增强数据迁移能力 - 🐛 修复多个已知问题,提升系统稳定性 技术改进: - 使用IndexedDB提升本地存储性能 - 实现模拟API服务,支持离线开发 - 增加自动化测试脚本,确保功能稳定 - 优化打包配置,提升构建效率 文件变更: - 新增42个文件 - 修改55个文件 - 包含测试脚本、配置文件、组件和API模块 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
206 lines
6.4 KiB
JavaScript
206 lines
6.4 KiB
JavaScript
import { chromium } from 'playwright';
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({
|
|
headless: false, // 有头模式,方便观察
|
|
});
|
|
const context = await browser.newContext();
|
|
const page = await context.newPage();
|
|
|
|
// 收集所有控制台错误
|
|
const consoleErrors = [];
|
|
page.on('console', (msg) => {
|
|
if (msg.type() === 'error') {
|
|
const errorText = msg.text();
|
|
// 忽略一些常见的无害错误
|
|
if (
|
|
!errorText.includes('validate error') &&
|
|
!errorText.includes('ResizeObserver') &&
|
|
!errorText.includes('Non-Error promise rejection')
|
|
) {
|
|
consoleErrors.push({
|
|
url: page.url(),
|
|
error: errorText,
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
try {
|
|
console.log('开始测试所有菜单页面...\n');
|
|
|
|
// 先访问一个内部页面来触发登录
|
|
await page.goto('http://localhost:5666/finance/dashboard', {
|
|
waitUntil: 'domcontentloaded',
|
|
timeout: 30_000,
|
|
});
|
|
|
|
// 处理登录
|
|
if (page.url().includes('/auth/login')) {
|
|
console.log('需要登录,正在处理...');
|
|
|
|
// 等待页面稳定
|
|
await page.waitForTimeout(2000);
|
|
|
|
// 查找并填写用户名
|
|
const usernameInput = await page.locator('input[type="text"]').first();
|
|
await usernameInput.click();
|
|
await usernameInput.fill('vben');
|
|
|
|
// 查找并填写密码
|
|
const passwordInput = await page
|
|
.locator('input[type="password"]')
|
|
.first();
|
|
await passwordInput.click();
|
|
await passwordInput.fill('123456');
|
|
|
|
// 提交表单
|
|
await page.keyboard.press('Enter');
|
|
|
|
// 等待登录处理
|
|
await page.waitForTimeout(3000);
|
|
|
|
// 检查是否登录成功
|
|
if (page.url().includes('/auth/login')) {
|
|
console.log('⚠️ 可能需要验证码,尝试点击登录按钮...');
|
|
// 尝试找到并点击登录按钮
|
|
const loginBtn = await page
|
|
.locator('button')
|
|
.filter({ hasText: /登\s*录|Login/i })
|
|
.first();
|
|
if (await loginBtn.isVisible()) {
|
|
await loginBtn.click();
|
|
await page.waitForTimeout(3000);
|
|
}
|
|
} else {
|
|
console.log('✓ 登录成功\n');
|
|
}
|
|
}
|
|
|
|
// 定义所有需要测试的菜单路径
|
|
const menuPaths = [
|
|
{ name: '财务概览', path: '/finance/dashboard' },
|
|
{ name: '交易管理', path: '/finance/transaction' },
|
|
{ name: '分类管理', path: '/finance/category' },
|
|
{ name: '人员管理', path: '/finance/person' },
|
|
{ name: '贷款管理', path: '/finance/loan' },
|
|
{ name: '数据概览', path: '/analytics/overview' },
|
|
{ name: '趋势分析', path: '/analytics/trends' },
|
|
{ name: '导入数据', path: '/tools/import' },
|
|
{ name: '导出数据', path: '/tools/export' },
|
|
{ name: '数据备份', path: '/tools/backup' },
|
|
{ name: '预算管理', path: '/tools/budget' },
|
|
{ name: '标签管理', path: '/tools/tags' },
|
|
];
|
|
|
|
console.log('开始逐个访问菜单...');
|
|
|
|
// 逐个访问每个菜单
|
|
for (const menu of menuPaths) {
|
|
console.log(`\n===============================`);
|
|
console.log(`测试菜单: ${menu.name}`);
|
|
console.log(`访问路径: ${menu.path}`);
|
|
|
|
try {
|
|
// 访问页面
|
|
const response = await page.goto(`http://localhost:5666${menu.path}`, {
|
|
waitUntil: 'networkidle',
|
|
timeout: 15_000,
|
|
});
|
|
|
|
// 等待页面加载
|
|
await page.waitForTimeout(2000);
|
|
|
|
// 检查是否被重定向到登录页
|
|
if (page.url().includes('/auth/login')) {
|
|
console.log('✗ 被重定向到登录页面');
|
|
continue;
|
|
}
|
|
|
|
// 基本检查
|
|
console.log(`✓ 页面加载成功`);
|
|
console.log(` 当前URL: ${page.url()}`);
|
|
|
|
// 检查页面元素
|
|
const pageChecks = {
|
|
页面标题: await page
|
|
.locator('h1, h2, .page-header-title')
|
|
.first()
|
|
.textContent()
|
|
.catch(() => '未找到'),
|
|
卡片组件: await page.locator('.ant-card').count(),
|
|
表格组件: await page.locator('.ant-table').count(),
|
|
表单组件: await page.locator('.ant-form').count(),
|
|
按钮数量: await page.locator('button').count(),
|
|
空状态: await page.locator('.ant-empty').count(),
|
|
};
|
|
|
|
// 输出检查结果
|
|
for (const [key, value] of Object.entries(pageChecks)) {
|
|
if (value !== '未找到' && value !== 0) {
|
|
console.log(` ${key}: ${value}`);
|
|
}
|
|
}
|
|
|
|
// 特殊页面检查
|
|
if (menu.path.includes('/analytics/')) {
|
|
const charts = await page
|
|
.locator('canvas, .echarts-container, [class*="chart"]')
|
|
.count();
|
|
if (charts > 0) {
|
|
console.log(` ✓ 图表组件: ${charts} 个`);
|
|
} else {
|
|
console.log(` ⚠️ 未找到图表组件`);
|
|
}
|
|
}
|
|
|
|
if (menu.path.includes('/finance/transaction')) {
|
|
// 检查交易表格
|
|
const rows = await page.locator('.ant-table-row').count();
|
|
console.log(` 表格行数: ${rows}`);
|
|
}
|
|
|
|
// 检查是否有错误提示
|
|
const errors = await page
|
|
.locator('.ant-alert-error, .ant-message-error')
|
|
.count();
|
|
if (errors > 0) {
|
|
console.log(` ⚠️ 错误提示: ${errors} 个`);
|
|
}
|
|
|
|
// 截图
|
|
await page.screenshot({
|
|
path: `test-screenshots${menu.path.replaceAll('/', '-')}.png`,
|
|
fullPage: false, // 只截取可见区域
|
|
});
|
|
} catch (error) {
|
|
console.log(`✗ 访问失败: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
// 输出总结
|
|
console.log('\n===============================');
|
|
console.log('测试总结');
|
|
console.log('===============================');
|
|
|
|
if (consoleErrors.length > 0) {
|
|
console.log('\n控制台错误:');
|
|
consoleErrors.forEach((err, index) => {
|
|
console.log(`${index + 1}. [${err.url}]`);
|
|
console.log(` ${err.error}`);
|
|
});
|
|
} else {
|
|
console.log('\n✓ 没有发现控制台错误');
|
|
}
|
|
|
|
console.log('\n✓ 测试完成!');
|
|
console.log('截图已保存到 test-screenshots 目录');
|
|
} catch (error) {
|
|
console.error('测试失败:', error);
|
|
} finally {
|
|
// 等待用户查看
|
|
await page.waitForTimeout(10_000);
|
|
await browser.close();
|
|
}
|
|
})();
|