feat: 配置开发环境和清理项目结构
- 修改默认路由重定向到首页 (/home) - 配置开发服务器使用5667端口 - 整理测试文件到temp-tests目录 - 优化项目结构便于开发和部署 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
187
temp-tests/test-analytics-complete.js
Normal file
187
temp-tests/test-analytics-complete.js
Normal file
@@ -0,0 +1,187 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
});
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
// 监听控制台错误
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
console.error('浏览器控制台错误:', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('🚀 开始完整测试分析功能...\n');
|
||||
|
||||
// 1. 访问首页并登录
|
||||
console.log('1. 登录系统...');
|
||||
await page.goto('http://localhost:5669/', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否需要登录
|
||||
const needLogin = await page.locator('button:has-text("登录")').isVisible();
|
||||
if (needLogin) {
|
||||
await page.fill('input[placeholder*="账号"]', 'vben');
|
||||
await page.fill('input[placeholder*="密码"]', '123456');
|
||||
await page.locator('button:has-text("登录")').click();
|
||||
await page.waitForTimeout(3000);
|
||||
console.log(' ✅ 登录成功');
|
||||
}
|
||||
|
||||
// 2. 刷新页面让菜单重新加载
|
||||
console.log('\n2. 刷新页面重新加载菜单...');
|
||||
await page.reload({ waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 3. 查找并点击数据分析菜单
|
||||
console.log('\n3. 导航到分析页面...');
|
||||
|
||||
// 尝试查找数据分析菜单
|
||||
const analyticsMenu = await page.locator('span:has-text("数据分析")').first();
|
||||
if (await analyticsMenu.isVisible()) {
|
||||
console.log(' ✅ 找到"数据分析"菜单');
|
||||
await analyticsMenu.click();
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
// 查找数据概览子菜单
|
||||
const overviewMenu = await page.locator('span:has-text("数据概览")').first();
|
||||
if (await overviewMenu.isVisible()) {
|
||||
console.log(' ✅ 找到"数据概览"子菜单');
|
||||
await overviewMenu.click();
|
||||
await page.waitForTimeout(3000);
|
||||
} else {
|
||||
console.log(' ❌ 未找到"数据概览"子菜单,尝试直接访问URL');
|
||||
await page.goto('http://localhost:5669/analytics/overview', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
} else {
|
||||
console.log(' ❌ 未找到"数据分析"菜单,尝试直接访问URL');
|
||||
await page.goto('http://localhost:5668/analytics/overview', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// 4. 检查页面是否正确加载
|
||||
console.log('\n4. 检查页面加载状态...');
|
||||
const currentUrl = page.url();
|
||||
console.log(' 当前URL:', currentUrl);
|
||||
|
||||
// 检查是否还是404
|
||||
const is404 = await page.locator('text="404"').isVisible();
|
||||
if (is404) {
|
||||
console.log(' ❌ 页面仍然显示404错误');
|
||||
console.log('\n 尝试访问财务管理页面作为备选...');
|
||||
|
||||
// 访问财务管理
|
||||
await page.goto('http://localhost:5669/finance/dashboard', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
const financeLoaded = !await page.locator('text="404"').isVisible();
|
||||
if (financeLoaded) {
|
||||
console.log(' ✅ 财务管理页面加载成功');
|
||||
}
|
||||
} else {
|
||||
console.log(' ✅ 分析页面加载成功!');
|
||||
|
||||
// 5. 详细检查功能组件
|
||||
console.log('\n5. 检查关键功能组件...');
|
||||
|
||||
// 等待组件加载
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查关键指标卡片
|
||||
const hasMetricsCards = await page.locator('.key-metrics-cards').isVisible();
|
||||
console.log(` 关键指标卡片: ${hasMetricsCards ? '✅' : '❌'}`);
|
||||
|
||||
if (hasMetricsCards) {
|
||||
const metricsCount = await page.locator('.metric-card').count();
|
||||
console.log(` - 发现 ${metricsCount} 个指标卡片`);
|
||||
|
||||
// 检查具体指标
|
||||
const indicators = [
|
||||
{ selector: '.ant-statistic-title:has-text("总收入")', name: '总收入' },
|
||||
{ selector: '.ant-statistic-title:has-text("总支出")', name: '总支出' },
|
||||
{ selector: '.ant-statistic-title:has-text("净收益")', name: '净收益' },
|
||||
{ selector: '.ant-statistic-title:has-text("日均收支")', name: '日均收支' },
|
||||
];
|
||||
|
||||
for (const ind of indicators) {
|
||||
const visible = await page.locator(ind.selector).isVisible();
|
||||
console.log(` - ${ind.name}: ${visible ? '✅' : '❌'}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查标签页
|
||||
const hasTabs = await page.locator('.ant-tabs').isVisible();
|
||||
console.log(`\n 标签页导航: ${hasTabs ? '✅' : '❌'}`);
|
||||
|
||||
if (hasTabs) {
|
||||
const tabs = [
|
||||
{ name: '核心指标', selector: '.trend-chart' },
|
||||
{ name: '预算分析', selector: '.budget-comparison' },
|
||||
{ name: '智能洞察', selector: '.smart-insights' },
|
||||
{ name: '标签分析', selector: '.tag-cloud-analysis' },
|
||||
{ name: '时间维度', selector: '.time-dimension-analysis' },
|
||||
];
|
||||
|
||||
for (const tab of tabs) {
|
||||
console.log(`\n 测试"${tab.name}"标签页...`);
|
||||
const tabElement = await page.locator(`.ant-tabs-tab:has-text("${tab.name}")`);
|
||||
|
||||
if (await tabElement.isVisible()) {
|
||||
await tabElement.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查对应组件是否加载
|
||||
const componentVisible = await page.locator(tab.selector).isVisible();
|
||||
console.log(` 组件加载: ${componentVisible ? '✅' : '❌'}`);
|
||||
|
||||
// 截取每个标签页的截图
|
||||
await page.screenshot({
|
||||
path: `analytics-tab-${tab.name.replace(/[^a-z0-9]/gi, '-')}.png`,
|
||||
fullPage: false
|
||||
});
|
||||
} else {
|
||||
console.log(` 标签不可见 ❌`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 测试交互功能
|
||||
console.log('\n6. 测试交互功能...');
|
||||
|
||||
// 测试日期选择器
|
||||
const dateRangePicker = await page.locator('.ant-picker-range');
|
||||
if (await dateRangePicker.isVisible()) {
|
||||
console.log(' 日期范围选择器: ✅');
|
||||
}
|
||||
|
||||
// 测试刷新按钮
|
||||
const refreshButton = await page.locator('button:has-text("刷新数据")');
|
||||
if (await refreshButton.isVisible()) {
|
||||
console.log(' 刷新数据按钮: ✅');
|
||||
await refreshButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
console.log(' 数据刷新完成');
|
||||
}
|
||||
|
||||
// 最终成功截图
|
||||
await page.screenshot({ path: 'analytics-complete-success.png', fullPage: true });
|
||||
console.log('\n📸 完整功能测试截图已保存: analytics-complete-success.png');
|
||||
|
||||
console.log('\n✅ 🎉 分析功能测试完全成功!所有组件正常工作!');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试过程中出错:', error);
|
||||
await page.screenshot({ path: 'analytics-complete-error.png' });
|
||||
console.log('错误截图已保存: analytics-complete-error.png');
|
||||
} finally {
|
||||
console.log('\n测试完成,5秒后关闭浏览器...');
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
144
temp-tests/test-analytics-debug.js
Normal file
144
temp-tests/test-analytics-debug.js
Normal file
@@ -0,0 +1,144 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
devtools: true // 打开开发者工具
|
||||
});
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
// 监听控制台消息
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
console.error('浏览器控制台错误:', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
// 监听页面错误
|
||||
page.on('pageerror', error => {
|
||||
console.error('页面错误:', error.message);
|
||||
});
|
||||
|
||||
// 监听响应
|
||||
page.on('response', response => {
|
||||
if (response.status() >= 400) {
|
||||
console.log(`请求失败: ${response.url()} - 状态码: ${response.status()}`);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('开始调试分析功能...\n');
|
||||
|
||||
// 1. 首先访问首页
|
||||
console.log('1. 访问首页...');
|
||||
await page.goto('http://localhost:5667/', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否需要登录
|
||||
const needLogin = await page.locator('button:has-text("登录")').isVisible();
|
||||
if (needLogin) {
|
||||
console.log(' 需要登录,使用默认账号...');
|
||||
await page.fill('input[placeholder*="账号"]', 'vben');
|
||||
await page.fill('input[placeholder*="密码"]', '123456');
|
||||
await page.locator('button:has-text("登录")').click();
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// 2. 检查菜单
|
||||
console.log('\n2. 检查菜单结构...');
|
||||
const analyticsMenu = await page.locator('span:has-text("数据分析")').first();
|
||||
if (await analyticsMenu.isVisible()) {
|
||||
console.log(' ✅ 找到"数据分析"菜单');
|
||||
await analyticsMenu.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 查找数据概览子菜单
|
||||
const overviewMenu = await page.locator('span:has-text("数据概览")').first();
|
||||
if (await overviewMenu.isVisible()) {
|
||||
console.log(' ✅ 找到"数据概览"子菜单');
|
||||
await overviewMenu.click();
|
||||
await page.waitForTimeout(2000);
|
||||
} else {
|
||||
console.log(' ❌ 未找到"数据概览"子菜单');
|
||||
}
|
||||
} else {
|
||||
console.log(' ❌ 未找到"数据分析"菜单');
|
||||
}
|
||||
|
||||
// 3. 检查当前URL
|
||||
console.log('\n3. 检查当前页面...');
|
||||
const currentUrl = page.url();
|
||||
console.log(' 当前URL:', currentUrl);
|
||||
|
||||
// 4. 直接导航到分析页面
|
||||
console.log('\n4. 直接访问分析页面...');
|
||||
await page.goto('http://localhost:5667/analytics/overview', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查是否404
|
||||
const is404 = await page.locator('text="404"').isVisible();
|
||||
if (is404) {
|
||||
console.log(' ❌ 页面返回404错误');
|
||||
|
||||
// 检查可用的路由
|
||||
console.log('\n5. 尝试其他路由...');
|
||||
const testRoutes = [
|
||||
'/finance/dashboard',
|
||||
'/finance/transaction',
|
||||
'/dashboard/analytics',
|
||||
'/analytics',
|
||||
];
|
||||
|
||||
for (const route of testRoutes) {
|
||||
await page.goto(`http://localhost:5667${route}`, { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(1000);
|
||||
const hasError = await page.locator('text="404"').isVisible();
|
||||
console.log(` ${route}: ${hasError ? '❌ 404' : '✅ 成功'}`);
|
||||
}
|
||||
} else {
|
||||
console.log(' ✅ 页面加载成功');
|
||||
|
||||
// 检查组件是否加载
|
||||
console.log('\n6. 检查组件加载...');
|
||||
const components = [
|
||||
{ selector: '.key-metrics-cards', name: '关键指标卡片' },
|
||||
{ selector: '.ant-tabs', name: '标签页' },
|
||||
{ selector: '.budget-comparison', name: '预算对比' },
|
||||
{ selector: '.smart-insights', name: '智能洞察' },
|
||||
{ selector: '.tag-cloud-analysis', name: '标签云' },
|
||||
{ selector: '.time-dimension-analysis', name: '时间维度' },
|
||||
];
|
||||
|
||||
for (const comp of components) {
|
||||
const isVisible = await page.locator(comp.selector).isVisible();
|
||||
console.log(` ${comp.name}: ${isVisible ? '✅' : '❌'}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 7. 获取页面内容检查
|
||||
console.log('\n7. 页面内容检查...');
|
||||
const pageTitle = await page.title();
|
||||
console.log(' 页面标题:', pageTitle);
|
||||
|
||||
const bodyText = await page.locator('body').textContent();
|
||||
if (bodyText.includes('数据概览')) {
|
||||
console.log(' ✅ 找到"数据概览"文本');
|
||||
}
|
||||
if (bodyText.includes('关键指标')) {
|
||||
console.log(' ✅ 找到"关键指标"相关内容');
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'analytics-debug.png', fullPage: true });
|
||||
console.log('\n📸 调试截图已保存: analytics-debug.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ 调试过程中出错:', error);
|
||||
await page.screenshot({ path: 'error-debug.png' });
|
||||
} finally {
|
||||
console.log('\n按任意键关闭浏览器...');
|
||||
await page.waitForTimeout(10000); // 等待10秒让开发者查看
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
139
temp-tests/test-analytics-features.js
Normal file
139
temp-tests/test-analytics-features.js
Normal file
@@ -0,0 +1,139 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
console.log('开始测试分析功能...');
|
||||
|
||||
// 访问登录页
|
||||
await page.goto('http://localhost:5667/');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 跳过登录或使用默认账号
|
||||
const loginButton = await page.locator('button:has-text("登录")').first();
|
||||
if (await loginButton.isVisible()) {
|
||||
console.log('正在登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'vben');
|
||||
await page.fill('input[placeholder*="密码"]', '123456');
|
||||
await loginButton.click();
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// 导航到分析页面
|
||||
console.log('导航到分析页面...');
|
||||
await page.goto('http://localhost:5667/analytics/overview');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查关键指标卡片
|
||||
console.log('\n✅ 检查关键指标卡片...');
|
||||
const metricsCards = await page.locator('.key-metrics-cards').isVisible();
|
||||
console.log('- 关键指标卡片显示:', metricsCards);
|
||||
|
||||
if (metricsCards) {
|
||||
const totalIncome = await page.locator('.ant-statistic-title:has-text("总收入")').isVisible();
|
||||
const totalExpense = await page.locator('.ant-statistic-title:has-text("总支出")').isVisible();
|
||||
const netProfit = await page.locator('.ant-statistic-title:has-text("净收益")').isVisible();
|
||||
const dailyAvg = await page.locator('.ant-statistic-title:has-text("日均收支")').isVisible();
|
||||
|
||||
console.log(' - 总收入卡片:', totalIncome);
|
||||
console.log(' - 总支出卡片:', totalExpense);
|
||||
console.log(' - 净收益卡片:', netProfit);
|
||||
console.log(' - 日均收支卡片:', dailyAvg);
|
||||
}
|
||||
|
||||
// 测试各个标签页
|
||||
console.log('\n✅ 测试标签页切换...');
|
||||
|
||||
// 测试预算分析标签
|
||||
const budgetTab = await page.locator('.ant-tabs-tab:has-text("预算分析")');
|
||||
if (await budgetTab.isVisible()) {
|
||||
console.log('- 切换到预算分析标签');
|
||||
await budgetTab.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const budgetComparison = await page.locator('.budget-comparison').isVisible();
|
||||
console.log(' 预算对比组件显示:', budgetComparison);
|
||||
}
|
||||
|
||||
// 测试智能洞察标签
|
||||
const insightsTab = await page.locator('.ant-tabs-tab:has-text("智能洞察")');
|
||||
if (await insightsTab.isVisible()) {
|
||||
console.log('- 切换到智能洞察标签');
|
||||
await insightsTab.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const smartInsights = await page.locator('.smart-insights').isVisible();
|
||||
console.log(' 智能洞察组件显示:', smartInsights);
|
||||
|
||||
// 检查洞察内容
|
||||
const insightItems = await page.locator('.insight-item').count();
|
||||
console.log(` 发现 ${insightItems} 条洞察建议`);
|
||||
}
|
||||
|
||||
// 测试标签分析标签
|
||||
const tagTab = await page.locator('.ant-tabs-tab:has-text("标签分析")');
|
||||
if (await tagTab.isVisible()) {
|
||||
console.log('- 切换到标签分析标签');
|
||||
await tagTab.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const tagCloud = await page.locator('.tag-cloud-analysis').isVisible();
|
||||
console.log(' 标签云分析组件显示:', tagCloud);
|
||||
}
|
||||
|
||||
// 测试时间维度标签
|
||||
const timeTab = await page.locator('.ant-tabs-tab:has-text("时间维度")');
|
||||
if (await timeTab.isVisible()) {
|
||||
console.log('- 切换到时间维度标签');
|
||||
await timeTab.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const timeDimension = await page.locator('.time-dimension-analysis').isVisible();
|
||||
console.log(' 时间维度分析组件显示:', timeDimension);
|
||||
|
||||
// 测试视图切换
|
||||
const viewModes = await page.locator('.ant-radio-button-wrapper').count();
|
||||
console.log(` 发现 ${viewModes} 个视图模式`);
|
||||
|
||||
if (viewModes > 0) {
|
||||
const hourView = await page.locator('.ant-radio-button-wrapper:has-text("时段")');
|
||||
if (await hourView.isVisible()) {
|
||||
console.log(' 切换到时段视图');
|
||||
await hourView.click();
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 测试日期筛选
|
||||
console.log('\n✅ 测试日期筛选功能...');
|
||||
const dateRangePicker = await page.locator('.ant-picker-range');
|
||||
if (await dateRangePicker.isVisible()) {
|
||||
console.log('- 日期范围选择器可用');
|
||||
|
||||
// 测试刷新按钮
|
||||
const refreshButton = await page.locator('button:has-text("刷新数据")');
|
||||
if (await refreshButton.isVisible()) {
|
||||
console.log('- 点击刷新数据');
|
||||
await refreshButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
}
|
||||
|
||||
// 截图保存
|
||||
console.log('\n📸 保存截图...');
|
||||
await page.screenshot({ path: 'analytics-overview.png', fullPage: true });
|
||||
|
||||
console.log('\n✨ 分析功能测试完成!');
|
||||
console.log('所有新功能都已成功集成并正常工作。');
|
||||
|
||||
} catch (error) {
|
||||
console.error('测试过程中出错:', error);
|
||||
await page.screenshot({ path: 'error-screenshot.png' });
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
144
temp-tests/test-analytics-final.js
Normal file
144
temp-tests/test-analytics-final.js
Normal file
@@ -0,0 +1,144 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
});
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
// 监听控制台错误
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
console.error('浏览器控制台错误:', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('🚀 开始测试新的分析功能...\n');
|
||||
|
||||
// 1. 访问首页并登录
|
||||
console.log('1. 登录系统...');
|
||||
await page.goto('http://localhost:5668/', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const needLogin = await page.locator('button:has-text("登录")').isVisible();
|
||||
if (needLogin) {
|
||||
await page.fill('input[placeholder*="账号"]', 'vben');
|
||||
await page.fill('input[placeholder*="密码"]', '123456');
|
||||
await page.locator('button:has-text("登录")').click();
|
||||
await page.waitForTimeout(3000);
|
||||
console.log(' ✅ 登录成功');
|
||||
}
|
||||
|
||||
// 2. 导航到分析页面
|
||||
console.log('\n2. 导航到分析页面...');
|
||||
|
||||
// 尝试通过菜单导航
|
||||
const analyticsMenu = await page.locator('span:has-text("数据分析")').first();
|
||||
if (await analyticsMenu.isVisible()) {
|
||||
console.log(' 点击数据分析菜单');
|
||||
await analyticsMenu.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const overviewMenu = await page.locator('span:has-text("数据概览")').first();
|
||||
if (await overviewMenu.isVisible()) {
|
||||
console.log(' 点击数据概览子菜单');
|
||||
await overviewMenu.click();
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
} else {
|
||||
// 直接导航
|
||||
console.log(' 直接访问分析页面URL');
|
||||
await page.goto('http://localhost:5668/analytics/overview', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// 3. 检查页面是否正确加载
|
||||
console.log('\n3. 检查页面加载状态...');
|
||||
const currentUrl = page.url();
|
||||
console.log(' 当前URL:', currentUrl);
|
||||
|
||||
const is404 = await page.locator('text="404"').isVisible();
|
||||
if (is404) {
|
||||
console.log(' ❌ 页面显示404错误');
|
||||
|
||||
// 截图保存错误状态
|
||||
await page.screenshot({ path: 'analytics-404-error.png', fullPage: true });
|
||||
console.log(' 错误截图已保存: analytics-404-error.png');
|
||||
|
||||
// 尝试返回首页再重新导航
|
||||
console.log('\n4. 尝试从首页重新导航...');
|
||||
await page.goto('http://localhost:5668/workspace', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
} else {
|
||||
console.log(' ✅ 页面加载成功');
|
||||
|
||||
// 4. 检查关键功能组件
|
||||
console.log('\n4. 检查关键功能组件...');
|
||||
|
||||
// 检查关键指标卡片
|
||||
const hasMetricsCards = await page.locator('.key-metrics-cards').isVisible();
|
||||
console.log(` 关键指标卡片: ${hasMetricsCards ? '✅' : '❌'}`);
|
||||
|
||||
if (hasMetricsCards) {
|
||||
const metricsCount = await page.locator('.metric-card').count();
|
||||
console.log(` - 发现 ${metricsCount} 个指标卡片`);
|
||||
}
|
||||
|
||||
// 检查标签页
|
||||
const hasTabs = await page.locator('.ant-tabs').isVisible();
|
||||
console.log(` 标签页导航: ${hasTabs ? '✅' : '❌'}`);
|
||||
|
||||
if (hasTabs) {
|
||||
const tabCount = await page.locator('.ant-tabs-tab').count();
|
||||
console.log(` - 发现 ${tabCount} 个标签页`);
|
||||
|
||||
// 测试每个标签页
|
||||
const tabs = [
|
||||
{ name: '预算分析', selector: '.budget-comparison' },
|
||||
{ name: '智能洞察', selector: '.smart-insights' },
|
||||
{ name: '标签分析', selector: '.tag-cloud-analysis' },
|
||||
{ name: '时间维度', selector: '.time-dimension-analysis' },
|
||||
];
|
||||
|
||||
for (const tab of tabs) {
|
||||
const tabElement = await page.locator(`.ant-tabs-tab:has-text("${tab.name}")`);
|
||||
if (await tabElement.isVisible()) {
|
||||
console.log(`\n 测试 ${tab.name} 标签页...`);
|
||||
await tabElement.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const componentVisible = await page.locator(tab.selector).isVisible();
|
||||
console.log(` 组件显示: ${componentVisible ? '✅' : '❌'}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 测试数据刷新功能
|
||||
console.log('\n5. 测试数据刷新...');
|
||||
const refreshButton = await page.locator('button:has-text("刷新数据")');
|
||||
if (await refreshButton.isVisible()) {
|
||||
console.log(' 点击刷新按钮');
|
||||
await refreshButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
console.log(' ✅ 数据刷新完成');
|
||||
}
|
||||
|
||||
// 成功截图
|
||||
await page.screenshot({ path: 'analytics-success.png', fullPage: true });
|
||||
console.log('\n📸 功能测试截图已保存: analytics-success.png');
|
||||
}
|
||||
|
||||
console.log('\n✨ 测试完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试过程中出错:', error);
|
||||
await page.screenshot({ path: 'analytics-error.png' });
|
||||
console.log('错误截图已保存: analytics-error.png');
|
||||
} finally {
|
||||
await page.waitForTimeout(5000); // 等待5秒让用户查看
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
131
temp-tests/test-auto-login.js
Normal file
131
temp-tests/test-auto-login.js
Normal file
@@ -0,0 +1,131 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 300,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 监听控制台
|
||||
page.on('console', (msg) => {
|
||||
const text = msg.text();
|
||||
if (text.includes('开发模式')) {
|
||||
console.log('[自动登录]', text);
|
||||
}
|
||||
if (msg.type() === 'error') {
|
||||
console.log('[错误]', text);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('========== 测试自动登录功能 ==========\n');
|
||||
|
||||
// 1. 访问登录页
|
||||
console.log('1. 访问登录页面...');
|
||||
await page.goto('http://localhost:5667/auth/login');
|
||||
console.log(' 等待自动登录...');
|
||||
|
||||
// 等待自动登录执行
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 2. 检查是否自动跳转
|
||||
const currentUrl = page.url();
|
||||
console.log(' 当前URL:', currentUrl);
|
||||
|
||||
if (currentUrl.includes('/login')) {
|
||||
console.log(' ⚠️ 自动登录未执行或失败');
|
||||
console.log(' 请检查是否在开发模式下运行');
|
||||
|
||||
// 检查页面元素
|
||||
const sliderBtn = await page.locator('.slider-button');
|
||||
const captchaVisible = await sliderBtn.isVisible();
|
||||
console.log(` 验证码是否显示: ${captchaVisible ? '是' : '否'}`);
|
||||
|
||||
await page.screenshot({ path: 'auto-login-failed.png' });
|
||||
console.log('\n截图保存: auto-login-failed.png');
|
||||
} else {
|
||||
console.log(' ✅ 自动登录成功!已跳转到首页\n');
|
||||
|
||||
// 3. 访问交易管理页面
|
||||
console.log('2. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查页面元素
|
||||
const table = await page.locator('.ant-table');
|
||||
const createBtn = await page.locator('button:has-text("新建")');
|
||||
|
||||
if (await table.isVisible()) {
|
||||
console.log(' ✅ 交易列表显示正常');
|
||||
|
||||
const rows = await page.locator('.ant-table-tbody tr').count();
|
||||
console.log(` 当前有 ${rows} 条交易记录`);
|
||||
}
|
||||
|
||||
// 4. 测试新建交易
|
||||
if (await createBtn.isVisible()) {
|
||||
console.log('\n3. 测试新建交易功能...');
|
||||
await createBtn.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const modal = await page.locator('.ant-modal');
|
||||
if (await modal.isVisible()) {
|
||||
console.log(' ✅ 新建交易弹窗打开');
|
||||
|
||||
// 选择类型
|
||||
const typeSelect = await page.locator('.ant-select').nth(0);
|
||||
await typeSelect.click();
|
||||
await page.locator('.ant-select-item:has-text("支出")').click();
|
||||
console.log(' 选择类型: 支出');
|
||||
|
||||
// 输入金额
|
||||
const amountInput = await page.locator(
|
||||
'input.ant-input-number-input',
|
||||
);
|
||||
await amountInput.fill('288.88');
|
||||
console.log(' 输入金额: 288.88');
|
||||
|
||||
// 输入描述
|
||||
const descInput = await page.locator('textarea[placeholder*="描述"]');
|
||||
if (await descInput.isVisible()) {
|
||||
await descInput.fill('自动登录测试交易');
|
||||
console.log(' 输入描述: 自动登录测试交易');
|
||||
}
|
||||
|
||||
// 提交
|
||||
const submitBtn = await page.locator(
|
||||
'.ant-modal-footer button.ant-btn-primary',
|
||||
);
|
||||
await submitBtn.click();
|
||||
console.log(' 提交表单...');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查结果
|
||||
const successMsg = await page.locator('.ant-message-success');
|
||||
if (await successMsg.isVisible()) {
|
||||
console.log(' ✅ 交易创建成功!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'auto-login-success.png', fullPage: true });
|
||||
console.log('\n截图保存: auto-login-success.png');
|
||||
|
||||
console.log('\n========== 测试完成 ==========');
|
||||
console.log('✅ 开发模式自动登录正常');
|
||||
console.log('✅ 无需手动处理验证码');
|
||||
console.log('✅ 交易管理功能正常');
|
||||
console.log('✅ 新建交易功能正常');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'error.png' });
|
||||
} finally {
|
||||
console.log('\n浏览器将在5秒后关闭...');
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
87
temp-tests/test-category-stats-fixed.js
Normal file
87
temp-tests/test-category-stats-fixed.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问分类统计页面...');
|
||||
await page.goto('http://localhost:5666/finance/category-stats', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查当前URL
|
||||
const currentUrl = page.url();
|
||||
console.log('当前URL:', currentUrl);
|
||||
|
||||
if (currentUrl.includes('login')) {
|
||||
console.log('需要登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForTimeout(2000);
|
||||
await page.goto('http://localhost:5666/finance/category-stats', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
console.log('\n2. 测试快速日期选择...');
|
||||
|
||||
// 测试"本月"按钮选中状态
|
||||
const monthButtonClass = await page.locator('button:has-text("本月")').getAttribute('class');
|
||||
console.log(' - 本月按钮默认选中:', monthButtonClass?.includes('ant-radio-button-checked') ? '✓' : '✗');
|
||||
|
||||
// 点击"本年"
|
||||
await page.click('button:has-text("本年")');
|
||||
await page.waitForTimeout(1000);
|
||||
const yearButtonClass = await page.locator('button:has-text("本年")').getAttribute('class');
|
||||
console.log(' - 本年按钮选中:', yearButtonClass?.includes('ant-radio-button-checked') ? '✓' : '✗');
|
||||
|
||||
// 点击"今天"
|
||||
await page.click('button:has-text("今天")');
|
||||
await page.waitForTimeout(1000);
|
||||
const todayButtonClass = await page.locator('button:has-text("今天")').getAttribute('class');
|
||||
console.log(' - 今天按钮选中:', todayButtonClass?.includes('ant-radio-button-checked') ? '✓' : '✗');
|
||||
|
||||
console.log('\n3. 测试图表切换和数据显示...');
|
||||
|
||||
// 切换到柱状图
|
||||
await page.click('button:has-text("柱状图")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查柱状图是否显示
|
||||
const barChartVisible = await page.locator('div[style*="height: 500px"]:visible canvas').count();
|
||||
console.log(' - 柱状图显示:', barChartVisible > 0 ? '✓' : '✗');
|
||||
|
||||
// 截图柱状图
|
||||
await page.screenshot({ path: 'bar-chart.png' });
|
||||
console.log(' - 柱状图截图: bar-chart.png');
|
||||
|
||||
// 切换到趋势图
|
||||
await page.click('button:has-text("趋势图")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查趋势图是否显示
|
||||
const trendChartVisible = await page.locator('div[style*="height: 500px"]:visible canvas').count();
|
||||
console.log(' - 趋势图显示:', trendChartVisible > 0 ? '✓' : '✗');
|
||||
|
||||
// 截图趋势图
|
||||
await page.screenshot({ path: 'trend-chart.png' });
|
||||
console.log(' - 趋势图截图: trend-chart.png');
|
||||
|
||||
// 切换回饼图
|
||||
await page.click('button:has-text("饼图")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const pieChartVisible = await page.locator('div[style*="height: 500px"]:visible canvas').count();
|
||||
console.log(' - 饼图显示:', pieChartVisible > 0 ? '✓' : '✗');
|
||||
|
||||
// 最终截图
|
||||
await page.screenshot({ path: 'final-category-stats.png', fullPage: true });
|
||||
console.log('\n✅ 测试完成!最终截图: final-category-stats.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error.message);
|
||||
await page.screenshot({ path: 'test-error.png' });
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
104
temp-tests/test-category-stats.js
Normal file
104
temp-tests/test-category-stats.js
Normal file
@@ -0,0 +1,104 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问登录页面...');
|
||||
await page.goto('http://localhost:5666');
|
||||
|
||||
// 等待登录页面加载
|
||||
await page.waitForSelector('input[placeholder*="账号"]', { timeout: 10000 });
|
||||
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
|
||||
// 点击登录按钮
|
||||
await page.click('button:has-text("登录")');
|
||||
|
||||
// 等待跳转到首页
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
console.log('3. 登录成功,已进入系统');
|
||||
|
||||
// 导航到分类统计页面
|
||||
console.log('4. 访问分类统计页面...');
|
||||
await page.goto('http://localhost:5666/finance/category-stats');
|
||||
|
||||
// 等待页面加载完成
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// 检查页面元素
|
||||
console.log('5. 检查页面元素...');
|
||||
|
||||
// 检查统计卡片
|
||||
const totalIncomeCard = await page.locator('.ant-statistic-title:has-text("总收入")').isVisible();
|
||||
const totalExpenseCard = await page.locator('.ant-statistic-title:has-text("总支出")').isVisible();
|
||||
const netIncomeCard = await page.locator('.ant-statistic-title:has-text("净收入")').isVisible();
|
||||
|
||||
console.log(' - 总收入卡片:', totalIncomeCard ? '✓' : '✗');
|
||||
console.log(' - 总支出卡片:', totalExpenseCard ? '✓' : '✗');
|
||||
console.log(' - 净收入卡片:', netIncomeCard ? '✓' : '✗');
|
||||
|
||||
// 检查图表切换按钮
|
||||
const pieButton = await page.locator('button:has-text("饼图")').isVisible();
|
||||
const barButton = await page.locator('button:has-text("柱状图")').isVisible();
|
||||
const trendButton = await page.locator('button:has-text("趋势图")').isVisible();
|
||||
|
||||
console.log(' - 饼图按钮:', pieButton ? '✓' : '✗');
|
||||
console.log(' - 柱状图按钮:', barButton ? '✓' : '✗');
|
||||
console.log(' - 趋势图按钮:', trendButton ? '✓' : '✗');
|
||||
|
||||
// 切换到表格视图
|
||||
console.log('6. 切换到表格视图...');
|
||||
await page.click('button:has-text("表格")');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 检查表格是否显示
|
||||
const table = await page.locator('.ant-table').isVisible();
|
||||
console.log(' - 表格显示:', table ? '✓' : '✗');
|
||||
|
||||
// 切换回图表视图
|
||||
console.log('7. 切换回图表视图...');
|
||||
await page.click('button:has-text("图表")');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 切换不同的图表类型
|
||||
console.log('8. 测试图表切换...');
|
||||
await page.click('button:has-text("柱状图")');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log(' - 切换到柱状图: ✓');
|
||||
|
||||
await page.click('button:has-text("趋势图")');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log(' - 切换到趋势图: ✓');
|
||||
|
||||
await page.click('button:has-text("饼图")');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log(' - 切换回饼图: ✓');
|
||||
|
||||
// 测试日期快速选择
|
||||
console.log('9. 测试日期快速选择...');
|
||||
await page.click('button:has-text("本月")');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log(' - 选择本月: ✓');
|
||||
|
||||
await page.click('button:has-text("本年")');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log(' - 选择本年: ✓');
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'category-stats-test.png', fullPage: true });
|
||||
console.log('10. 页面截图已保存为 category-stats-test.png');
|
||||
|
||||
console.log('\n✅ 分类统计页面测试完成!所有功能正常工作。');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'category-stats-error.png' });
|
||||
console.log('错误截图已保存为 category-stats-error.png');
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
109
temp-tests/test-check-menu-full.js
Normal file
109
temp-tests/test-check-menu-full.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问系统...');
|
||||
await page.goto('http://localhost:5670');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查是否需要登录
|
||||
if (page.url().includes('login')) {
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
console.log('3. 刷新页面加载最新菜单...');
|
||||
await page.reload();
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 展开侧边栏
|
||||
const isCollapsed = await page.locator('.ant-layout-sider-collapsed').count();
|
||||
if (isCollapsed > 0) {
|
||||
console.log(' 展开侧边栏...');
|
||||
await page.click('.ant-layout-sider-trigger');
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
console.log('\n4. 检查菜单结构...');
|
||||
|
||||
// 获取所有可见的菜单项
|
||||
const menuItems = await page.locator('.ant-menu-item, .ant-menu-submenu').evaluateAll(elements => {
|
||||
return elements.map(el => {
|
||||
const titleEl = el.querySelector('.ant-menu-title-content');
|
||||
const iconEl = el.querySelector('.ant-menu-item-icon, .ant-menu-submenu-icon');
|
||||
const isSubmenu = el.classList.contains('ant-menu-submenu');
|
||||
const level = el.closest('.ant-menu-sub') ? 2 : 1;
|
||||
|
||||
return {
|
||||
text: titleEl?.textContent?.trim() || '',
|
||||
hasIcon: !!iconEl,
|
||||
isSubmenu,
|
||||
level,
|
||||
visible: window.getComputedStyle(el).display !== 'none'
|
||||
};
|
||||
}).filter(item => item.text && item.visible);
|
||||
});
|
||||
|
||||
console.log('\n当前菜单结构:');
|
||||
console.log('================');
|
||||
|
||||
menuItems.forEach((item, index) => {
|
||||
const prefix = item.level === 2 ? ' └─ ' : '';
|
||||
const type = item.isSubmenu ? '[父菜单]' : '[菜单项]';
|
||||
const icon = item.hasIcon ? '✓' : '✗';
|
||||
console.log(`${prefix}${index + 1}. ${item.text} ${type} 图标:${icon}`);
|
||||
});
|
||||
|
||||
console.log('\n期望的菜单顺序:');
|
||||
console.log('1. 记一笔 (快速记账)');
|
||||
console.log('2. 交易记录 (查看所有交易)');
|
||||
console.log('3. 统计分析 (各种报表)');
|
||||
console.log('4. 设置 (分类/预算/标签/人员)');
|
||||
console.log('5. 贷款管理');
|
||||
console.log('6. 系统工具 (导入导出等)');
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'menu-structure-check.png', fullPage: true });
|
||||
console.log('\n截图保存为: menu-structure-check.png');
|
||||
|
||||
// 点击测试
|
||||
console.log('\n5. 测试菜单点击...');
|
||||
|
||||
// 尝试点击"记一笔"
|
||||
const quickAddMenu = await page.locator('.ant-menu-item:has-text("记一笔")').count();
|
||||
if (quickAddMenu > 0) {
|
||||
console.log(' 找到"记一笔"菜单,点击测试...');
|
||||
await page.click('.ant-menu-item:has-text("记一笔")');
|
||||
await page.waitForTimeout(2000);
|
||||
console.log(' 当前URL:', page.url());
|
||||
} else {
|
||||
console.log(' ⚠️ 未找到"记一笔"菜单');
|
||||
}
|
||||
|
||||
// 尝试点击"交易记录"
|
||||
const transMenu = await page.locator('.ant-menu-item:has-text("交易记录")').count();
|
||||
if (transMenu > 0) {
|
||||
console.log(' 找到"交易记录"菜单,点击测试...');
|
||||
await page.click('.ant-menu-item:has-text("交易记录")');
|
||||
await page.waitForTimeout(2000);
|
||||
console.log(' 当前URL:', page.url());
|
||||
} else {
|
||||
console.log(' ⚠️ 未找到"交易记录"菜单');
|
||||
}
|
||||
|
||||
console.log('\n✅ 检查完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 错误:', error.message);
|
||||
await page.screenshot({ path: 'menu-error.png' });
|
||||
} finally {
|
||||
await page.waitForTimeout(3000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
107
temp-tests/test-check.js
Normal file
107
temp-tests/test-check.js
Normal file
@@ -0,0 +1,107 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 500,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('点击新建按钮...');
|
||||
const createBtn = await page
|
||||
.locator('button')
|
||||
.filter({ hasText: '新建' })
|
||||
.first();
|
||||
await createBtn.click();
|
||||
|
||||
console.log('等待弹窗...');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查弹窗中的按钮
|
||||
console.log('\n检查弹窗按钮...');
|
||||
const modalFooterButtons = await page
|
||||
.locator('.ant-modal-footer button')
|
||||
.all();
|
||||
console.log(`找到 ${modalFooterButtons.length} 个按钮`);
|
||||
|
||||
for (const [i, btn] of modalFooterButtons.entries()) {
|
||||
const text = await btn.textContent();
|
||||
const disabled = await btn.isDisabled();
|
||||
const classes = await btn.getAttribute('class');
|
||||
console.log(
|
||||
`按钮 ${i + 1}: 文本="${text}", 禁用=${disabled}, class="${classes}"`,
|
||||
);
|
||||
}
|
||||
|
||||
// 填写必填字段
|
||||
console.log('\n填写必填字段...');
|
||||
|
||||
// 1. 金额
|
||||
console.log('填写金额...');
|
||||
const amountInput = await page
|
||||
.locator('input.ant-input-number-input')
|
||||
.first();
|
||||
await amountInput.clear();
|
||||
await amountInput.fill('100');
|
||||
|
||||
// 2. 选择分类 - 使用更精确的方式
|
||||
console.log('选择分类...');
|
||||
// 先找到分类的选择框(在弹窗内)
|
||||
const modal = await page.locator('.ant-modal-content');
|
||||
const categorySelect = await modal.locator('.ant-select').nth(1);
|
||||
await categorySelect.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// 选择第一个选项
|
||||
const firstOption = await page
|
||||
.locator('.ant-select-dropdown:visible .ant-select-item')
|
||||
.first();
|
||||
if (await firstOption.isVisible()) {
|
||||
const optionText = await firstOption.textContent();
|
||||
console.log(`选择分类: ${optionText}`);
|
||||
await firstOption.click();
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
// 再次检查按钮状态
|
||||
console.log('\n填写后再次检查按钮...');
|
||||
const submitBtn = await page
|
||||
.locator('.ant-modal-footer button.ant-btn-primary')
|
||||
.first();
|
||||
if (await submitBtn.isVisible()) {
|
||||
const text = await submitBtn.textContent();
|
||||
const disabled = await submitBtn.isDisabled();
|
||||
console.log(`提交按钮: 文本="${text}", 禁用=${disabled}`);
|
||||
|
||||
if (!disabled) {
|
||||
console.log('点击提交...');
|
||||
await submitBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否有消息
|
||||
const successMsg = await page.locator('.ant-message-success');
|
||||
const errorMsg = await page.locator('.ant-message-error');
|
||||
|
||||
if (await successMsg.isVisible()) {
|
||||
console.log('✅ 成功提示出现');
|
||||
}
|
||||
if (await errorMsg.isVisible()) {
|
||||
const error = await errorMsg.textContent();
|
||||
console.log('❌ 错误提示:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('错误:', error.message);
|
||||
} finally {
|
||||
console.log('\n保持打开10秒供检查...');
|
||||
await page.waitForTimeout(10_000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
111
temp-tests/test-clear-cache-menu.js
Normal file
111
temp-tests/test-clear-cache-menu.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const context = await browser.newContext({
|
||||
// 完全清除缓存
|
||||
storageState: undefined
|
||||
});
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 清除所有缓存,重新登录...');
|
||||
|
||||
// 直接访问登录页
|
||||
await page.goto('http://localhost:5670/auth/login', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
|
||||
// 等待登录完成并跳转
|
||||
await page.waitForURL('**/workspace', { timeout: 10000 }).catch(() => {
|
||||
console.log(' 等待workspace页面超时,继续...');
|
||||
});
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('3. 检查侧边栏状态...');
|
||||
|
||||
// 展开侧边栏(如果是折叠的)
|
||||
const trigger = await page.locator('.ant-layout-sider-trigger').count();
|
||||
if (trigger > 0) {
|
||||
const isCollapsed = await page.locator('.ant-layout-sider-collapsed').count();
|
||||
if (isCollapsed > 0) {
|
||||
console.log(' 展开侧边栏...');
|
||||
await page.click('.ant-layout-sider-trigger');
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n4. 获取菜单信息...');
|
||||
|
||||
// 获取所有菜单项
|
||||
const allMenus = await page.locator('.ant-menu .ant-menu-title-content').allTextContents();
|
||||
|
||||
console.log('\n所有菜单项(按显示顺序):');
|
||||
console.log('========================');
|
||||
allMenus.forEach((text, index) => {
|
||||
console.log(`${index + 1}. ${text}`);
|
||||
});
|
||||
|
||||
// 分类检查
|
||||
console.log('\n菜单分类检查:');
|
||||
console.log('-------------');
|
||||
|
||||
const expectedMenus = [
|
||||
'记一笔',
|
||||
'交易记录',
|
||||
'统计分析',
|
||||
'设置',
|
||||
'贷款管理',
|
||||
'系统工具'
|
||||
];
|
||||
|
||||
for (const menuName of expectedMenus) {
|
||||
const found = allMenus.includes(menuName);
|
||||
console.log(`${found ? '✅' : '❌'} ${menuName}`);
|
||||
}
|
||||
|
||||
// 获取更详细的菜单信息
|
||||
const detailedMenus = await page.locator('.ant-menu-item, .ant-menu-submenu').evaluateAll(elements => {
|
||||
return elements.map(el => {
|
||||
const titleEl = el.querySelector('.ant-menu-title-content');
|
||||
const isActive = el.classList.contains('ant-menu-item-selected');
|
||||
const isSubmenu = el.classList.contains('ant-menu-submenu');
|
||||
const path = el.querySelector('a')?.getAttribute('href') || '';
|
||||
|
||||
return {
|
||||
text: titleEl?.textContent?.trim() || '',
|
||||
isActive,
|
||||
isSubmenu,
|
||||
path,
|
||||
classes: Array.from(el.classList).join(' ')
|
||||
};
|
||||
}).filter(item => item.text);
|
||||
});
|
||||
|
||||
console.log('\n详细菜单信息:');
|
||||
console.log('============');
|
||||
detailedMenus.forEach(menu => {
|
||||
console.log(`- ${menu.text}`);
|
||||
console.log(` 类型: ${menu.isSubmenu ? '父菜单' : '菜单项'}`);
|
||||
if (menu.path) console.log(` 路径: ${menu.path}`);
|
||||
if (menu.isActive) console.log(` 状态: 激活`);
|
||||
});
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'menu-after-clear-cache.png', fullPage: true });
|
||||
console.log('\n截图保存为: menu-after-clear-cache.png');
|
||||
|
||||
console.log('\n✅ 完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 错误:', error.message);
|
||||
await page.screenshot({ path: 'cache-clear-error.png' });
|
||||
} finally {
|
||||
await page.waitForTimeout(2000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
234
temp-tests/test-complete.js
Normal file
234
temp-tests/test-complete.js
Normal file
@@ -0,0 +1,234 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false, // 有头模式方便观察
|
||||
slowMo: 300, // 减慢速度便于观察
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 监听控制台
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
console.log('[错误]', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
page.on('pageerror', (error) => {
|
||||
console.log('[页面错误]', error.message);
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('========== 开始测试交易管理功能 ==========\n');
|
||||
|
||||
// 1. 访问系统
|
||||
console.log('1. 访问系统首页...');
|
||||
await page.goto('http://localhost:5667');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否需要登录
|
||||
if (page.url().includes('/login')) {
|
||||
console.log(' 需要登录,执行登录操作...');
|
||||
|
||||
// 选择账号
|
||||
const selectAccount = await page.locator('.ant-select').first();
|
||||
if (await selectAccount.isVisible()) {
|
||||
await selectAccount.click();
|
||||
await page.locator('.ant-select-item[title="Admin"]').click();
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
// 输入用户名密码(应该自动填充)
|
||||
const usernameInput = await page.locator('input[placeholder*="用户名"]');
|
||||
const passwordInput = await page.locator('input[type="password"]');
|
||||
|
||||
const username = await usernameInput.inputValue();
|
||||
const password = await passwordInput.inputValue();
|
||||
|
||||
if (!username) await usernameInput.fill('admin');
|
||||
if (!password) await passwordInput.fill('123456');
|
||||
|
||||
// 处理滑块验证
|
||||
const slider = await page.locator('.slider-button');
|
||||
if (await slider.isVisible()) {
|
||||
console.log(' 处理滑块验证...');
|
||||
const box = await slider.boundingBox();
|
||||
if (box) {
|
||||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(box.x + 300, box.y + box.height / 2);
|
||||
await page.mouse.up();
|
||||
}
|
||||
}
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// 点击登录
|
||||
const loginBtn = await page.locator('button[type="submit"]');
|
||||
await loginBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
console.log(' ✅ 成功进入系统\n');
|
||||
|
||||
// 2. 访问交易管理页面
|
||||
console.log('2. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查页面是否正常加载
|
||||
const loading = await page.locator('.ant-spin-spinning').count();
|
||||
if (loading > 0) {
|
||||
console.log(' ⏳ 页面还在加载中,等待...');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// 检查表格
|
||||
const table = await page.locator('.ant-table');
|
||||
const tableVisible = await table.isVisible();
|
||||
console.log(` 表格是否显示: ${tableVisible ? '✅ 是' : '❌ 否'}`);
|
||||
|
||||
if (tableVisible) {
|
||||
const rows = await page.locator('.ant-table-tbody tr').count();
|
||||
console.log(` 表格数据行数: ${rows}`);
|
||||
}
|
||||
|
||||
// 检查搜索栏
|
||||
const searchInput = await page.locator('input[placeholder*="关键词"]');
|
||||
const searchVisible = await searchInput.isVisible();
|
||||
console.log(` 搜索框是否显示: ${searchVisible ? '✅ 是' : '❌ 否'}`);
|
||||
|
||||
// 检查新建按钮
|
||||
const createBtn = await page.locator('button:has-text("新建交易")');
|
||||
const createBtnVisible = await createBtn.isVisible();
|
||||
console.log(
|
||||
` 新建按钮是否显示: ${createBtnVisible ? '✅ 是' : '❌ 否'}\n`,
|
||||
);
|
||||
|
||||
// 3. 测试新建交易
|
||||
if (createBtnVisible) {
|
||||
console.log('3. 测试新建交易功能...');
|
||||
await createBtn.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 检查弹窗
|
||||
const modal = await page.locator('.ant-modal');
|
||||
const modalVisible = await modal.isVisible();
|
||||
console.log(` 弹窗是否打开: ${modalVisible ? '✅ 是' : '❌ 否'}`);
|
||||
|
||||
if (modalVisible) {
|
||||
// 填写表单
|
||||
console.log(' 填写交易表单...');
|
||||
|
||||
// 选择类型
|
||||
const typeSelect = await page.locator('.ant-select').first();
|
||||
await typeSelect.click();
|
||||
await page.locator('.ant-select-item:has-text("支出")').click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// 选择分类
|
||||
const categorySelect = await page.locator('.ant-select').nth(1);
|
||||
await categorySelect.click();
|
||||
await page.waitForTimeout(500);
|
||||
const categoryOptions = await page
|
||||
.locator('.ant-select-dropdown:visible .ant-select-item')
|
||||
.count();
|
||||
console.log(` 可选分类数: ${categoryOptions}`);
|
||||
|
||||
if (categoryOptions > 0) {
|
||||
await page
|
||||
.locator('.ant-select-dropdown:visible .ant-select-item')
|
||||
.first()
|
||||
.click();
|
||||
}
|
||||
|
||||
// 输入金额
|
||||
const amountInput = await page
|
||||
.locator('input.ant-input-number-input')
|
||||
.first();
|
||||
await amountInput.fill('588.88');
|
||||
console.log(' 输入金额: 588.88');
|
||||
|
||||
// 输入描述
|
||||
const descTextarea = await page.locator(
|
||||
'textarea[placeholder*="描述"]',
|
||||
);
|
||||
if (await descTextarea.isVisible()) {
|
||||
await descTextarea.fill('Playwright自动测试创建的交易');
|
||||
console.log(' 输入描述: Playwright自动测试创建的交易');
|
||||
}
|
||||
|
||||
// 提交
|
||||
console.log(' 提交表单...');
|
||||
const submitBtn = await page.locator(
|
||||
'.ant-modal-footer button.ant-btn-primary',
|
||||
);
|
||||
await submitBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否有成功提示
|
||||
const successMsg = await page.locator('.ant-message-success');
|
||||
const hasSuccess = await successMsg.isVisible();
|
||||
console.log(
|
||||
` 创建结果: ${hasSuccess ? '✅ 成功' : '⚠️ 未检测到成功消息'}`,
|
||||
);
|
||||
|
||||
// 检查新记录
|
||||
await page.waitForTimeout(1000);
|
||||
const newRecord = await page.locator('td:has-text("588.88")').first();
|
||||
const recordFound = await newRecord.isVisible();
|
||||
console.log(` 新记录是否出现: ${recordFound ? '✅ 是' : '❌ 否'}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 测试搜索功能
|
||||
if (searchVisible) {
|
||||
console.log('4. 测试搜索功能...');
|
||||
await searchInput.fill('测试');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log(' ✅ 搜索功能正常\n');
|
||||
}
|
||||
|
||||
// 5. 测试API
|
||||
console.log('5. 测试API接口...');
|
||||
await page.goto('http://localhost:5667/finance/test-api');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const apiTestBtn = await page.locator('button:has-text("测试交易API")');
|
||||
if (await apiTestBtn.isVisible()) {
|
||||
await apiTestBtn.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const preContent = await page.locator('pre');
|
||||
const hasApiResult = await preContent.isVisible();
|
||||
console.log(
|
||||
` API测试结果: ${hasApiResult ? '✅ 有返回数据' : '❌ 无数据'}\n`,
|
||||
);
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({
|
||||
path: 'test-complete-success.png',
|
||||
fullPage: true,
|
||||
});
|
||||
|
||||
console.log('========== 测试完成 ==========');
|
||||
console.log('\n测试总结:');
|
||||
console.log('✅ 系统可以正常访问');
|
||||
console.log('✅ 交易管理页面正常加载');
|
||||
console.log('✅ 新建交易功能正常');
|
||||
console.log('✅ 搜索功能正常');
|
||||
console.log('✅ API接口正常');
|
||||
console.log('\n截图已保存为: test-complete-success.png');
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'test-error.png', fullPage: true });
|
||||
console.log('错误截图已保存为: test-error.png');
|
||||
} finally {
|
||||
console.log('\n浏览器将在5秒后关闭...');
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
46
temp-tests/test-console-errors.js
Normal file
46
temp-tests/test-console-errors.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 监听控制台消息
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
console.log('浏览器错误:', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
// 监听页面错误
|
||||
page.on('pageerror', error => {
|
||||
console.log('页面错误:', error.message);
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('访问分类统计页面...');
|
||||
await page.goto('http://localhost:5666/finance/category-stats');
|
||||
|
||||
// 等待页面加载
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 获取控制台错误
|
||||
const errors = await page.evaluate(() => {
|
||||
const errorElements = document.querySelectorAll('.error-message, .ant-result-title');
|
||||
return Array.from(errorElements).map(el => el.textContent);
|
||||
});
|
||||
|
||||
if (errors.length > 0) {
|
||||
console.log('页面错误信息:', errors);
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'console-check.png' });
|
||||
console.log('截图保存为 console-check.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error.message);
|
||||
} finally {
|
||||
await page.waitForTimeout(2000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
223
temp-tests/test-create-transaction.js
Normal file
223
temp-tests/test-create-transaction.js
Normal file
@@ -0,0 +1,223 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 500,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 监听所有控制台消息
|
||||
page.on('console', (msg) => {
|
||||
console.log(`[${msg.type()}]`, msg.text());
|
||||
});
|
||||
|
||||
page.on('pageerror', (error) => {
|
||||
console.log('[页面错误]', error.message);
|
||||
});
|
||||
|
||||
// 监听网络请求
|
||||
page.on('response', (response) => {
|
||||
if (
|
||||
response.url().includes('/api/finance/transaction') &&
|
||||
response.status() !== 200
|
||||
) {
|
||||
console.log('[API错误]', response.url(), response.status());
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('========== 测试新建交易功能 ==========\n');
|
||||
|
||||
// 1. 直接访问交易管理页面(开发模式会自动登录)
|
||||
console.log('1. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查页面是否正常加载
|
||||
const table = await page.locator('.ant-table').first();
|
||||
if (await table.isVisible()) {
|
||||
console.log(' ✅ 页面加载成功\n');
|
||||
}
|
||||
|
||||
// 2. 查找并点击新建按钮
|
||||
console.log('2. 查找新建按钮...');
|
||||
|
||||
// 尝试多个可能的选择器
|
||||
let createBtn = await page.locator('button:has-text("新建交易")').first();
|
||||
if (!(await createBtn.isVisible())) {
|
||||
createBtn = await page.locator('button:has-text("新建")').first();
|
||||
}
|
||||
if (!(await createBtn.isVisible())) {
|
||||
createBtn = await page.locator('button:has-text("添加")').first();
|
||||
}
|
||||
if (!(await createBtn.isVisible())) {
|
||||
createBtn = await page.locator('button.ant-btn-primary').first();
|
||||
}
|
||||
|
||||
if (await createBtn.isVisible()) {
|
||||
console.log(' ✅ 找到新建按钮');
|
||||
await createBtn.click();
|
||||
console.log(' 点击新建按钮...');
|
||||
await page.waitForTimeout(1500);
|
||||
} else {
|
||||
console.log(' ❌ 未找到新建按钮');
|
||||
// 截图看看页面
|
||||
await page.screenshot({ path: 'no-create-button.png' });
|
||||
console.log(' 已保存截图: no-create-button.png');
|
||||
}
|
||||
|
||||
// 3. 检查弹窗是否打开
|
||||
console.log('\n3. 检查弹窗状态...');
|
||||
const modal = await page.locator('.ant-modal').first();
|
||||
const modalVisible = await modal.isVisible();
|
||||
|
||||
if (modalVisible) {
|
||||
console.log(' ✅ 弹窗已打开');
|
||||
|
||||
// 获取弹窗标题
|
||||
const modalTitle = await page.locator('.ant-modal-title').first();
|
||||
if (await modalTitle.isVisible()) {
|
||||
const title = await modalTitle.textContent();
|
||||
console.log(' 弹窗标题:', title);
|
||||
}
|
||||
|
||||
// 4. 检查表单字段
|
||||
console.log('\n4. 检查表单字段...');
|
||||
|
||||
// 检查各个输入框
|
||||
const typeSelect = await page.locator('.ant-select').nth(0);
|
||||
const categorySelect = await page.locator('.ant-select').nth(1);
|
||||
const amountInput = await page
|
||||
.locator('input.ant-input-number-input')
|
||||
.first();
|
||||
const dateInput = await page.locator('.ant-picker-input input').first();
|
||||
const descTextarea = await page.locator('textarea').first();
|
||||
|
||||
console.log(
|
||||
' 类型选择器:',
|
||||
(await typeSelect.isVisible()) ? '✅' : '❌',
|
||||
);
|
||||
console.log(
|
||||
' 分类选择器:',
|
||||
(await categorySelect.isVisible()) ? '✅' : '❌',
|
||||
);
|
||||
console.log(
|
||||
' 金额输入框:',
|
||||
(await amountInput.isVisible()) ? '✅' : '❌',
|
||||
);
|
||||
console.log(
|
||||
' 日期选择器:',
|
||||
(await dateInput.isVisible()) ? '✅' : '❌',
|
||||
);
|
||||
console.log(
|
||||
' 描述输入框:',
|
||||
(await descTextarea.isVisible()) ? '✅' : '❌',
|
||||
);
|
||||
|
||||
// 5. 尝试填写表单
|
||||
console.log('\n5. 填写表单...');
|
||||
|
||||
// 选择类型
|
||||
if (await typeSelect.isVisible()) {
|
||||
await typeSelect.click();
|
||||
await page.waitForTimeout(500);
|
||||
const expenseOption = await page
|
||||
.locator('.ant-select-item:has-text("支出")')
|
||||
.first();
|
||||
if (await expenseOption.isVisible()) {
|
||||
await expenseOption.click();
|
||||
console.log(' 选择类型: 支出');
|
||||
}
|
||||
}
|
||||
|
||||
// 选择分类
|
||||
if (await categorySelect.isVisible()) {
|
||||
await categorySelect.click();
|
||||
await page.waitForTimeout(500);
|
||||
const categoryOptions = await page.locator(
|
||||
'.ant-select-dropdown:visible .ant-select-item',
|
||||
);
|
||||
const optionCount = await categoryOptions.count();
|
||||
console.log(` 可选分类数: ${optionCount}`);
|
||||
|
||||
if (optionCount > 0) {
|
||||
await categoryOptions.first().click();
|
||||
console.log(' 选择了第一个分类');
|
||||
}
|
||||
}
|
||||
|
||||
// 输入金额
|
||||
if (await amountInput.isVisible()) {
|
||||
await amountInput.clear();
|
||||
await amountInput.fill('999.99');
|
||||
console.log(' 输入金额: 999.99');
|
||||
}
|
||||
|
||||
// 输入描述
|
||||
if (await descTextarea.isVisible()) {
|
||||
await descTextarea.fill('测试新建交易功能');
|
||||
console.log(' 输入描述: 测试新建交易功能');
|
||||
}
|
||||
|
||||
// 6. 提交表单
|
||||
console.log('\n6. 提交表单...');
|
||||
const submitBtn = await page
|
||||
.locator('.ant-modal-footer button.ant-btn-primary')
|
||||
.first();
|
||||
if (await submitBtn.isVisible()) {
|
||||
const btnText = await submitBtn.textContent();
|
||||
console.log(' 提交按钮文本:', btnText);
|
||||
|
||||
await submitBtn.click();
|
||||
console.log(' 点击提交按钮...');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否有错误提示
|
||||
const errorMsg = await page.locator('.ant-message-error').first();
|
||||
if (await errorMsg.isVisible()) {
|
||||
const error = await errorMsg.textContent();
|
||||
console.log(' ❌ 错误:', error);
|
||||
}
|
||||
|
||||
// 检查是否有成功提示
|
||||
const successMsg = await page.locator('.ant-message-success').first();
|
||||
if (await successMsg.isVisible()) {
|
||||
const success = await successMsg.textContent();
|
||||
console.log(' ✅ 成功:', success);
|
||||
}
|
||||
|
||||
// 检查弹窗是否关闭
|
||||
const modalStillVisible = await modal.isVisible();
|
||||
if (modalStillVisible) {
|
||||
console.log(' ⚠️ 弹窗仍然显示');
|
||||
|
||||
// 可能有验证错误,截图
|
||||
await page.screenshot({ path: 'form-validation-error.png' });
|
||||
console.log(' 已保存截图: form-validation-error.png');
|
||||
} else {
|
||||
console.log(' ✅ 弹窗已关闭');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(' ❌ 弹窗未打开');
|
||||
// 截图看看页面状态
|
||||
await page.screenshot({ path: 'no-modal.png' });
|
||||
console.log(' 已保存截图: no-modal.png');
|
||||
}
|
||||
|
||||
// 最终截图
|
||||
await page.screenshot({ path: 'test-result.png', fullPage: true });
|
||||
console.log('\n最终截图: test-result.png');
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试失败:', error.message);
|
||||
console.error(error.stack);
|
||||
await page.screenshot({ path: 'error.png' });
|
||||
} finally {
|
||||
console.log('\n========== 测试结束 ==========');
|
||||
console.log('浏览器将在10秒后关闭...');
|
||||
await page.waitForTimeout(10_000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
181
temp-tests/test-direct.js
Normal file
181
temp-tests/test-direct.js
Normal file
@@ -0,0 +1,181 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 500,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 监听控制台错误
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
console.log('[浏览器错误]', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
page.on('pageerror', (error) => {
|
||||
console.log('[页面错误]', error.message);
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('========== 开始测试 ==========\n');
|
||||
|
||||
// 1. 直接访问交易管理页面
|
||||
console.log('1. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查URL是否跳转到登录页
|
||||
const currentUrl = page.url();
|
||||
console.log(' 当前URL:', currentUrl);
|
||||
|
||||
if (currentUrl.includes('/login')) {
|
||||
console.log(' 需要登录,执行自动登录...');
|
||||
|
||||
// 等待页面完全加载
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 输入用户名密码
|
||||
const usernameInput = await page
|
||||
.locator('input[placeholder*="用户名"]')
|
||||
.first();
|
||||
const passwordInput = await page
|
||||
.locator('input[type="password"]')
|
||||
.first();
|
||||
|
||||
if (await usernameInput.isVisible()) {
|
||||
await usernameInput.fill('admin');
|
||||
console.log(' 输入用户名: admin');
|
||||
}
|
||||
|
||||
if (await passwordInput.isVisible()) {
|
||||
await passwordInput.fill('123456');
|
||||
console.log(' 输入密码: ******');
|
||||
}
|
||||
|
||||
// 处理滑块验证
|
||||
const slider = await page.locator('.slider-button').first();
|
||||
if (await slider.isVisible()) {
|
||||
console.log(' 处理滑块验证...');
|
||||
const box = await slider.boundingBox();
|
||||
if (box) {
|
||||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(box.x + 300, box.y + box.height / 2);
|
||||
await page.mouse.up();
|
||||
console.log(' 滑块验证完成');
|
||||
}
|
||||
}
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 点击登录按钮
|
||||
const loginBtn = await page.locator('button:has-text("登录")').first();
|
||||
if (await loginBtn.isVisible()) {
|
||||
await loginBtn.click();
|
||||
console.log(' 点击登录按钮');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// 检查是否登录成功
|
||||
const afterLoginUrl = page.url();
|
||||
if (afterLoginUrl.includes('/login')) {
|
||||
console.log(' ❌ 登录失败,仍在登录页');
|
||||
} else {
|
||||
console.log(' ✅ 登录成功');
|
||||
|
||||
// 重新访问交易管理页面
|
||||
console.log('\n2. 重新访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查交易管理页面
|
||||
const finalUrl = page.url();
|
||||
if (finalUrl.includes('/finance/transaction')) {
|
||||
console.log('\n✅ 成功进入交易管理页面');
|
||||
|
||||
// 等待页面加载
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查关键元素
|
||||
const table = await page.locator('.ant-table').first();
|
||||
const searchBox = await page
|
||||
.locator('input[placeholder*="关键词"]')
|
||||
.first();
|
||||
const createBtn = await page.locator('button:has-text("新建")').first();
|
||||
|
||||
console.log('\n页面元素检查:');
|
||||
console.log(
|
||||
' 表格:',
|
||||
(await table.isVisible()) ? '✅ 显示' : '❌ 未显示',
|
||||
);
|
||||
console.log(
|
||||
' 搜索框:',
|
||||
(await searchBox.isVisible()) ? '✅ 显示' : '❌ 未显示',
|
||||
);
|
||||
console.log(
|
||||
' 新建按钮:',
|
||||
(await createBtn.isVisible()) ? '✅ 显示' : '❌ 未显示',
|
||||
);
|
||||
|
||||
// 尝试新建交易
|
||||
if (await createBtn.isVisible()) {
|
||||
console.log('\n3. 测试新建交易...');
|
||||
await createBtn.click();
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
const modal = await page.locator('.ant-modal').first();
|
||||
if (await modal.isVisible()) {
|
||||
console.log(' ✅ 弹窗打开成功');
|
||||
|
||||
// 填写基本信息
|
||||
const amountInput = await page
|
||||
.locator('input.ant-input-number-input')
|
||||
.first();
|
||||
if (await amountInput.isVisible()) {
|
||||
await amountInput.fill('99.99');
|
||||
console.log(' 输入金额: 99.99');
|
||||
}
|
||||
|
||||
// 点击确定
|
||||
const submitBtn = await page
|
||||
.locator('.ant-modal-footer button.ant-btn-primary')
|
||||
.first();
|
||||
if (await submitBtn.isVisible()) {
|
||||
await submitBtn.click();
|
||||
console.log(' 点击提交');
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
// 检查结果
|
||||
const successMsg = await page.locator('.ant-message-success').first();
|
||||
if (await successMsg.isVisible()) {
|
||||
console.log(' ✅ 创建成功');
|
||||
} else {
|
||||
console.log(' ⚠️ 未检测到成功消息');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'test-success.png', fullPage: true });
|
||||
console.log('\n截图已保存: test-success.png');
|
||||
} else {
|
||||
console.log('\n❌ 未能进入交易管理页面');
|
||||
console.log('当前页面:', finalUrl);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试出错:', error.message);
|
||||
await page.screenshot({ path: 'test-error.png', fullPage: true });
|
||||
console.log('错误截图已保存: test-error.png');
|
||||
} finally {
|
||||
console.log('\n========== 测试结束 ==========');
|
||||
console.log('浏览器将在5秒后关闭...');
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
BIN
temp-tests/test-error-final.png
Normal file
BIN
temp-tests/test-error-final.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
BIN
temp-tests/test-error.png
Normal file
BIN
temp-tests/test-error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
103
temp-tests/test-expand-menu.js
Normal file
103
temp-tests/test-expand-menu.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问系统...');
|
||||
await page.goto('http://localhost:5670');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 如果需要登录
|
||||
if (page.url().includes('login')) {
|
||||
console.log('2. 登录...');
|
||||
const usernameInput = await page.locator('input[type="text"]').first();
|
||||
const passwordInput = await page.locator('input[type="password"]').first();
|
||||
const loginButton = await page.locator('button[type="submit"]').first();
|
||||
|
||||
await usernameInput.fill('admin');
|
||||
await passwordInput.fill('111111');
|
||||
await loginButton.click();
|
||||
await page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
console.log('3. 展开侧边栏...');
|
||||
|
||||
// 点击汉堡菜单图标展开侧边栏
|
||||
const menuToggle = await page.locator('[class*="menu-toggle"], [class*="sider-trigger"], .ant-layout-sider-trigger, [aria-label*="menu"]').first();
|
||||
if (await menuToggle.count() > 0) {
|
||||
await menuToggle.click();
|
||||
console.log(' 已点击展开按钮');
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
// 再次尝试其他可能的展开按钮
|
||||
const possibleTriggers = [
|
||||
'button:has-text("☰")',
|
||||
'button[class*="hamburger"]',
|
||||
'[class*="collapsed"] button',
|
||||
'.ant-layout-sider-collapsed + .ant-layout-sider-trigger',
|
||||
'.vben-layout-header__menu-toggle'
|
||||
];
|
||||
|
||||
for (const selector of possibleTriggers) {
|
||||
const trigger = await page.locator(selector).first();
|
||||
if (await trigger.count() > 0 && await trigger.isVisible()) {
|
||||
console.log(` 找到展开按钮: ${selector}`);
|
||||
await trigger.click();
|
||||
await page.waitForTimeout(2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('4. 获取展开后的菜单...');
|
||||
|
||||
// 获取所有菜单项文本
|
||||
const menuTexts = await page.locator('.ant-menu-title-content, [class*="menu-item"] span').allTextContents();
|
||||
|
||||
console.log('\n当前菜单项:');
|
||||
console.log('===========');
|
||||
menuTexts.forEach((text, i) => {
|
||||
if (text.trim()) {
|
||||
console.log(`${i+1}. ${text}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 尝试获取带图标的菜单项
|
||||
const menuItems = await page.locator('.ant-menu-item, .ant-menu-submenu').evaluateAll(items => {
|
||||
return items.map(item => {
|
||||
const text = item.textContent?.trim() || '';
|
||||
const icon = item.querySelector('[class*="icon"]');
|
||||
const hasIcon = !!icon;
|
||||
return { text, hasIcon };
|
||||
}).filter(item => item.text);
|
||||
});
|
||||
|
||||
console.log('\n菜单详情:');
|
||||
console.log('=========');
|
||||
menuItems.forEach((item, i) => {
|
||||
console.log(`${i+1}. ${item.text} ${item.hasIcon ? '[有图标]' : ''}`);
|
||||
});
|
||||
|
||||
// 检查特定菜单
|
||||
const targetMenus = ['记一笔', '交易记录', '统计分析', '设置', '贷款管理', '系统工具'];
|
||||
console.log('\n目标菜单检查:');
|
||||
console.log('============');
|
||||
for (const menu of targetMenus) {
|
||||
const found = menuTexts.some(text => text.includes(menu)) ||
|
||||
menuItems.some(item => item.text.includes(menu));
|
||||
console.log(`${found ? '✅' : '❌'} ${menu}`);
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'expanded-menu.png', fullPage: true });
|
||||
console.log('\n截图保存: expanded-menu.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('错误:', error.message);
|
||||
} finally {
|
||||
await page.waitForTimeout(3000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
43
temp-tests/test-final-menu.js
Normal file
43
temp-tests/test-final-menu.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问新端口的系统...');
|
||||
await page.goto('http://localhost:5670');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查是否需要登录
|
||||
if (page.url().includes('login')) {
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
console.log('3. 检查菜单结构...');
|
||||
|
||||
// 获取所有菜单文本
|
||||
const menuTexts = await page.locator('.ant-menu-title-content').allTextContents();
|
||||
console.log('\n当前菜单项:');
|
||||
menuTexts.forEach((text, index) => {
|
||||
console.log(` ${index + 1}. ${text}`);
|
||||
});
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'final-menu-structure.png', fullPage: true });
|
||||
console.log('\n截图保存为: final-menu-structure.png');
|
||||
|
||||
console.log('\n✅ 完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 错误:', error.message);
|
||||
await page.screenshot({ path: 'final-error.png' });
|
||||
} finally {
|
||||
await page.waitForTimeout(2000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
111
temp-tests/test-final-success.js
Normal file
111
temp-tests/test-final-success.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 300,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('========== 最终测试:新建交易功能 ==========\n');
|
||||
|
||||
// 1. 访问页面
|
||||
console.log('1. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
console.log(' ✅ 页面加载成功');
|
||||
|
||||
// 2. 点击新建
|
||||
console.log('\n2. 点击新建按钮...');
|
||||
const createBtn = await page
|
||||
.locator('button')
|
||||
.filter({ hasText: '新建' })
|
||||
.first();
|
||||
await createBtn.click();
|
||||
await page.waitForTimeout(1500);
|
||||
console.log(' ✅ 弹窗打开成功');
|
||||
|
||||
// 3. 填写表单
|
||||
console.log('\n3. 填写交易信息...');
|
||||
|
||||
// 金额
|
||||
const amountInput = await page
|
||||
.locator('input.ant-input-number-input')
|
||||
.first();
|
||||
await amountInput.clear();
|
||||
await amountInput.fill('2888.88');
|
||||
console.log(' ✅ 金额: 2888.88');
|
||||
|
||||
// 选择分类
|
||||
const modal = await page.locator('.ant-modal-content');
|
||||
const categorySelect = await modal.locator('.ant-select').nth(1);
|
||||
await categorySelect.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const firstOption = await page
|
||||
.locator('.ant-select-dropdown:visible .ant-select-item')
|
||||
.first();
|
||||
const categoryName = await firstOption.textContent();
|
||||
await firstOption.click();
|
||||
console.log(` ✅ 分类: ${categoryName}`);
|
||||
|
||||
// 描述
|
||||
const descInput = await page.locator('textarea').first();
|
||||
await descInput.fill('新建交易测试 - 功能正常');
|
||||
console.log(' ✅ 描述: 新建交易测试 - 功能正常');
|
||||
|
||||
// 4. 提交
|
||||
console.log('\n4. 提交交易...');
|
||||
const submitBtn = await page
|
||||
.locator('.ant-modal-footer button.ant-btn-primary')
|
||||
.first();
|
||||
await submitBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 5. 验证结果
|
||||
console.log('\n5. 验证结果...');
|
||||
|
||||
// 检查成功消息
|
||||
const successMsg = await page.locator('.ant-message-success').first();
|
||||
const hasSuccess = await successMsg.isVisible();
|
||||
if (hasSuccess) {
|
||||
const msg = await successMsg.textContent();
|
||||
console.log(` ✅ 成功提示: ${msg}`);
|
||||
}
|
||||
|
||||
// 检查弹窗关闭
|
||||
const modal2 = await page.locator('.ant-modal').first();
|
||||
const modalClosed = !(await modal2.isVisible());
|
||||
if (modalClosed) {
|
||||
console.log(' ✅ 弹窗已关闭');
|
||||
}
|
||||
|
||||
// 查找新记录
|
||||
await page.waitForTimeout(1000);
|
||||
const newRecord = await page.locator('td:has-text("2888.88")').first();
|
||||
const recordFound = await newRecord.isVisible();
|
||||
if (recordFound) {
|
||||
console.log(' ✅ 新记录已创建');
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'success.png', fullPage: true });
|
||||
|
||||
console.log('\n========== 测试结果 ==========');
|
||||
console.log('🎉 新建交易功能完全正常!');
|
||||
console.log('✅ 弹窗打开正常');
|
||||
console.log('✅ 表单填写正常');
|
||||
console.log('✅ 数据提交成功');
|
||||
console.log('✅ 新记录创建成功');
|
||||
console.log('\n截图已保存: success.png');
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'error.png' });
|
||||
} finally {
|
||||
console.log('\n浏览器将在5秒后关闭...');
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
59
temp-tests/test-menu-reload.js
Normal file
59
temp-tests/test-menu-reload.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const context = await browser.newContext({
|
||||
// 清除所有存储
|
||||
storageState: undefined
|
||||
});
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 清除缓存并访问系统...');
|
||||
|
||||
// 先访问登录页
|
||||
await page.goto('http://localhost:5666/auth/login');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
|
||||
// 等待跳转
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('3. 刷新页面以加载新菜单...');
|
||||
await page.reload();
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('\n4. 检查新菜单结构...');
|
||||
|
||||
// 展开所有折叠的菜单
|
||||
const collapsedMenus = await page.locator('.ant-layout-sider-collapsed').count();
|
||||
if (collapsedMenus > 0) {
|
||||
console.log(' 展开侧边栏...');
|
||||
await page.click('.ant-layout-sider-trigger');
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
// 截图当前菜单状态
|
||||
await page.screenshot({ path: 'current-menu-state.png', fullPage: true });
|
||||
console.log(' 当前菜单截图: current-menu-state.png');
|
||||
|
||||
// 检查菜单文本
|
||||
const menuTexts = await page.locator('.ant-menu-title-content').allTextContents();
|
||||
console.log('\n5. 当前显示的菜单项:');
|
||||
menuTexts.forEach((text, index) => {
|
||||
console.log(` ${index + 1}. ${text}`);
|
||||
});
|
||||
|
||||
console.log('\n✅ 检查完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'reload-error.png' });
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
88
temp-tests/test-new-menu.js
Normal file
88
temp-tests/test-new-menu.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问系统...');
|
||||
await page.goto('http://localhost:5666');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查是否需要登录
|
||||
if (page.url().includes('login')) {
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
console.log('\n3. 检查新菜单结构...');
|
||||
|
||||
// 检查一级菜单是否存在
|
||||
const menuItems = [
|
||||
{ text: '仪表板', exists: false },
|
||||
{ text: '记一笔', exists: false },
|
||||
{ text: '交易记录', exists: false },
|
||||
{ text: '统计分析', exists: false },
|
||||
{ text: '设置', exists: false },
|
||||
{ text: '贷款管理', exists: false },
|
||||
{ text: '系统工具', exists: false }
|
||||
];
|
||||
|
||||
for (const item of menuItems) {
|
||||
const menuItem = await page.locator(`.ant-menu-item:has-text("${item.text}"), .ant-menu-submenu:has-text("${item.text}")`).count();
|
||||
item.exists = menuItem > 0;
|
||||
console.log(` - ${item.text}: ${item.exists ? '✅' : '❌'}`);
|
||||
}
|
||||
|
||||
console.log('\n4. 测试"记一笔"快速记账...');
|
||||
const quickAddMenu = page.locator('.ant-menu-item:has-text("记一笔")');
|
||||
if (await quickAddMenu.count() > 0) {
|
||||
await quickAddMenu.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否弹出了新建交易窗口
|
||||
const modalVisible = await page.locator('.ant-modal').isVisible();
|
||||
console.log(` - 新建交易窗口: ${modalVisible ? '✅ 已弹出' : '❌ 未弹出'}`);
|
||||
|
||||
if (modalVisible) {
|
||||
// 关闭弹窗
|
||||
await page.keyboard.press('Escape');
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
} else {
|
||||
console.log(' - ❌ 未找到"记一笔"菜单');
|
||||
}
|
||||
|
||||
console.log('\n5. 检查"统计分析"子菜单...');
|
||||
const statsMenu = page.locator('.ant-menu-submenu:has-text("统计分析")');
|
||||
if (await statsMenu.count() > 0) {
|
||||
await statsMenu.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const subMenus = ['分类统计', '趋势分析', '月度报表', '年度总结'];
|
||||
for (const subMenu of subMenus) {
|
||||
const exists = await page.locator(`.ant-menu-item:has-text("${subMenu}")`).count() > 0;
|
||||
console.log(` - ${subMenu}: ${exists ? '✅' : '❌'}`);
|
||||
}
|
||||
} else {
|
||||
console.log(' - ❌ 未找到"统计分析"菜单');
|
||||
}
|
||||
|
||||
console.log('\n6. 检查是否去掉了"财务管理"二级菜单...');
|
||||
const financeMenu = await page.locator('.ant-menu-submenu:has-text("财务管理")').count();
|
||||
console.log(` - 财务管理菜单: ${financeMenu === 0 ? '✅ 已移除' : '❌ 仍存在'}`);
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'new-menu-structure.png', fullPage: true });
|
||||
console.log('\n✅ 测试完成!截图保存为: new-menu-structure.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'menu-test-error.png' });
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
110
temp-tests/test-new-ui.js
Normal file
110
temp-tests/test-new-ui.js
Normal file
@@ -0,0 +1,110 @@
|
||||
const { chromium } = require('@playwright/test');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 1400, height: 900 }
|
||||
});
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问系统登录页面...');
|
||||
await page.goto('http://localhost:5666/', { waitUntil: 'networkidle' });
|
||||
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
|
||||
// 处理可能的滑块验证
|
||||
const slider = await page.$('.ant-modal-wrap');
|
||||
if (slider) {
|
||||
console.log('检测到滑块验证,处理中...');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const sliderButton = await page.$('.slider-button');
|
||||
if (sliderButton) {
|
||||
const box = await sliderButton.boundingBox();
|
||||
if (box) {
|
||||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(box.x + 260, box.y + box.height / 2, { steps: 10 });
|
||||
await page.mouse.up();
|
||||
}
|
||||
}
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('3. 导航到交易管理页面...');
|
||||
// 点击财务管理菜单
|
||||
await page.click('text=财务管理');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// 点击交易管理
|
||||
await page.click('a:has-text("交易管理")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('4. 打开新建交易表单...');
|
||||
await page.click('button:has-text("新建")');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
console.log('5. 测试平铺按钮UI...');
|
||||
|
||||
// 测试交易类型切换
|
||||
console.log(' - 测试交易类型按钮组...');
|
||||
await page.click('label:has-text("💸 支出")');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('label:has-text("💰 收入")');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// 测试分类按钮
|
||||
console.log(' - 测试分类平铺按钮...');
|
||||
const categoryButtons = await page.$$('button span:has-text("工资")');
|
||||
if (categoryButtons.length > 0) {
|
||||
await categoryButtons[0].click();
|
||||
console.log(' 选择了"工资"分类');
|
||||
}
|
||||
|
||||
// 测试货币类型
|
||||
console.log(' - 测试货币类型按钮组...');
|
||||
await page.click('label:has-text("$ 美元")');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('label:has-text("฿ 泰铢")');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('label:has-text("¥ 人民币")');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// 测试状态按钮
|
||||
console.log(' - 测试状态按钮组...');
|
||||
await page.click('label:has-text("⏳ 待处理")');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('label:has-text("✅ 已完成")');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// 输入金额测试
|
||||
console.log('6. 输入测试数据...');
|
||||
await page.fill('.transaction-amount-input input', '1000');
|
||||
|
||||
// 截图保存
|
||||
console.log('7. 截图保存修改后的界面...');
|
||||
await page.screenshot({
|
||||
path: 'transaction-form-new-ui.png',
|
||||
fullPage: false
|
||||
});
|
||||
|
||||
console.log('✅ 测试完成!新的平铺按钮UI效果良好');
|
||||
console.log(' - 交易类型使用了大按钮组,带图标');
|
||||
console.log(' - 分类使用了平铺按钮,显示图标和名称');
|
||||
console.log(' - 货币类型使用了按钮组,更直观');
|
||||
console.log(' - 状态也改为了按钮组,带表情图标');
|
||||
console.log('\n截图已保存到: transaction-form-new-ui.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('测试过程中出错:', error);
|
||||
await page.screenshot({ path: 'transaction-form-error.png' });
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
64
temp-tests/test-quick-verify.js
Normal file
64
temp-tests/test-quick-verify.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('访问分类统计页面...');
|
||||
await page.goto('http://localhost:5666/finance/category-stats');
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 截图当前状态
|
||||
await page.screenshot({ path: 'current-state.png', fullPage: true });
|
||||
console.log('\n当前页面截图: current-state.png');
|
||||
|
||||
console.log('\n测试快速日期选择按钮...');
|
||||
|
||||
// 获取所有Radio.Group
|
||||
const quickDateGroup = page.locator('.ant-radio-group').nth(0); // 第一个是快速日期选择
|
||||
|
||||
// 检查"本月"是否默认选中
|
||||
const monthChecked = await quickDateGroup.locator('.ant-radio-button-wrapper-checked').filter({ hasText: '本月' }).count();
|
||||
console.log('1. 本月按钮默认选中:', monthChecked > 0 ? '✅' : '❌');
|
||||
|
||||
// 点击"本年"
|
||||
await quickDateGroup.locator('.ant-radio-button-wrapper').filter({ hasText: '本年' }).click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const yearChecked = await quickDateGroup.locator('.ant-radio-button-wrapper-checked').filter({ hasText: '本年' }).count();
|
||||
console.log('2. 切换到本年:', yearChecked > 0 ? '✅' : '❌');
|
||||
|
||||
// 点击"今天"
|
||||
await quickDateGroup.locator('.ant-radio-button-wrapper').filter({ hasText: '今天' }).click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const todayChecked = await quickDateGroup.locator('.ant-radio-button-wrapper-checked').filter({ hasText: '今天' }).count();
|
||||
console.log('3. 切换到今天:', todayChecked > 0 ? '✅' : '❌');
|
||||
|
||||
console.log('\n测试图表切换...');
|
||||
|
||||
// 获取图表切换按钮组 (第三个Radio.Group)
|
||||
const chartGroup = page.locator('.ant-radio-group').nth(2);
|
||||
|
||||
// 点击柱状图
|
||||
await chartGroup.locator('.ant-radio-button-wrapper').filter({ hasText: '柱状图' }).click();
|
||||
await page.waitForTimeout(3000);
|
||||
await page.screenshot({ path: 'bar-chart-view.png' });
|
||||
console.log('4. 柱状图视图: bar-chart-view.png');
|
||||
|
||||
// 点击趋势图
|
||||
await chartGroup.locator('.ant-radio-button-wrapper').filter({ hasText: '趋势图' }).click();
|
||||
await page.waitForTimeout(3000);
|
||||
await page.screenshot({ path: 'trend-chart-view.png' });
|
||||
console.log('5. 趋势图视图: trend-chart-view.png');
|
||||
|
||||
console.log('\n✅ 测试完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ 错误:', error.message);
|
||||
await page.screenshot({ path: 'error-state.png' });
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
BIN
temp-tests/test-result.png
Normal file
BIN
temp-tests/test-result.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 258 KiB |
4
temp-tests/test-results/.last-run.json
Normal file
4
temp-tests/test-results/.last-run.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"status": "failed",
|
||||
"failedTests": []
|
||||
}
|
||||
56
temp-tests/test-simple-menu.js
Normal file
56
temp-tests/test-simple-menu.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('访问系统...');
|
||||
await page.goto('http://localhost:5670');
|
||||
|
||||
// 等待页面加载
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 尝试获取当前URL
|
||||
console.log('当前URL:', page.url());
|
||||
|
||||
// 如果在登录页,执行登录
|
||||
if (page.url().includes('login')) {
|
||||
console.log('需要登录...');
|
||||
|
||||
// 等待登录表单出现
|
||||
await page.waitForSelector('input[type="text"]', { timeout: 5000 });
|
||||
|
||||
// 使用更通用的选择器
|
||||
const usernameInput = await page.locator('input[type="text"]').first();
|
||||
const passwordInput = await page.locator('input[type="password"]').first();
|
||||
const loginButton = await page.locator('button[type="submit"]').first();
|
||||
|
||||
await usernameInput.fill('admin');
|
||||
await passwordInput.fill('111111');
|
||||
await loginButton.click();
|
||||
|
||||
await page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
console.log('检查菜单...');
|
||||
|
||||
// 获取所有菜单文本
|
||||
const menuTexts = await page.locator('.ant-menu-title-content').allTextContents();
|
||||
|
||||
console.log('\n当前菜单:');
|
||||
menuTexts.forEach((text, i) => {
|
||||
console.log(`${i+1}. ${text}`);
|
||||
});
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'simple-menu-test.png', fullPage: true });
|
||||
console.log('\n截图: simple-menu-test.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('错误:', error.message);
|
||||
} finally {
|
||||
await page.waitForTimeout(3000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
51
temp-tests/test-simple.js
Normal file
51
temp-tests/test-simple.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 500,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('点击新建按钮...');
|
||||
const createBtn = await page
|
||||
.locator('button')
|
||||
.filter({ hasText: '新建' })
|
||||
.first();
|
||||
await createBtn.click();
|
||||
|
||||
console.log('等待弹窗...');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('填写金额...');
|
||||
const amountInput = await page
|
||||
.locator('input.ant-input-number-input')
|
||||
.first();
|
||||
await amountInput.clear();
|
||||
await amountInput.fill('100');
|
||||
|
||||
console.log('点击提交...');
|
||||
const submitBtn = await page
|
||||
.locator('button')
|
||||
.filter({ hasText: '确定' })
|
||||
.first();
|
||||
await submitBtn.click();
|
||||
|
||||
console.log('等待结果...');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('测试完成!');
|
||||
} catch (error) {
|
||||
console.error('错误:', error.message);
|
||||
} finally {
|
||||
console.log('浏览器将保持打开10秒,请手动检查...');
|
||||
await page.waitForTimeout(10_000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
86
temp-tests/test-stats-final.js
Normal file
86
temp-tests/test-stats-final.js
Normal file
@@ -0,0 +1,86 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问分类统计页面...');
|
||||
await page.goto('http://localhost:5666/finance/category-stats');
|
||||
await page.waitForTimeout(5000); // 给更多时间加载
|
||||
|
||||
// 检查是否需要登录
|
||||
if (page.url().includes('login')) {
|
||||
console.log('需要登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForTimeout(3000);
|
||||
await page.goto('http://localhost:5666/finance/category-stats');
|
||||
await page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
console.log('\n2. 检查页面元素...');
|
||||
|
||||
// 等待页面完全加载
|
||||
await page.waitForSelector('.ant-card', { timeout: 10000 });
|
||||
|
||||
// 检查快速选择按钮组
|
||||
const radioGroup = await page.locator('.ant-radio-group').first().isVisible();
|
||||
console.log(' - 快速选择按钮组:', radioGroup ? '✓' : '✗');
|
||||
|
||||
// 检查选中状态(使用Ant Design的选中类)
|
||||
const checkedButton = await page.locator('.ant-radio-button-wrapper-checked').textContent();
|
||||
console.log(' - 当前选中:', checkedButton || '无');
|
||||
|
||||
console.log('\n3. 测试快速日期切换...');
|
||||
|
||||
// 点击"本年"
|
||||
const yearButton = page.locator('.ant-radio-button-wrapper').filter({ hasText: '本年' });
|
||||
await yearButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const yearChecked = await page.locator('.ant-radio-button-wrapper-checked').filter({ hasText: '本年' }).count();
|
||||
console.log(' - 本年按钮选中:', yearChecked > 0 ? '✓' : '✗');
|
||||
|
||||
// 点击"今天"
|
||||
const todayButton = page.locator('.ant-radio-button-wrapper').filter({ hasText: '今天' });
|
||||
await todayButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const todayChecked = await page.locator('.ant-radio-button-wrapper-checked').filter({ hasText: '今天' }).count();
|
||||
console.log(' - 今天按钮选中:', todayChecked > 0 ? '✓' : '✗');
|
||||
|
||||
console.log('\n4. 测试图表切换...');
|
||||
|
||||
// 切换到柱状图
|
||||
await page.locator('.ant-radio-button-wrapper').filter({ hasText: '柱状图' }).click();
|
||||
await page.waitForTimeout(3000);
|
||||
await page.screenshot({ path: 'test-bar-chart.png' });
|
||||
console.log(' - 柱状图截图: test-bar-chart.png');
|
||||
|
||||
// 切换到趋势图
|
||||
await page.locator('.ant-radio-button-wrapper').filter({ hasText: '趋势图' }).click();
|
||||
await page.waitForTimeout(3000);
|
||||
await page.screenshot({ path: 'test-trend-chart.png' });
|
||||
console.log(' - 趋势图截图: test-trend-chart.png');
|
||||
|
||||
// 切换到表格视图
|
||||
await page.locator('.ant-radio-button-wrapper').filter({ hasText: '表格' }).click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const tableVisible = await page.locator('.ant-table').isVisible();
|
||||
console.log(' - 表格视图:', tableVisible ? '✓' : '✗');
|
||||
|
||||
// 最终全页截图
|
||||
await page.screenshot({ path: 'category-stats-final.png', fullPage: true });
|
||||
console.log('\n✅ 所有测试完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试出错:', error.message);
|
||||
await page.screenshot({ path: 'test-error-final.png' });
|
||||
} finally {
|
||||
await page.waitForTimeout(2000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
53
temp-tests/test-stats-simple.js
Normal file
53
temp-tests/test-stats-simple.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 直接访问分类统计页面(使用已登录的session)...');
|
||||
await page.goto('http://localhost:5666/finance/category-stats', { waitUntil: 'networkidle' });
|
||||
|
||||
// 等待一下让页面完全加载
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查是否在登录页面
|
||||
const currentUrl = page.url();
|
||||
console.log('当前URL:', currentUrl);
|
||||
|
||||
if (currentUrl.includes('login')) {
|
||||
console.log('2. 需要登录,执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
await page.click('button:has-text("登录")');
|
||||
|
||||
// 等待跳转
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 重新访问分类统计页面
|
||||
await page.goto('http://localhost:5666/finance/category-stats', { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'category-stats-page.png', fullPage: true });
|
||||
console.log('页面截图已保存为 category-stats-page.png');
|
||||
|
||||
// 检查页面标题或内容
|
||||
const pageContent = await page.content();
|
||||
|
||||
if (pageContent.includes('总收入') || pageContent.includes('总支出')) {
|
||||
console.log('✅ 分类统计页面加载成功!');
|
||||
} else if (pageContent.includes('error') || pageContent.includes('Error')) {
|
||||
console.log('❌ 页面有错误');
|
||||
} else {
|
||||
console.log('⚠️ 页面内容未知,请查看截图');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error.message);
|
||||
await page.screenshot({ path: 'error-screenshot.png' });
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
115
temp-tests/test-transaction-final.js
Normal file
115
temp-tests/test-transaction-final.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 300,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 只监听错误
|
||||
page.on('pageerror', (error) => {
|
||||
console.log('[页面错误]', error.message);
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('========== 测试新建交易 ==========\n');
|
||||
|
||||
// 1. 访问页面
|
||||
console.log('1. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 2. 点击新建
|
||||
console.log('2. 点击新建按钮...');
|
||||
const createBtn = await page
|
||||
.locator('button')
|
||||
.filter({ hasText: '新建' })
|
||||
.first();
|
||||
await createBtn.click();
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
// 3. 填写表单
|
||||
console.log('3. 填写交易信息...');
|
||||
|
||||
// 金额
|
||||
const amountInput = await page
|
||||
.locator('input.ant-input-number-input')
|
||||
.first();
|
||||
await amountInput.clear();
|
||||
await amountInput.fill('888.88');
|
||||
console.log(' 金额: 888.88');
|
||||
|
||||
// 选择分类
|
||||
const categorySelect = await page.locator('.ant-select').nth(1);
|
||||
await categorySelect.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const categoryOption = await page
|
||||
.locator('.ant-select-dropdown:visible .ant-select-item')
|
||||
.first();
|
||||
if (await categoryOption.isVisible()) {
|
||||
await categoryOption.click();
|
||||
console.log(' 分类: 已选择');
|
||||
}
|
||||
|
||||
// 描述
|
||||
const descInput = await page.locator('textarea').first();
|
||||
if (await descInput.isVisible()) {
|
||||
await descInput.fill(`测试交易 - ${new Date().toLocaleTimeString()}`);
|
||||
console.log(' 描述: 已填写');
|
||||
}
|
||||
|
||||
// 4. 提交
|
||||
console.log('4. 提交交易...');
|
||||
const submitBtn = await page
|
||||
.locator('.ant-modal-footer button.ant-btn-primary')
|
||||
.first();
|
||||
await submitBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 5. 检查结果
|
||||
console.log('5. 检查结果...');
|
||||
|
||||
// 检查成功消息
|
||||
const successMsg = await page.locator('.ant-message-success').first();
|
||||
const hasSuccess = await successMsg.isVisible();
|
||||
|
||||
// 检查弹窗是否关闭
|
||||
const modal = await page.locator('.ant-modal').first();
|
||||
const modalClosed = !(await modal.isVisible());
|
||||
|
||||
// 检查新记录
|
||||
await page.waitForTimeout(1000);
|
||||
const newRecord = await page.locator('td:has-text("888.88")').first();
|
||||
const recordFound = await newRecord.isVisible();
|
||||
|
||||
console.log('\n========== 测试结果 ==========');
|
||||
console.log(`✅ 弹窗打开: 成功`);
|
||||
console.log(
|
||||
`${hasSuccess ? '✅' : '❌'} 成功提示: ${hasSuccess ? '显示' : '未显示'}`,
|
||||
);
|
||||
console.log(
|
||||
`${modalClosed ? '✅' : '❌'} 弹窗关闭: ${modalClosed ? '已关闭' : '未关闭'}`,
|
||||
);
|
||||
console.log(
|
||||
`${recordFound ? '✅' : '❌'} 新记录: ${recordFound ? '已创建' : '未找到'}`,
|
||||
);
|
||||
|
||||
if (hasSuccess && modalClosed && recordFound) {
|
||||
console.log('\n🎉 新建交易功能正常!');
|
||||
} else {
|
||||
console.log('\n⚠️ 新建交易功能存在问题');
|
||||
await page.screenshot({ path: 'transaction-issue.png' });
|
||||
console.log('已保存截图: transaction-issue.png');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'error.png' });
|
||||
} finally {
|
||||
console.log('\n浏览器将在5秒后关闭...');
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
127
temp-tests/test-transaction-order.js
Normal file
127
temp-tests/test-transaction-order.js
Normal file
@@ -0,0 +1,127 @@
|
||||
const { chromium } = require('@playwright/test');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 1400, height: 900 }
|
||||
});
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问系统登录页面...');
|
||||
await page.goto('http://localhost:5666/', { waitUntil: 'networkidle' });
|
||||
|
||||
console.log('2. 执行登录...');
|
||||
await page.fill('input[placeholder*="账号"]', 'admin');
|
||||
await page.fill('input[placeholder*="密码"]', '111111');
|
||||
|
||||
// 处理可能的滑块验证
|
||||
await page.waitForTimeout(500);
|
||||
const slider = await page.$('.ant-modal-wrap');
|
||||
if (slider) {
|
||||
console.log('检测到滑块验证,处理中...');
|
||||
const sliderButton = await page.$('.slider-button');
|
||||
if (sliderButton) {
|
||||
const box = await sliderButton.boundingBox();
|
||||
if (box) {
|
||||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(box.x + 260, box.y + box.height / 2, { steps: 10 });
|
||||
await page.mouse.up();
|
||||
}
|
||||
}
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
await page.click('button:has-text("登录")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('3. 导航到交易管理页面...');
|
||||
await page.click('text=财务管理');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('a:has-text("交易管理")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('4. 检查当前列表的第一条记录...');
|
||||
const firstRowBefore = await page.locator('tbody tr').first();
|
||||
const firstDateBefore = await firstRowBefore.locator('td:nth-child(2)').textContent();
|
||||
console.log(' 当前第一条记录的日期:', firstDateBefore);
|
||||
|
||||
console.log('5. 创建新交易...');
|
||||
await page.click('button:has-text("新建")');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 选择收入类型
|
||||
await page.click('label:has-text("💰 收入")');
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// 输入金额
|
||||
await page.fill('.transaction-amount-input input', '5000');
|
||||
|
||||
// 选择分类(假设有工资分类)
|
||||
const salaryButton = await page.$('button span:has-text("工资")');
|
||||
if (salaryButton) {
|
||||
await salaryButton.click();
|
||||
} else {
|
||||
// 如果没有工资分类,选择第一个可用分类
|
||||
const firstCategory = await page.$('.ant-form-item:has-text("分类") button:not(:has-text("添加"))');
|
||||
if (firstCategory) {
|
||||
await firstCategory.click();
|
||||
}
|
||||
}
|
||||
|
||||
// 设置今天的日期
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
console.log(' 设置日期为今天:', today);
|
||||
|
||||
// 填写描述
|
||||
await page.fill('textarea[placeholder*="描述"]', `测试交易 - ${new Date().toLocaleTimeString()}`);
|
||||
|
||||
console.log('6. 提交新交易...');
|
||||
await page.click('button:has-text("确定")');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('7. 验证新交易是否在第一页第一条...');
|
||||
const firstRowAfter = await page.locator('tbody tr').first();
|
||||
const firstDateAfter = await firstRowAfter.locator('td:nth-child(2)').textContent();
|
||||
const firstDescAfter = await firstRowAfter.locator('td:nth-child(8)').textContent();
|
||||
|
||||
console.log(' 新列表第一条记录的日期:', firstDateAfter);
|
||||
console.log(' 新列表第一条记录的描述:', firstDescAfter);
|
||||
|
||||
// 检查是否包含刚才创建的测试交易
|
||||
if (firstDescAfter && firstDescAfter.includes('测试交易')) {
|
||||
console.log('✅ 测试成功!新创建的交易显示在第一页第一条');
|
||||
} else {
|
||||
console.log('⚠️ 新交易可能不在第一条,让我检查前几条...');
|
||||
|
||||
// 检查前5条记录
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const row = await page.locator(`tbody tr:nth-child(${i + 1})`);
|
||||
const desc = await row.locator('td:nth-child(8)').textContent();
|
||||
if (desc && desc.includes('测试交易')) {
|
||||
console.log(` 找到了!新交易在第 ${i + 1} 条`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n📊 排序测试结果:');
|
||||
console.log(' - 默认按日期倒序排序 ✅');
|
||||
console.log(' - 新交易自动跳转到第一页 ✅');
|
||||
console.log(' - 最新的交易显示在最前面 ✅');
|
||||
|
||||
// 截图保存
|
||||
await page.screenshot({
|
||||
path: 'transaction-order-test.png',
|
||||
fullPage: false
|
||||
});
|
||||
console.log('\n截图已保存到: transaction-order-test.png');
|
||||
|
||||
} catch (error) {
|
||||
console.error('测试过程中出错:', error);
|
||||
await page.screenshot({ path: 'transaction-order-error.png' });
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
99
temp-tests/test-transaction-page.js
Normal file
99
temp-tests/test-transaction-page.js
Normal file
@@ -0,0 +1,99 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 500,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 监听控制台消息
|
||||
page.on('console', (msg) => {
|
||||
console.log(`[${msg.type()}]`, msg.text());
|
||||
});
|
||||
|
||||
// 监听页面错误
|
||||
page.on('pageerror', (error) => {
|
||||
console.log('[PAGE ERROR]', error.message);
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('1. 访问系统...');
|
||||
await page.goto('http://localhost:5667');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('2. 测试API页面...');
|
||||
await page.goto('http://localhost:5667/finance/test-api');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 测试分类API
|
||||
console.log('3. 测试分类API...');
|
||||
const categoryBtn = await page.locator('button:has-text("测试分类API")');
|
||||
await categoryBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查结果
|
||||
const preElement = await page.locator('pre');
|
||||
if (await preElement.isVisible()) {
|
||||
const content = await preElement.textContent();
|
||||
console.log('分类API结果:', `${content?.slice(0, 100)}...`);
|
||||
}
|
||||
|
||||
// 测试交易页面
|
||||
console.log('4. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查是否还在加载
|
||||
const spinners = await page.locator('.ant-spin').count();
|
||||
console.log(`找到 ${spinners} 个加载指示器`);
|
||||
|
||||
// 检查表格是否加载
|
||||
const table = await page.locator('.ant-table');
|
||||
if (await table.isVisible()) {
|
||||
console.log('✅ 表格已加载');
|
||||
|
||||
// 统计行数
|
||||
const rows = await page.locator('.ant-table-tbody tr').count();
|
||||
console.log(`表格中有 ${rows} 行数据`);
|
||||
} else {
|
||||
console.log('❌ 表格未加载');
|
||||
}
|
||||
|
||||
// 检查新建按钮
|
||||
const createBtn = await page.locator('button:has-text("新建交易")');
|
||||
if (await createBtn.isVisible()) {
|
||||
console.log('✅ 新建交易按钮存在');
|
||||
|
||||
// 点击新建按钮
|
||||
await createBtn.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 检查弹窗
|
||||
const modal = await page.locator('.ant-modal');
|
||||
if (await modal.isVisible()) {
|
||||
console.log('✅ 新建交易弹窗已打开');
|
||||
|
||||
// 关闭弹窗
|
||||
await page.locator('.ant-modal-close').click();
|
||||
}
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({
|
||||
path: 'transaction-page-test.png',
|
||||
fullPage: true,
|
||||
});
|
||||
console.log('截图已保存');
|
||||
|
||||
console.log('\n测试完成!');
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
await page.screenshot({ path: 'test-error.png', fullPage: true });
|
||||
} finally {
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
console.log('浏览器已关闭');
|
||||
}
|
||||
})();
|
||||
117
temp-tests/test-transaction.js
Normal file
117
temp-tests/test-transaction.js
Normal file
@@ -0,0 +1,117 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
// 启动浏览器
|
||||
const browser = await chromium.launch({
|
||||
headless: false, // 使用有头模式方便观察
|
||||
slowMo: 500, // 减慢操作速度,方便观察
|
||||
});
|
||||
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 1280, height: 720 },
|
||||
});
|
||||
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
console.log('1. 访问系统...');
|
||||
await page.goto('http://localhost:5667');
|
||||
|
||||
// 等待页面加载完成(通过等待某个元素出现)
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查是否已自动登录
|
||||
const url = page.url();
|
||||
console.log('当前URL:', url);
|
||||
|
||||
if (url.includes('/login')) {
|
||||
console.log('需要登录,执行登录操作...');
|
||||
// 如果还在登录页,说明自动登录没生效
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
// 导航到交易管理页面
|
||||
console.log('2. 导航到交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 点击新建按钮
|
||||
console.log('3. 点击新建交易按钮...');
|
||||
const createButton = await page
|
||||
.locator('button:has-text("新建交易")')
|
||||
.first();
|
||||
await createButton.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 填写表单
|
||||
console.log('4. 填写交易表单...');
|
||||
|
||||
// 选择交易类型(支出)
|
||||
await page.locator('.ant-select').first().click();
|
||||
await page.locator('.ant-select-item:has-text("支出")').click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// 选择分类(等待分类加载)
|
||||
console.log(' 选择分类...');
|
||||
await page.locator('.ant-select').nth(1).click();
|
||||
await page.waitForTimeout(500);
|
||||
const categoryOption = await page.locator('.ant-select-item').first();
|
||||
if (await categoryOption.isVisible()) {
|
||||
await categoryOption.click();
|
||||
}
|
||||
|
||||
// 输入金额
|
||||
console.log(' 输入金额...');
|
||||
await page.locator('input.ant-input-number-input').first().fill('299.99');
|
||||
|
||||
// 选择货币
|
||||
console.log(' 选择货币...');
|
||||
await page.locator('.ant-select').nth(2).click();
|
||||
await page.locator('.ant-select-item:has-text("CNY")').click();
|
||||
|
||||
// 输入项目名称
|
||||
console.log(' 输入项目名称...');
|
||||
const projectInput = await page.locator('input[placeholder*="项目"]');
|
||||
await projectInput.fill('测试项目');
|
||||
|
||||
// 输入描述
|
||||
console.log(' 输入描述...');
|
||||
const descTextarea = await page.locator('textarea[placeholder*="描述"]');
|
||||
await descTextarea.fill('这是通过Playwright自动测试创建的交易记录');
|
||||
|
||||
// 提交表单
|
||||
console.log('5. 提交表单...');
|
||||
await page.locator('.ant-modal-footer button.ant-btn-primary').click();
|
||||
|
||||
// 等待提交完成
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查是否有成功提示
|
||||
const successMessage = await page.locator('.ant-message-success');
|
||||
if (await successMessage.isVisible()) {
|
||||
console.log('✅ 创建成功!');
|
||||
} else {
|
||||
console.log('⚠️ 未检测到成功消息,检查页面状态...');
|
||||
}
|
||||
|
||||
// 验证新记录是否出现在列表中
|
||||
console.log('6. 验证新记录是否在列表中...');
|
||||
const newRecord = await page.locator('text=测试项目').first();
|
||||
if (await newRecord.isVisible()) {
|
||||
console.log('✅ 新记录已出现在列表中!');
|
||||
} else {
|
||||
console.log('⚠️ 未在列表中找到新记录');
|
||||
}
|
||||
|
||||
console.log('\n测试完成!保持浏览器打开10秒供查看...');
|
||||
await page.waitForTimeout(10_000);
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
// 截图保存错误状态
|
||||
await page.screenshot({ path: 'test-error.png', fullPage: true });
|
||||
console.log('错误截图已保存为 test-error.png');
|
||||
} finally {
|
||||
await browser.close();
|
||||
console.log('浏览器已关闭');
|
||||
}
|
||||
})();
|
||||
192
temp-tests/test-with-slider.js
Normal file
192
temp-tests/test-with-slider.js
Normal file
@@ -0,0 +1,192 @@
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: false,
|
||||
slowMo: 300,
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// 监听控制台
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
console.log('[错误]', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('========== 测试交易管理系统 ==========\n');
|
||||
|
||||
// 1. 访问登录页
|
||||
console.log('1. 访问登录页面...');
|
||||
await page.goto('http://localhost:5667/auth/login');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 2. 填写登录信息
|
||||
console.log('2. 填写登录信息...');
|
||||
|
||||
// 输入用户名
|
||||
const usernameInput = await page.locator('input[placeholder*="用户名"]');
|
||||
await usernameInput.fill('admin');
|
||||
console.log(' 用户名: admin');
|
||||
|
||||
// 输入密码
|
||||
const passwordInput = await page.locator('input[type="password"]');
|
||||
await passwordInput.fill('123456');
|
||||
console.log(' 密码: ******');
|
||||
|
||||
// 3. 处理滑块验证
|
||||
console.log('3. 处理滑块验证...');
|
||||
|
||||
// 等待滑块出现
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 尝试多个可能的滑块选择器
|
||||
let sliderBtn = await page.locator('.slider-button');
|
||||
let sliderTrack = await page.locator('.slider-track');
|
||||
|
||||
// 如果第一组选择器不存在,尝试其他选择器
|
||||
if (!(await sliderBtn.isVisible())) {
|
||||
sliderBtn = await page.locator('[class*="slider"][class*="btn"]');
|
||||
sliderTrack = await page.locator('[class*="slider"][class*="track"]');
|
||||
}
|
||||
|
||||
// 如果还是找不到,尝试更通用的选择器
|
||||
if (!(await sliderBtn.isVisible())) {
|
||||
sliderBtn = await page.locator('[draggable="true"]');
|
||||
sliderTrack = await page.locator('[class*="verify"]');
|
||||
}
|
||||
|
||||
if (await sliderBtn.isVisible()) {
|
||||
console.log(' 找到滑块,开始拖动...');
|
||||
|
||||
// 获取滑块位置
|
||||
const btnBox = await sliderBtn.boundingBox();
|
||||
|
||||
if (btnBox) {
|
||||
// 计算起点和终点
|
||||
const startX = btnBox.x + btnBox.width / 2;
|
||||
const startY = btnBox.y + btnBox.height / 2;
|
||||
const endX = startX + 300; // 向右拖动300像素
|
||||
|
||||
// 执行拖动
|
||||
await page.mouse.move(startX, startY);
|
||||
await page.mouse.down();
|
||||
|
||||
// 缓慢拖动到终点
|
||||
const steps = 30;
|
||||
for (let i = 1; i <= steps; i++) {
|
||||
const x = startX + (endX - startX) * (i / steps);
|
||||
await page.mouse.move(x, startY);
|
||||
await page.waitForTimeout(10);
|
||||
}
|
||||
|
||||
await page.mouse.up();
|
||||
console.log(' ✅ 滑块验证完成');
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
} else {
|
||||
console.log(' 未找到滑块验证,可能需要手动处理');
|
||||
console.log(' 请在浏览器中手动完成滑块验证...');
|
||||
// 给用户10秒时间手动完成滑块验证
|
||||
await page.waitForTimeout(10_000);
|
||||
}
|
||||
|
||||
// 4. 点击登录
|
||||
console.log('4. 点击登录按钮...');
|
||||
const loginBtn = await page.locator('button[aria-label="login"]');
|
||||
await loginBtn.click();
|
||||
|
||||
// 等待登录完成
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 5. 检查是否登录成功
|
||||
const currentUrl = page.url();
|
||||
if (currentUrl.includes('/login')) {
|
||||
console.log(' ❌ 登录失败');
|
||||
await page.screenshot({ path: 'login-failed.png' });
|
||||
} else {
|
||||
console.log(' ✅ 登录成功\n');
|
||||
|
||||
// 6. 访问交易管理页面
|
||||
console.log('5. 访问交易管理页面...');
|
||||
await page.goto('http://localhost:5667/finance/transaction');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 检查页面元素
|
||||
const table = await page.locator('.ant-table');
|
||||
const createBtn = await page.locator('button:has-text("新建")');
|
||||
|
||||
if (await table.isVisible()) {
|
||||
console.log(' ✅ 交易列表显示正常');
|
||||
|
||||
const rows = await page.locator('.ant-table-tbody tr').count();
|
||||
console.log(` 当前有 ${rows} 条交易记录`);
|
||||
}
|
||||
|
||||
// 7. 测试新建交易
|
||||
if (await createBtn.isVisible()) {
|
||||
console.log('\n6. 测试新建交易功能...');
|
||||
await createBtn.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
const modal = await page.locator('.ant-modal');
|
||||
if (await modal.isVisible()) {
|
||||
console.log(' ✅ 新建交易弹窗打开');
|
||||
|
||||
// 选择类型
|
||||
const typeSelect = await page.locator('.ant-select').nth(0);
|
||||
await typeSelect.click();
|
||||
await page.locator('.ant-select-item:has-text("支出")').click();
|
||||
console.log(' 选择类型: 支出');
|
||||
|
||||
// 输入金额
|
||||
const amountInput = await page.locator(
|
||||
'input.ant-input-number-input',
|
||||
);
|
||||
await amountInput.fill('188.88');
|
||||
console.log(' 输入金额: 188.88');
|
||||
|
||||
// 输入描述
|
||||
const descInput = await page.locator('textarea[placeholder*="描述"]');
|
||||
if (await descInput.isVisible()) {
|
||||
await descInput.fill('Playwright测试交易');
|
||||
console.log(' 输入描述: Playwright测试交易');
|
||||
}
|
||||
|
||||
// 提交
|
||||
const submitBtn = await page.locator(
|
||||
'.ant-modal-footer button.ant-btn-primary',
|
||||
);
|
||||
await submitBtn.click();
|
||||
console.log(' 点击提交...');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 检查结果
|
||||
const successMsg = await page.locator('.ant-message-success');
|
||||
if (await successMsg.isVisible()) {
|
||||
console.log(' ✅ 交易创建成功!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: 'test-final.png', fullPage: true });
|
||||
console.log('\n截图保存: test-final.png');
|
||||
|
||||
console.log('\n========== 测试完成 ==========');
|
||||
console.log('✅ 系统运行正常');
|
||||
console.log('✅ 登录功能正常');
|
||||
console.log('✅ 交易管理页面正常');
|
||||
console.log('✅ 新建交易功能正常');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试失败:', error.message);
|
||||
await page.screenshot({ path: 'error.png' });
|
||||
} finally {
|
||||
console.log('\n浏览器将在5秒后关闭...');
|
||||
await page.waitForTimeout(5000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user