export enum TestStatus { PENDING = 'pending', RUNNING = 'running', PASSED = 'passed', FAILED = 'failed', SKIPPED = 'skipped', RETRY = 'retry' } export enum ErrorType { TIMEOUT = 'timeout', ELEMENT_NOT_FOUND = 'element_not_found', API_ERROR = 'api_error', ASSERTION_ERROR = 'assertion_error', NETWORK_ERROR = 'network_error', AUTH_ERROR = 'auth_error', DATA_ERROR = 'data_error', ENVIRONMENT_ERROR = 'environment_error', UNKNOWN = 'unknown' } export interface TestError { type: ErrorType; message: string; stack?: string; screenshot?: string; video?: string; timestamp: Date; } export interface TestStep { name: string; status: TestStatus; duration: number; error?: TestError; timestamp: Date; } export interface TestCase { id: string; name: string; suite: string; module: 'api' | 'admin' | 'uniapp'; status: TestStatus; duration: number; startTime: Date; endTime?: Date; steps: TestStep[]; error?: TestError; retries: number; maxRetries: number; tags: string[]; priority: 'high' | 'medium' | 'low'; } export interface TestSuite { id: string; name: string; module: 'api' | 'admin' | 'uniapp'; tests: TestCase[]; status: TestStatus; duration: number; startTime: Date; endTime?: Date; passRate: number; } export interface TestModule { name: 'api' | 'admin' | 'uniapp'; suites: TestSuite[]; status: TestStatus; duration: number; startTime: Date; endTime?: Date; totalTests: number; passedTests: number; failedTests: number; skippedTests: number; passRate: number; } export interface TestResult { modules: TestModule[]; status: TestStatus; duration: number; startTime: Date; endTime?: Date; totalTests: number; passedTests: number; failedTests: number; skippedTests: number; passRate: number; environment: TestEnvironment; } export interface TestEnvironment { nodeVersion: string; os: string; browserVersions: Record; apiBaseUrl: string; adminBaseUrl: string; uniappBaseUrl: string; databaseType: string; timestamp: Date; } export interface TDDIteration { iteration: number; previousResult: TestResult; currentResult: TestResult; fixes: TDDFix[]; timestamp: Date; } export interface TDDFix { id: string; type: 'code' | 'test' | 'config' | 'data'; description: string; affectedTests: string[]; status: 'pending' | 'applied' | 'verified' | 'failed'; } export class TestResultBuilder { private result: TestResult; constructor() { this.result = { modules: [], status: TestStatus.PENDING, duration: 0, startTime: new Date(), totalTests: 0, passedTests: 0, failedTests: 0, skippedTests: 0, passRate: 0, environment: { nodeVersion: process.version, os: process.platform, browserVersions: {}, apiBaseUrl: process.env.API_BASE_URL || 'http://localhost:8080', adminBaseUrl: process.env.ADMIN_BASE_URL || 'http://localhost:5174', uniappBaseUrl: process.env.UNIAPP_BASE_URL || 'http://localhost:8081', databaseType: 'h2', timestamp: new Date() } }; } setStartTime(startTime: Date): this { this.result.startTime = startTime; return this; } setEndTime(endTime: Date): this { this.result.endTime = endTime; this.result.duration = endTime.getTime() - this.result.startTime.getTime(); return this; } addModule(module: TestModule): this { this.result.modules.push(module); this.updateTotals(); return this; } private updateTotals(): void { this.result.totalTests = this.result.modules.reduce((sum, m) => sum + m.totalTests, 0); this.result.passedTests = this.result.modules.reduce((sum, m) => sum + m.passedTests, 0); this.result.failedTests = this.result.modules.reduce((sum, m) => sum + m.failedTests, 0); this.result.skippedTests = this.result.modules.reduce((sum, m) => sum + m.skippedTests, 0); this.result.passRate = this.result.totalTests > 0 ? (this.result.passedTests / this.result.totalTests) * 100 : 0; this.result.status = this.result.failedTests > 0 ? TestStatus.FAILED : TestStatus.PASSED; } build(): TestResult { return { ...this.result }; } } export class TestModuleBuilder { private module: TestModule; constructor(name: 'api' | 'admin' | 'uniapp') { this.module = { name, suites: [], status: TestStatus.PENDING, duration: 0, startTime: new Date(), totalTests: 0, passedTests: 0, failedTests: 0, skippedTests: 0, passRate: 0 }; } setStartTime(startTime: Date): this { this.module.startTime = startTime; return this; } setEndTime(endTime: Date): this { this.module.endTime = endTime; this.module.duration = endTime.getTime() - this.module.startTime.getTime(); return this; } addSuite(suite: TestSuite): this { this.module.suites.push(suite); this.updateTotals(); return this; } private updateTotals(): void { this.module.totalTests = this.module.suites.reduce((sum, s) => sum + s.tests.length, 0); this.module.passedTests = this.module.suites.reduce( (sum, s) => sum + s.tests.filter(t => t.status === TestStatus.PASSED).length, 0 ); this.module.failedTests = this.module.suites.reduce( (sum, s) => sum + s.tests.filter(t => t.status === TestStatus.FAILED).length, 0 ); this.module.skippedTests = this.module.suites.reduce( (sum, s) => sum + s.tests.filter(t => t.status === TestStatus.SKIPPED).length, 0 ); this.module.passRate = this.module.totalTests > 0 ? (this.module.passedTests / this.module.totalTests) * 100 : 0; this.module.status = this.module.failedTests > 0 ? TestStatus.FAILED : TestStatus.PASSED; } build(): TestModule { return { ...this.module }; } }