Files
E2E-Test/utils/error-handler.ts
2025-11-04 16:29:07 +08:00

157 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 错误处理工具类
* 负责错误收集、清理和报告生成
*/
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`);
}
}
}