- Add HVAC_Test_User_Factory class with: * User creation with specific roles * Multiple role support * Persona management system * Account cleanup integration - Create comprehensive test suite in HVAC_Test_User_Factory_Test.php - Update testing improvement plan documentation - Add implementation decisions to project memory bank - Restructure .gitignore with: * Whitelist approach for better file management * Explicit backup exclusions * Specific bin directory inclusions Part of the Account Management component from the testing framework improvement plan.
69 lines
No EOL
2.4 KiB
TypeScript
69 lines
No EOL
2.4 KiB
TypeScript
import { Reporter, TestCase, TestResult, TestStep } from '@playwright/test/reporter';
|
|
|
|
export interface ReportMetrics {
|
|
duration: number;
|
|
memory: number;
|
|
networkRequests: number;
|
|
}
|
|
|
|
export abstract class BaseReporter implements Reporter {
|
|
protected testResults: Map<string, TestResult[]> = new Map();
|
|
protected metrics: Map<string, ReportMetrics> = new Map();
|
|
|
|
onBegin(config: any, suite: any) {
|
|
this.testResults.clear();
|
|
this.metrics.clear();
|
|
}
|
|
|
|
onTestEnd(test: TestCase, result: TestResult) {
|
|
if (!this.testResults.has(test.title)) {
|
|
this.testResults.set(test.title, []);
|
|
}
|
|
this.testResults.get(test.title)?.push(result);
|
|
|
|
// Collect metrics
|
|
this.metrics.set(test.title, {
|
|
duration: result.duration,
|
|
memory: this.calculateMemoryUsage(result),
|
|
networkRequests: this.countNetworkRequests(result)
|
|
});
|
|
}
|
|
|
|
protected getStatusCounts() {
|
|
let passed = 0, failed = 0, skipped = 0;
|
|
this.testResults.forEach(results => {
|
|
results.forEach(result => {
|
|
if (result.status === 'passed') passed++;
|
|
else if (result.status === 'failed') failed++;
|
|
else if (result.status === 'skipped') skipped++;
|
|
});
|
|
});
|
|
return { passed, failed, skipped };
|
|
}
|
|
|
|
protected calculateMemoryUsage(result: TestResult): number {
|
|
// Extract memory info from test result attachments or metadata
|
|
return result.attachments
|
|
.filter(a => a.name === 'memory-snapshot')
|
|
.reduce((total, snapshot) => total + (snapshot.body ? JSON.parse(snapshot.body.toString()).memoryUsage : 0), 0);
|
|
}
|
|
|
|
protected countNetworkRequests(result: TestResult): number {
|
|
return result.attachments
|
|
.filter(a => a.name === 'network-requests')
|
|
.reduce((total, reqs) => total + (reqs.body ? JSON.parse(reqs.body.toString()).length : 0), 0);
|
|
}
|
|
|
|
protected getAttachments(result: TestResult) {
|
|
return {
|
|
screenshots: result.attachments.filter(a => a.contentType?.startsWith('image/')),
|
|
videos: result.attachments.filter(a => a.contentType?.startsWith('video/')),
|
|
traces: result.attachments.filter(a => a.name === 'trace')
|
|
};
|
|
}
|
|
|
|
protected formatDuration(ms: number): string {
|
|
if (ms < 1000) return `${ms}ms`;
|
|
return `${(ms / 1000).toFixed(2)}s`;
|
|
}
|
|
} |