UNPKG

pw-simple-testrail-reporter

Version:
206 lines 8.47 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TestRailReporter = void 0; exports.getTestCaseName = getTestCaseName; const testrail_1 = __importDefault(require("@dlenroc/testrail")); const logger_1 = __importDefault(require("./logger")); const dotenv_1 = __importDefault(require("dotenv")); // Read from default ".env" file. dotenv_1.default.config(); /** * Mapping status within Playwright & TestRail */ const StatusMap = new Map([ ["failed", 5], ["passed", 1], ["skipped", 3], ["timedout", 5], ["interrupted", 5], ]); /** * Initialise TestRail API credential auth */ const api = new testrail_1.default({ host: process.env.TESTRAIL_HOST, password: process.env.TESTRAIL_PASSWORD, username: process.env.TESTRAIL_USERNAME, }); const testResults = []; // Track test case IDs that need to be added to the run const testCasesToAdd = []; // Track test case IDs already in the run const existingTestCaseIds = new Set(); class TestRailReporter { onBegin() { return __awaiter(this, void 0, void 0, function* () { if (!process.env.TESTRAIL_RUN_ID) { (0, logger_1.default)("No 'TESTRAIL_RUN_ID' found, skipping reporting......"); return; } (0, logger_1.default)("Existing Test Run with ID " + process.env.TESTRAIL_RUN_ID + " will be used"); // Fetch existing test cases in the run const runId = parseInt(process.env.TESTRAIL_RUN_ID); try { const tests = yield api.getTests(runId); tests.forEach((test) => { existingTestCaseIds.add(test.case_id); }); (0, logger_1.default)(`Found ${existingTestCaseIds.size} test cases in run ${runId}`); } catch (error) { (0, logger_1.default)(`Error fetching tests for run ${runId}: ${error}`); } }); } onTestEnd(test, result) { if (!process.env.TESTRAIL_RUN_ID) { return; } (0, logger_1.default)(`Test Case Completed : ${test.title} Status : ${result.status}`); // Return no test case match with TestRail Case ID Regex const testCaseMatches = getTestCaseName(test.title); if (testCaseMatches != null) { try { testCaseMatches.forEach((testCaseMatch) => { const testId = parseInt(testCaseMatch.substring(1), 10); // Check if test case is in the run if (!existingTestCaseIds.has(testId)) { testCasesToAdd.push(testId); existingTestCaseIds.add(testId); // Add to set to avoid duplicates (0, logger_1.default)(`Test case C${testId} not in run, will be added`); } // Update test status if test case is not skipped if (result.status != "skipped") { const testComment = setTestComment(result); const payload = { case_id: testId, status_id: StatusMap.get(result.status), comment: testComment, }; testResults.push(payload); } }); } catch (error) { console.log(error); } } else { (0, logger_1.default)("Test case could not be extracted from test title!"); } } onEnd() { return __awaiter(this, void 0, void 0, function* () { if (!process.env.TESTRAIL_RUN_ID) { return; } const runId = parseInt(process.env.TESTRAIL_RUN_ID); // Add missing test cases to the run if any if (testCasesToAdd.length > 0) { try { (0, logger_1.default)(`Adding ${testCasesToAdd.length} test cases to run ${runId}`); // First get the current run to see its configuration const currentRun = yield api.getRun(runId); // Prepare the update payload const updatePayload = { case_ids: testCasesToAdd, include_all: currentRun.include_all, }; // If the run doesn't include all test cases, we need to add our new cases // to the existing ones to avoid replacing them if (!currentRun.include_all) { // Get existing case IDs if they're not already included in all cases const existingCaseIds = Array.from(existingTestCaseIds).filter((id) => !testCasesToAdd.includes(id)); // Combine existing and new case IDs updatePayload.case_ids = [ ...existingCaseIds, ...testCasesToAdd, ]; (0, logger_1.default)(`Preserving ${existingCaseIds.length} existing test cases in the run`); } // Update the run with the combined test cases yield api.updateRun(runId, updatePayload); (0, logger_1.default)(`Successfully added test cases to run ${runId}`); } catch (error) { (0, logger_1.default)(`Error adding test cases to run ${runId}: ${error}`); // If we can't add test cases, we should still try to update results for existing ones } } // Update test results if (testResults.length > 0) { (0, logger_1.default)("Updating test status for the following TestRail Run ID: " + runId); yield updateResultCases(runId, testResults); } else { (0, logger_1.default)("No test results to update"); } }); } onError(error) { (0, logger_1.default)(error.message); } } exports.TestRailReporter = TestRailReporter; /** * Get list of matching Test IDs */ function getTestCaseName(testname) { const testCaseIdRegex = /\bC(\d+)\b/g; const testCaseMatches = [testname.match(testCaseIdRegex)]; if (testCaseMatches[0] != null) { testCaseMatches[0].forEach((testCaseMatch) => { const testCaseId = parseInt(testCaseMatch.substring(1), 10); (0, logger_1.default)("Matched Test Case ID: " + testCaseId); }); } else { (0, logger_1.default)("No test case matches available"); } return testCaseMatches[0]; } /** * Set Test comment for TestCase Failed | Passed * @param result * @returns */ function setTestComment(result) { if (result.status == "failed" || result.status == "timedOut" || result.status == "interrupted") { const comment = { testStatus: result.status, testError: result.error }; return JSON.stringify(comment); } else { return `Test Passed within ${result.duration} ms`; } } /** * Update TestResult for Multiple Cases * @param runId * @param payload */ function updateResultCases(runId, payload) { return __awaiter(this, void 0, void 0, function* () { (0, logger_1.default)(payload); yield api.addResultsForCases(runId, { results: payload, }); }); } //# sourceMappingURL=reporter.js.map