UNPKG

artes

Version:

The simplest way to automate UI and API tests using Cucumber-style steps.

139 lines (105 loc) 3.74 kB
const { Formatter } = require('@cucumber/cucumber'); const fs = require('fs'); const path = require('path'); class StatusFormatter extends Formatter { constructor(options) { super(options); const outputDir = './test-status'; if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } const workerId = process.env.CUCUMBER_WORKER_ID || '0'; this.workerId = workerId; this.outputFile = path.join(outputDir, `test-results-${workerId}.txt`); this.outputDir = outputDir; fs.writeFileSync(this.outputFile, '', 'utf8'); this.pickles = new Map(); this.testCases = new Map(); this.testCaseStartedIdToAttempt = new Map(); const { eventBroadcaster } = options; eventBroadcaster.on('envelope', (envelope) => { if (envelope.pickle) { this.pickles.set(envelope.pickle.id, envelope.pickle); } if (envelope.testCase) { this.testCases.set(envelope.testCase.id, envelope.testCase); } if (envelope.testCaseStarted) { this.testCaseStartedIdToAttempt.set( envelope.testCaseStarted.id, envelope.testCaseStarted.testCaseId ); } if (envelope.testCaseFinished) { this.handleTestCaseFinished(envelope.testCaseFinished); } if (envelope.testRunFinished) { this.handleTestRunFinished(); } }); } getFormattedTimestamp() { const now = new Date(); const YYYY = now.getFullYear(); const MM = String(now.getMonth() + 1).padStart(2, '0'); const DD = String(now.getDate()).padStart(2, '0'); const hh = String(now.getHours()).padStart(2, '0'); const mm = String(now.getMinutes()).padStart(2, '0'); const ss = String(now.getSeconds()).padStart(2, '0'); const ms = String(now.getMilliseconds()).padStart(3, '0'); return `${YYYY}${MM}${DD}-${hh}${mm}${ss}-${ms}`; } handleTestCaseFinished(testCaseFinished) { try { const timestamp = this.getFormattedTimestamp(); const testCaseId = this.testCaseStartedIdToAttempt.get( testCaseFinished.testCaseStartedId ); if (!testCaseId) return; const testCase = this.testCases.get(testCaseId); if (!testCase) return; const pickle = this.pickles.get(testCase.pickleId); if (!pickle) return; const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt( testCaseFinished.testCaseStartedId ); const status = testCaseAttempt?.worstTestStepResult?.status || 'UNKNOWN'; const info = { name: pickle.name, id: pickle.id, uri: pickle.uri }; const line = `${timestamp} | ${status.toUpperCase()} | ${info.name} | ${info.id} | ${info.uri}\n`; fs.appendFileSync(this.outputFile, line, 'utf8'); } catch (error) { console.error('Error in handleTestCaseFinished:', error); } } handleTestRunFinished() { if (this.workerId !== '0') { return; } setTimeout(() => { this.mergeResults(); }, 1000); } mergeResults() { try { const testStatusFile = path.join(this.outputDir, 'test-status.txt'); const files = fs.readdirSync(this.outputDir) .filter(f => f.startsWith('test-results-') && f.endsWith('.txt')) .sort(); if (files.length === 0) { console.log('No result files found to merge'); return; } const combined = files .map(f => fs.readFileSync(path.join(this.outputDir, f), 'utf8')) .join(''); fs.writeFileSync(testStatusFile, combined, 'utf8'); } catch (error) { console.error('Error merging results:', error); } } } module.exports = StatusFormatter;