- 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.
152 lines
No EOL
4.9 KiB
TypeScript
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\`
|
|
`);
|
|
}
|
|
} |