const fs = require('fs'); class CustomReporter { onEnd(config, result) { const outputPath = 'tests/output/latest-result.txt'; if (!result) { // test run aborted or failed to initialize if (!fs.existsSync('tests/output')) fs.mkdirSync('tests/output', { recursive: true }); fs.writeFileSync(outputPath, 'TEST RUN FAILED OR ABORTED', 'utf-8'); return; } const failed = result.status === 'failed' || result.numFailedTests > 0; const date = new Date().toISOString(); const duration = (result.duration || 0) + 'ms'; if (!fs.existsSync('tests/output')) fs.mkdirSync('tests/output', { recursive: true }); if (!failed) { const content = [ '==================================', 'TEST RESULT', 'PASSED', `Date: ${date}`, `Total Test: ${result.total || 0}`, `Passed: ${result.passed || 0}`, `Failed: ${result.failed || 0}`, `Duration: ${duration}`, '==================================', ].join('\n'); fs.writeFileSync(outputPath, content, 'utf-8'); return; } const lines = []; lines.push('=================================='); lines.push('FAILED'); lines.push(`Date: ${date}`); lines.push(`Duration: ${duration}`); lines.push('=================================='); const buildFailureDetails = (suites) => { for (const s of suites) { if (s.suites && s.suites.length) buildFailureDetails(s.suites); if (s.tests && s.tests.length) { for (const t of s.tests) { if (t.status === 'failed') { lines.push('Test Name: ' + (t.title || t.titleText || '')); for (const r of t.results || []) { if (r.status === 'failed') { const error = r.error || {}; lines.push('Error Message: ' + (error.message || '')); if (error.stack) lines.push('Stack Trace: ' + error.stack); } } lines.push('----------------------------------'); } } } } }; if (result.suites) buildFailureDetails(result.suites); fs.writeFileSync(outputPath, lines.join('\n'), 'utf-8'); } } module.exports = CustomReporter;