@testomatio/reporter
Version:
Testomatio Reporter Client
109 lines (92 loc) • 3.59 kB
JavaScript
import pc from 'picocolors';
import TestomatClient from '../client.js';
import { TESTOMAT_TMP_STORAGE_DIR } from '../constants.js';
import { getTestomatIdFromTestTitle, ansiRegExp, fileSystem } from '../utils/utils.js';
import { services } from '../services/index.js';
import path from 'path';
import createDebugMessages from 'debug';
const debug = createDebugMessages('@testomatio/reporter:adapter-jest');
export class JestReporter {
constructor(globalConfig, options) {
this._globalConfig = globalConfig;
this._options = options;
this.client = new TestomatClient({ apiKey: options?.apiKey });
this.client.createRun();
}
onRunStart() {
// clear tmp dir
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
}
// start of test file (including beforeAll)
onTestStart(testFile) {
debug('Start running test file:', testFile.path);
services.setContext(testFile.path);
}
// start of the test (including beforeEach)
onTestCaseStart(test, testCase) {
debug('Start running test:', testCase.fullName);
services.setContext(testCase.fullName);
}
// end of test file! (there is also onTestCaseResult listener)
onTestResult(test, testResult) {
if (!this.client) return;
const { testResults } = testResult;
for (const result of testResults) {
let error;
let steps;
const { status, title, duration, failureMessages } = result;
if (failureMessages[0]) {
const errorMessage = failureMessages[0].replace(ansiRegExp(), '');
error = new Error(errorMessage);
steps = failureMessages[0];
}
const testId = getTestomatIdFromTestTitle(title);
// suite titles from most outer to most inner, separated by space
let fullSuiteTitle = testResult.ancestorTitles?.join(' ');
// if no suite titles, use file name
if (!fullSuiteTitle && testResult.testFilePath) fullSuiteTitle = path.basename(testResult.testFilePath);
const logs = getTestLogs(result);
const artifacts = services.artifacts.get(result.fullName);
const keyValues = services.keyValues.get(result.fullName);
const links = services.links.get(result.fullName);
const deducedStatus = status === 'pending' ? 'skipped' : status;
// In jest if test is not matched with test name pattern it is considered as skipped.
// So adding a check if it is skipped for real or because of test pattern
if (!this._globalConfig.testNamePattern || deducedStatus !== 'skipped') {
this.client.addTestRun(deducedStatus, {
test_id: testId,
suite_title: fullSuiteTitle,
error,
steps,
title,
time: duration,
logs,
links,
manuallyAttachedArtifacts: artifacts,
meta: keyValues,
});
}
}
}
onRunComplete(contexts, results) {
if (!this.client) return;
const { numFailedTests } = results;
const status = numFailedTests === 0 ? 'passed' : 'failed';
this.client.updateRunStatus(status);
}
}
function getTestLogs(testResult) {
const suiteLogsArr = services.logger.getLogs(testResult.testFilePath);
const suiteLogs = suiteLogsArr ? suiteLogsArr.join('\n').trim() : '';
const testLogsArr = services.logger.getLogs(testResult.fullName);
const testLogs = testLogsArr ? testLogsArr.join('\n').trim() : '';
let logs = '';
if (suiteLogs) {
logs += `${pc.bold('\t--- Suite ---')}\n${suiteLogs}`;
}
if (testLogs) {
logs += `\n${pc.bold('\t--- Test ---')}\n${testLogs}`;
}
return logs;
}
export default JestReporter;