aiotests-playwright-reporter
Version:
AIO Tests reporter for reporting results from Playwright to AIO Tests
679 lines (678 loc) • 31.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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.reportTestResults = exports.validateAIOConfig = void 0;
const AioTestsLogger_1 = __importDefault(require("./AioTestsLogger"));
const axios_1 = __importStar(require("axios"));
const fs_1 = __importDefault(require("fs"));
const form_data_1 = __importDefault(require("form-data"));
const baseUrl = "https://tcms.aiojiraapps.com/aio-tcms/api/v1";
const restVersion = "/rest/aio-tcms-api/1.0";
const rateLimitWaitTime = 60 * 1000;
const apiTimeout = 45 * 1000;
const CREATE_IF_ABSENT = "CREATE_IF_ABSENT";
const createNewCycleOptions = [true, false, "true", "false", CREATE_IF_ABSENT];
const bulkRequestBody = { testRuns: [] };
const browserKeyMap = new Map();
const browserBulkRequestMap = new Map();
let debugMode = false;
let aioAPIClient;
let isAttachmentAPIAvailable = null;
let stopReporting = false;
let allCaseKeys = [];
let allFailedRuns = [];
let bulkTestRunUpdate = false;
let multiBrowser = false;
function sleep(ms) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => setTimeout(resolve, ms));
});
}
function initAPIClient(aioConfig) {
debugMode = !!aioConfig.debugMode;
AioTestsLogger_1.default.setDebugMode(debugMode);
AioTestsLogger_1.default.debug("Debug Mode is set to true");
if (aioConfig.cloud || process.env.AIO_API_KEY) {
if (!aioConfig.cloud.apiKey && !process.env.AIO_API_KEY) {
AioTestsLogger_1.default.error('Cloud hosting config does not specify apiKey. Please add "cloud":{"apiKey":"auth token"}', debugMode);
}
else {
let apiKey = process.env.AIO_API_KEY
? process.env.AIO_API_KEY
: aioConfig.cloud.apiKey;
aioAPIClient = axios_1.default.create({
baseURL: baseUrl,
timeout: apiTimeout,
headers: { Authorization: `AioAuth ${apiKey}` },
});
}
return;
}
else if (aioConfig.hosted) {
if (!!!aioConfig.hosted.jiraUrl) {
AioTestsLogger_1.default.error('Server hosting config does not specify jiraUrl. Please add "server":{"jiraUrl":"https://companyhostedjira.com/jira"}');
}
else {
aioAPIClient = axios_1.default.create({
baseURL: aioConfig.hosted.jiraUrl + restVersion,
timeout: apiTimeout,
});
if (aioConfig.hosted.jiraUsername || process.env.JIRA_USERNAME) {
let jUsername = process.env.JIRA_USERNAME
? process.env.JIRA_USERNAME
: aioConfig.hosted.jiraUsername;
let jPassword = process.env.JIRA_PASSWORD
? process.env.JIRA_PASSWORD
: aioConfig.hosted.jiraPassword;
aioAPIClient.defaults.auth = {
username: jUsername,
password: jPassword,
};
}
else if (aioConfig.hosted.jiraPAT || process.env.JIRA_PAT) {
let jPAT = process.env.JIRA_PAT
? process.env.JIRA_PAT
: aioConfig.hosted.jiraPAT;
aioAPIClient.defaults.headers.common["Authorization"] = `Bearer ${jPAT}`;
}
else {
AioTestsLogger_1.default.error("Server hosting config missing Jira username or PAT. " +
' Please set JIRA_USERNAME/JIRA_PASSWORD or JIRA_PAT as an environment variable or add "hosted":{"jiraUrl":"yoururl", "jiraUsername":"un", "jiraPassword":"pwd"}' +
' or "hosted":{"jiraUrl":"your url", "jiraPAT":"PAT token"} to config file');
aioAPIClient = null;
}
}
return;
}
AioTestsLogger_1.default.error("No authentication information found. Please set AIO_API_KEY/JIRA_USERNAME/JIRA_PAT as an environment variable or " +
'add "cloud":{"apiKey":"auth token"} or "server":{"jiraServerUrl":"val"}) to config');
}
const validateAIOConfig = (config, reportError) => {
if (!!config.enableReporting) {
if (!!!config.jiraProjectId && !!reportError) {
AioTestsLogger_1.default.error("Jira Project Id is mandatory for AIO Tests Reporting.", true);
return;
}
initAPIClient(config);
if (!aioAPIClient) {
AioTestsLogger_1.default.error("Please specify valid credentials to connect with AIO Tests.");
return;
}
return config;
}
else {
if (reportError)
AioTestsLogger_1.default.error("AIO Tests reporting is not enabled. Please set env:{aioTests:{enableReporting:true}}", true);
}
return undefined;
};
exports.validateAIOConfig = validateAIOConfig;
const getOrCreateCycle = (aioConfig) => __awaiter(void 0, void 0, void 0, function* () {
if (!aioAPIClient) {
return Promise.resolve();
}
AioTestsLogger_1.default.logStartEnd("Determining cycle to update");
if (!aioConfig.cycleDetails) {
AioTestsLogger_1.default.error('Please specify cycleDetails in config. eg. "cycleDetails": {"cycleKey":"AT-CY-11"}', true);
return Promise.resolve();
}
else {
let aioCycleConfig = aioConfig.cycleDetails;
if (aioCycleConfig.createNewCycle &&
!createNewCycleOptions.includes(aioCycleConfig.createNewCycle)) {
return Promise.resolve(`Invalid value for createNewCycle "${aioCycleConfig.createNewCycle}". Valid values include ${createNewCycleOptions}.`);
}
if ((!aioCycleConfig.createNewCycle || "false" === aioCycleConfig.createNewCycle) && aioCycleConfig.cycleKey) {
aioCycleConfig["cycleKeyToReportTo"] = aioCycleConfig.cycleKey;
return Promise.resolve();
}
if (aioCycleConfig.createNewCycle === true || "true" === aioCycleConfig.createNewCycle || aioCycleConfig.createNewCycle === CREATE_IF_ABSENT) {
let cycleTitle = aioCycleConfig.cycleName;
let customFields = aioCycleConfig.customFields;
if (!cycleTitle) {
return Promise.resolve("createNewCycle is set to " + aioCycleConfig.createNewCycle + " in config. Please set cycleName.");
}
if (aioCycleConfig.createNewCycle === CREATE_IF_ABSENT) {
let results = yield findExistingCycleThroughName(aioConfig);
if (results === true) {
AioTestsLogger_1.default.debug("Existing cycle found");
//Cycle found and set.
return;
}
if (results !== false) {
//Error while finding cycle.
AioTestsLogger_1.default.log(results);
return;
}
}
AioTestsLogger_1.default.log("Creating cycle : " + cycleTitle);
let folderCreationPromise = getOrCreateFolder(aioConfig.jiraProjectId, aioCycleConfig);
return folderCreationPromise
.then((folderCreationResponse) => __awaiter(void 0, void 0, void 0, function* () {
AioTestsLogger_1.default.debug("Folder task resolved. Creating cycle.");
let createCycleBody = {
title: cycleTitle,
customFields: customFields || null,
};
if (folderCreationResponse) {
createCycleBody.folder = folderCreationResponse.data;
}
if (aioCycleConfig.tasks && aioCycleConfig.tasks.length > 0 && Array.isArray(aioCycleConfig.tasks)) {
let jiraTasks = aioCycleConfig.tasks.filter((f) => f && !!f.trim());
if (jiraTasks.length > 0) {
createCycleBody.jiraTaskIDs = jiraTasks;
}
}
AioTestsLogger_1.default.debug("Cycle endpoint " + "/project/" + aioConfig.jiraProjectId + "/testcycle/detail");
try {
let response = yield aioAPIClient
.post("/project/" + aioConfig.jiraProjectId + "/testcycle/detail", createCycleBody);
aioCycleConfig["cycleKeyToReportTo"] = response.data.key;
AioTestsLogger_1.default.log("Cycle created successfully : " + aioCycleConfig.cycleKeyToReportTo);
}
catch (error) {
debugLogError(error);
if (error.response) {
if (error.response.status === 401 ||
error.response.status === 403) {
return Promise.resolve("Authorization error. Please check credentials.");
}
else {
return Promise.resolve(error.response.status + " : " + error.response.data);
}
}
}
}))
.catch((error) => {
debugLogError(error);
if (error.response) {
AioTestsLogger_1.default.error(error.response.status + " : " + error.response.data);
}
return Promise.resolve("Error in fetching or creating cycle folder. " +
'Please check format of folder, for eg. ["Cloud","Release1"]');
});
}
return Promise.resolve('createNewCycle is false in config. Please specify a cycle key (eg. AT-CY-11) as "cycleKey":"AT-CY=11" or cycle name as "cycleName":"Regression release 1" ');
}
});
function getOrCreateFolder(jiraProjectId, aioCycleConfig) {
return __awaiter(this, void 0, void 0, function* () {
if (aioCycleConfig.folder && Array.isArray(aioCycleConfig.folder) && aioCycleConfig.folder.length > 0) {
const userFolderHierarchy = aioCycleConfig.folder.filter((folder) => folder && folder.trim());
if (userFolderHierarchy.length > 0) {
AioTestsLogger_1.default.log(`Creating or fetching folder: ${userFolderHierarchy}`);
return aioAPIClient.put(`/project/${jiraProjectId}/testcycle/folder/hierarchy`, {
folderHierarchy: userFolderHierarchy,
});
}
}
else {
AioTestsLogger_1.default.debug("No cycle folder information set.");
}
return Promise.resolve();
});
}
function findExistingCycleThroughName(aioConfig) {
return __awaiter(this, void 0, void 0, function* () {
if (aioConfig.parallelBuild && aioConfig.parallelBuild.masterBuild === false) {
let to = aioConfig.parallelBuild.waitForSeconds
? aioConfig.parallelBuild.waitForSeconds
: 2;
AioTestsLogger_1.default.log(`Waiting for ${to} seconds for master build to finish`);
yield new Promise((resolve) => setTimeout(resolve, to * 1000));
}
let body = {
title: {
comparisonType: "EXACT_MATCH",
value: aioConfig.cycleDetails.cycleName.trim(),
},
};
AioTestsLogger_1.default.log("Finding cycle with name : " + aioConfig.cycleDetails.cycleName.trim());
return aioAPIClient
.post(`/project/${aioConfig.jiraProjectId}/testcycle/search`, body)
.then(function (response) {
var _a, _b;
const items = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.items;
if (items && items.length > 0) {
aioConfig.cycleDetails["cycleKeyToReportTo"] = (_b = items[0]) === null || _b === void 0 ? void 0 : _b.key;
return true;
}
else {
return false;
}
})
.catch(function (error) {
debugLogError(error);
if (error.response) {
if (error.response.status === 401 || error.response.status === 403) {
return Promise.resolve("Authorization error. Please check credentials.");
}
else {
return Promise.resolve(error.response.status + " : " + error.response.data);
}
}
return Promise.resolve("An unknown error occurred while searching for the cycle.");
});
});
}
function getCustomFieldValueToUpdate(customFieldsToUpdate) {
const cfUpdates = [];
if (customFieldsToUpdate) {
customFieldsToUpdate.forEach((cf) => {
const data = {
customValue: { name: cf.name, value: cf.value },
};
if (cf.operationType) {
data.customFieldUpdateOperationType = cf.operationType;
}
cfUpdates.push(data);
});
}
return cfUpdates;
}
const replaceProjectNameForRunFields = (customFieldUpdates, projectName) => {
if (customFieldUpdates == null) {
return null;
}
return customFieldUpdates.map((customFieldUpdate) => replaceProjectName(customFieldUpdate, projectName));
};
const replaceProjectName = (customFieldUpdate, projectName) => {
const { value } = customFieldUpdate.customValue;
let newValue;
if (typeof value === "string") {
// Case: value is a string
newValue = value.replace(/\$project/g, projectName);
}
else if (Array.isArray(value)) {
if (value.every((item) => typeof item === "string")) {
// Case: value is a string[]
newValue = value.map((item) => item.replace(/\$project/g, projectName));
}
else if (value.every((item) => typeof item === "object" && item !== null && "value" in item)) {
// Case: value is a { value: string }[]
newValue = value.map((item) => ({
value: item.value.replace(/\$project/g, projectName),
}));
}
else {
throw new Error("Invalid array structure in value field");
}
}
else if (typeof value === "object" && value !== null) {
if ("value" in value) {
// Case: value is { value: string }
newValue = { value: value.value.replace(/\$project/g, projectName) };
}
else {
throw new Error("Invalid object structure in value field");
}
}
else {
newValue = value;
}
return {
customValue: { name: customFieldUpdate.customValue.name, value: newValue },
customFieldUpdateOperationType: customFieldUpdate.customFieldUpdateOperationType,
};
};
function debugLogError(error) {
if (debugMode) {
AioTestsLogger_1.default.error("*** AIO Debug Mode Error Reporting ***");
AioTestsLogger_1.default.errorObj(error.message);
if (error.response) {
const status = error.response.status;
const data = error.response.data;
AioTestsLogger_1.default.errorObj(`${status} ${data}`);
}
else {
AioTestsLogger_1.default.errorObj(error);
}
AioTestsLogger_1.default.error("*** AIO Debug Mode Error Reporting End ***");
}
}
function getAIORunStatus(playwrightStatus) {
switch (playwrightStatus) {
case "failed":
return "Failed";
case "passed":
return "Passed";
default:
return "Not Run";
}
}
function uploadScreenshot(path, jiraProjectId, cyclekey, runId, trialCounter = 0) {
return __awaiter(this, void 0, void 0, function* () {
if (path) {
const form = new form_data_1.default();
form.append("file", fs_1.default.createReadStream(path));
try {
yield aioAPIClient.post(`/project/${jiraProjectId}/testcycle/${cyclekey}/testrun/${runId}/attachment`, form, {
headers: form.getHeaders(),
});
AioTestsLogger_1.default.log(`Screenshot uploaded: ${path}`);
}
catch (error) {
if (error.response) {
if (error.response.status === 429 && trialCounter < 3) {
AioTestsLogger_1.default.log("Reached AIO rate limits. Pausing...");
yield sleep(rateLimitWaitTime);
return uploadScreenshot(path, jiraProjectId, cyclekey, runId, trialCounter + 1);
}
else if (error.response.status === 404) {
AioTestsLogger_1.default.error("Attachment API is not supported in the current API version and hence attachments could not be uploaded. Please upgrade to the latest version of AIO Tests.");
isAttachmentAPIAvailable = false;
}
}
else {
if (error.data) {
AioTestsLogger_1.default.error(error.data);
}
else {
AioTestsLogger_1.default.error(error.code);
}
}
}
}
});
}
function initCycleDetails(aioConfig) {
return __awaiter(this, void 0, void 0, function* () {
try {
const data = yield getOrCreateCycle(aioConfig);
if (aioConfig.cycleDetails.cycleKeyToReportTo) {
AioTestsLogger_1.default.log("Reporting results to cycle : " + aioConfig.cycleDetails.cycleKeyToReportTo);
}
else {
stopReporting = true;
if (typeof data === "string") {
AioTestsLogger_1.default.error(data);
}
}
}
catch (err) {
if (err instanceof Error) {
AioTestsLogger_1.default.error("An error occurred: " + err.message);
}
else {
AioTestsLogger_1.default.error("An unknown error occurred");
}
stopReporting = true;
}
});
}
const reportTestResults = function (config, testSummary, multiBrowsers) {
return __awaiter(this, void 0, void 0, function* () {
if (testSummary && testSummary.length) {
yield initCycleDetails(config);
if (!aioAPIClient || stopReporting) {
return Promise.resolve();
}
multiBrowser = multiBrowsers;
const cfUpdates = config.runDetails ? getCustomFieldValueToUpdate(config.runDetails.customFieldsToUpdate) : null;
let index = 0;
const total = testSummary.length;
AioTestsLogger_1.default.logStartEnd("Reporting results");
for (const { result, test } of testSummary) {
const isLast = index === total - 1;
yield reportSpecResults(config, result, test, cfUpdates);
if (isLast && bulkTestRunUpdate) {
yield bulkUpdateResult(config);
}
index++;
}
}
else {
AioTestsLogger_1.default.log("No case keys found in specs");
}
});
};
exports.reportTestResults = reportTestResults;
const reportSpecResults = function (config, results, testCase, cfUpdates) {
return __awaiter(this, void 0, void 0, function* () {
const testData = yield findResults(results, testCase);
const passedCaseKeys = [];
const failedCaseKeys = [];
const targetKeys = results.status === "passed" ? passedCaseKeys : failedCaseKeys;
targetKeys.push(...testData.keys());
allCaseKeys.push(...targetKeys);
if (failedCaseKeys.length > 0) {
AioTestsLogger_1.default.log("*".repeat(5) + " Updating failed cases " + "*".repeat(5));
try {
yield postFailedResult(failedCaseKeys, testData, config, cfUpdates);
}
catch (err) {
debugLogError(err);
}
}
yield addDataForBulkUpdateResult(passedCaseKeys, testData, config, cfUpdates);
});
};
function postFailedResult(failedCaseKeys, testData, config, cfUpdates) {
return __awaiter(this, void 0, void 0, function* () {
return failedCaseKeys.reduce((promiseChain, caseKey) => {
const attemptData = testData.get(caseKey);
return promiseChain.then(() => __awaiter(this, void 0, void 0, function* () {
yield postResult(config, caseKey, attemptData, attemptData.screenshot, cfUpdates);
}));
}, Promise.resolve());
});
}
function findResults(results, testCase) {
return __awaiter(this, void 0, void 0, function* () {
let testData = new Map();
let pattern = new RegExp("\\w+-TC-\\d+", "gi");
let tcKeys = [];
let match;
testCase.tags.forEach((tag) => {
do {
match = pattern.exec(tag);
if (match) {
tcKeys.push(match[0]);
}
} while (match != null);
});
if (tcKeys.length) {
tcKeys.forEach((tcKey) => {
// @ts-ignore
const comments = results.error || multiBrowser ? generateComments(testCase._projectId ? testCase._projectId : "", results.error) : null;
// @ts-ignore
testData.set(tcKey, {
testId: tcKey,
duration: results.duration / 1000,
testStatus: getAIORunStatus(results.status),
retires: results.retry,
comments: comments,
screenshot: results.attachments
.filter((attachment) => attachment.contentType.startsWith("image"))
.map((attachment) => attachment.path)
.filter((path) => path !== undefined),
// @ts-ignore
browser: testCase._projectId
});
});
}
return testData;
});
}
function generateComments(browserName, error) {
return [
multiBrowser ? `Browser: ${browserName}` : undefined,
(error === null || error === void 0 ? void 0 : error.message) ? `Message: ${error.message}` : undefined,
(error === null || error === void 0 ? void 0 : error.stack) ? `Stack: ${error.stack}` : undefined,
].filter(Boolean);
}
function addDataForBulkUpdateResult(passedCaseKeys, testDataMap, config, cfUpdates) {
return __awaiter(this, void 0, void 0, function* () {
for (const passedCaseKey of passedCaseKeys) {
const testData = testDataMap.get(passedCaseKey);
if (!testData)
continue;
const testRun = {
testCaseKey: passedCaseKey,
testRunStatus: testData.testStatus,
effort: testData.duration,
isAutomated: true,
comments: testData.comments,
customFieldValueToUpdate: config.runDetails
? replaceProjectNameForRunFields(cfUpdates, testData.browser)
: cfUpdates,
};
if (multiBrowser) {
const existingRequest = browserBulkRequestMap.get(testData.browser);
if (existingRequest) {
existingRequest.testRuns.push(testRun);
}
else {
browserBulkRequestMap.set(testData.browser, { testRuns: [testRun] });
}
}
else {
bulkRequestBody.testRuns.push(testRun);
}
bulkTestRunUpdate = true;
}
});
}
function bulkUpdateResult(aioConfig, trialCounter = 0) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const { jiraProjectId, cycleDetails, addNewRun } = aioConfig;
const url = `/project/${jiraProjectId}/testcycle/${cycleDetails.cycleKeyToReportTo}/bulk/testrun/update?createNewRun=${!!addNewRun}`;
AioTestsLogger_1.default.log("*".repeat(5) + " Updating all passed cases " + "*".repeat(5));
AioTestsLogger_1.default.debug(`Reporting results in bulk: ${url}`);
try {
const processResponse = (response, browser) => {
const { successCount, errorCount, errors } = response.data;
AioTestsLogger_1.default.log(`Successfully reported ${successCount} passed cases${browser ? ` for browser: ${browser}` : ""}.`);
if (errorCount > 0) {
AioTestsLogger_1.default.error("Failures in reporting passed cases:");
Object.entries(errors).forEach(([key, error]) => {
const errorMessage = error.message || "Unknown error";
AioTestsLogger_1.default.error(`${key}: ${errorMessage}`);
});
}
};
if (multiBrowser) {
for (const [browser, bulkRequestBodyBrowser] of browserBulkRequestMap) {
const response = yield aioAPIClient.post(url, bulkRequestBodyBrowser);
processResponse(response, browser);
}
}
else {
const response = yield aioAPIClient.post(url, bulkRequestBody);
processResponse(response);
}
}
catch (err) {
debugLogError(err);
if (((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 429 && trialCounter < 3) {
AioTestsLogger_1.default.log("Reached AIO rate limits. Retrying...");
yield sleep(rateLimitWaitTime);
return bulkUpdateResult(aioConfig, trialCounter + 1);
}
const errorMsg = err.response
? `Status Code - ${err.response.status}: ${JSON.stringify(err.response.data)}`
: err.code;
AioTestsLogger_1.default.error(`Error in bulk cases reporting: ${errorMsg}`);
stopReporting = true;
}
});
}
function postResult(aioConfig, caseKey, results, screenshots, cfUpdates, trialCounter = 0) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const data = {
testRunStatus: results.testStatus,
effort: results.duration,
isAutomated: true,
comments: results.comments,
customFieldValueToUpdate: aioConfig.runDetails
? replaceProjectNameForRunFields(cfUpdates, results.browser)
: cfUpdates,
};
const createNewRun = aioConfig.addNewRun;
AioTestsLogger_1.default.debug(`Posting results to /project/${aioConfig.jiraProjectId}/testcycle/${aioConfig.cycleDetails.cycleKeyToReportTo}/testcase/${caseKey}/testrun?createNewRun=${createNewRun}`);
try {
const response = yield aioAPIClient.post(`/project/${aioConfig.jiraProjectId}/testcycle/${aioConfig.cycleDetails.cycleKeyToReportTo}/testcase/${caseKey}/testrun?createNewRun=${createNewRun}`, data);
if (multiBrowser) {
if (browserKeyMap.has(results.browser)) {
(_a = browserKeyMap.get(results.browser)) === null || _a === void 0 ? void 0 : _a.push(response.data.ID);
}
else {
browserKeyMap.set(results.browser, [response.data.ID]);
}
}
else {
allFailedRuns.push(response.data.ID);
}
AioTestsLogger_1.default.log(`Successfully reported ${caseKey} as ${data.testRunStatus} with runID ${response.data.ID}.`);
const runId = response.data.ID;
if (aioConfig.addAttachmentToFailedCases && data.testRunStatus.toLowerCase() === "failed" && (isAttachmentAPIAvailable || isAttachmentAPIAvailable == null)) {
return yield uploadAttachments(aioConfig.jiraProjectId, aioConfig.cycleDetails.cycleKeyToReportTo, runId, screenshots);
}
}
catch (err) {
debugLogError(err);
if ((0, axios_1.isAxiosError)(err) && err.response) {
if (err.response.status === 429 && trialCounter < 3) {
AioTestsLogger_1.default.log("Reached AIO rate limits. Pausing...");
yield sleep(rateLimitWaitTime);
return postResult(aioConfig, caseKey, results, screenshots, cfUpdates, trialCounter + 1);
}
else {
AioTestsLogger_1.default.error(`Error reporting ${caseKey} : Status Code - ${err.response.status} - ${err.response.data}`);
}
}
else {
AioTestsLogger_1.default.error(`Error in bulk cases reporting : ${err.message}`);
}
}
});
}
function uploadAttachments(jiraProjectId, cycleKey, runId, resultScreenshots) {
return __awaiter(this, void 0, void 0, function* () {
if (resultScreenshots) {
return resultScreenshots.reduce((promise, screenshot) => __awaiter(this, void 0, void 0, function* () {
yield promise;
return uploadScreenshot(screenshot, jiraProjectId, cycleKey, runId);
}), Promise.resolve());
}
else {
return Promise.resolve();
}
});
}