upskill-event-manager/wordpress-dev/tests/e2e/reporters/MarkdownReporter.ts
bengizmo d6211ee364 feat(testing): Implement HVAC_Test_User_Factory and update .gitignore
- 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.
2025-04-14 17:41:36 -03:00

152 lines
No EOL
4.9 KiB
TypeScript

import { TestCase, TestResult } from '@playwright/test/reporter';
import { BaseReporter, ReportMetrics } from './BaseReporter';
import fs from 'fs/promises';
import path from 'path';
export class MarkdownReporter extends BaseReporter {
private outputFile: string;
private sections: string[] = [];
constructor(options: { outputFile: string }) {
super();
this.outputFile = options.outputFile;
}
async onEnd() {
const counts = this.getStatusCounts();
// Test Summary Section
this.sections.push(`# Test Execution Report\n
## Summary
- **Total Tests:** ${counts.passed + counts.failed + counts.skipped}
- **Passed:** ${counts.passed}
- **Failed:** ${counts.failed}
- **Skipped:** ${counts.skipped}
- **Execution Time:** ${this.calculateTotalDuration()}
`);
// Test Results by Status
this.addStatusSection('Passed Tests', 'passed');
this.addStatusSection('Failed Tests', 'failed');
this.addStatusSection('Skipped Tests', 'skipped');
// Performance Metrics
this.sections.push(`\n## Performance Metrics\n`);
this.metrics.forEach((metrics, title) => {
this.sections.push(`### ${title}
- Duration: ${this.formatDuration(metrics.duration)}
- Memory Usage: ${Math.round(metrics.memory)}MB
- Network Requests: ${metrics.networkRequests}
`);
});
// Attachments Summary
this.sections.push(`\n## Test Artifacts\n`);
await this.summarizeAttachments();
// Error Details
this.sections.push(`\n## Error Details\n`);
this.testResults.forEach((results, title) => {
results.forEach(result => {
if (result.error) {
this.sections.push(`### Error in ${title}
\`\`\`
${result.error.message}
${result.error.stack || ''}
\`\`\`
`);
}
});
});
// Log Integration
this.sections.push(`\n## Log Integration\n`);
await this.addLogSummary();
// Write the report
await fs.mkdir(path.dirname(this.outputFile), { recursive: true });
await fs.writeFile(this.outputFile, this.sections.join('\n'));
}
private addStatusSection(title: string, status: string) {
const tests = Array.from(this.testResults.entries())
.filter(([_, results]) => results.some(r => r.status === status));
if (tests.length > 0) {
this.sections.push(`\n## ${title}\n`);
tests.forEach(([title, results]) => {
results.forEach(result => {
if (result.status === status) {
const metrics = this.metrics.get(title);
this.sections.push(`### ${title}
- Duration: ${this.formatDuration(metrics?.duration || 0)}
- Status: ${status.toUpperCase()}
${result.error ? `- Error: ${result.error.message}\n` : ''}
`);
}
});
});
}
}
private calculateTotalDuration(): string {
const total = Array.from(this.metrics.values())
.reduce((sum, metrics) => sum + metrics.duration, 0);
return this.formatDuration(total);
}
private async summarizeAttachments() {
const summary = {
screenshots: 0,
videos: 0,
traces: 0
};
this.testResults.forEach((results) => {
results.forEach(result => {
const attachments = this.getAttachments(result);
summary.screenshots += attachments.screenshots.length;
summary.videos += attachments.videos.length;
summary.traces += attachments.traces.length;
});
});
this.sections.push(`### Attachment Summary
- Screenshots: ${summary.screenshots}
- Videos: ${summary.videos}
- Traces: ${summary.traces}
> Note: All attachments are stored in the \`test-results/attachments\` directory
`);
}
private async addLogSummary() {
let errorCount = 0;
let warningCount = 0;
this.testResults.forEach((results) => {
results.forEach(result => {
result.attachments
.filter(a => a.name === 'log-entries')
.forEach(log => {
if (log.body) {
const entries = JSON.parse(log.body.toString());
errorCount += entries.filter((e: any) => e.level === 'ERROR').length;
warningCount += entries.filter((e: any) => e.level === 'WARNING').length;
}
});
});
});
this.sections.push(`### Log Summary
- Total Errors: ${errorCount}
- Total Warnings: ${warningCount}
> Note: Detailed logs are available in the following locations:
> - WordPress Debug Log: \`wp-content/debug.log\`
> - PHP Error Log: \`php_errors.log\`
> - Nginx Access Log: \`access.log\`
> - Nginx Error Log: \`error.log\`
`);
}
}