first commit

This commit is contained in:
2025-11-04 16:29:07 +08:00
commit 8ee74625c7
19 changed files with 4562 additions and 0 deletions

156
utils/error-handler.ts Normal file
View File

@ -0,0 +1,156 @@
/**
* 错误处理工具类
* 负责错误收集、清理和报告生成
*/
import * as fs from 'fs';
import * as path from 'path';
import { Page } from '@playwright/test';
export interface ErrorRecord {
step: string;
error: string;
timestamp: string;
pageUrl: string;
}
export interface LoginInfo {
email: string;
password: string;
}
export class ErrorHandler {
private errors: ErrorRecord[] = [];
private loginInfo: LoginInfo;
constructor(loginInfo: LoginInfo) {
this.loginInfo = loginInfo;
}
/**
* 清理错误信息,去除技术细节
*/
private cleanErrorMessage(error: unknown): string {
let errorMessage = error instanceof Error ? error.message : String(error);
// 只保留第一行主要错误,去掉 Call log 等技术细节
const firstLine = errorMessage.split('\n')[0];
const cleanError = firstLine.replace(/\s+\(.*?\)/, '').trim();
return cleanError;
}
/**
* 记录错误
*/
recordError(stepName: string, error: unknown, page: Page): void {
const cleanError = this.cleanErrorMessage(error);
const timestamp = new Date().toISOString();
const pageUrl = page.url();
this.errors.push({
step: stepName,
error: cleanError,
timestamp,
pageUrl,
});
console.error(`[失败] ${stepName}: ${cleanError}`);
console.error(`[页面URL] ${pageUrl}`);
}
/**
* 执行步骤并捕获错误
*/
async executeStep(
stepName: string,
stepFunction: () => Promise<void>,
page: Page
): Promise<void> {
try {
console.log(`\n[执行] ${stepName}`);
await stepFunction();
console.log(`[成功] ${stepName}`);
} catch (error) {
this.recordError(stepName, error, page);
// 继续执行下一步,不中断测试流程
}
}
/**
* 获取所有错误
*/
getErrors(): ErrorRecord[] {
return this.errors;
}
/**
* 检查是否有错误
*/
hasErrors(): boolean {
return this.errors.length > 0;
}
/**
* 生成错误报告文件
*/
generateErrorReport(reportDir: string = '.', filePrefix: string = 'test-error-report'): string {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const reportPath = path.join(reportDir, `${filePrefix}-${timestamp}.txt`);
let report = '========== 测试错误报告 ==========\n\n';
report += `报告生成时间: ${new Date().toLocaleString('zh-CN')}\n\n`;
// 登录账号信息(只显示一次)
report += '【登录账号信息】\n';
report += `账号: ${this.loginInfo.email}\n`;
report += `密码: ${this.loginInfo.password}\n`;
report += `测试环境: https://pre.prodream.cn/en\n\n`;
report += `${'='.repeat(60)}\n\n`;
if (this.errors.length === 0) {
report += '✅ 所有功能测试通过,未发现问题!\n';
} else {
report += `发现 ${this.errors.length} 个问题,详情如下:\n\n`;
// 每个错误按照格式:问题功能 + 页面链接
this.errors.forEach((err, index) => {
report += `【问题 ${index + 1}\n`;
report += `问题功能: ${err.step}\n`;
report += `页面链接: ${err.pageUrl}\n`;
report += `错误详情: ${err.error}\n`;
report += `发生时间: ${new Date(err.timestamp).toLocaleString('zh-CN')}\n`;
report += '\n';
});
report += `${'='.repeat(60)}\n`;
report += `\n说明: 测试过程中遇到错误会自动跳过并继续执行后续步骤。\n`;
}
fs.writeFileSync(reportPath, report, 'utf-8');
return reportPath;
}
/**
* 打印错误摘要到控制台
*/
printSummary(): void {
console.log('\n\n========== 测试执行完成 ==========');
if (this.errors.length === 0) {
console.log('✅ 所有步骤执行成功!');
} else {
console.log(`\n⚠ 发现 ${this.errors.length} 个问题:\n`);
this.errors.forEach((err, index) => {
console.log(`【问题 ${index + 1}`);
console.log(` 问题功能: ${err.step}`);
console.log(` 页面链接: ${err.pageUrl}`);
console.log(` 错误详情: ${err.error}`);
console.log('');
});
console.log(`\n账号: ${this.loginInfo.email}`);
console.log(`密码: ${this.loginInfo.password}\n`);
}
}
}