UNPKG

@wdio/testrail-reporter

Version:

Create or update a run on testrail and publish the test case results.

143 lines (142 loc) 7.36 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _TestRailAPI_config, _TestRailAPI_projectId, _TestRailAPI_baseUrl, _TestRailAPI_includeAll; import axios from 'axios'; import logger from '@wdio/logger'; const log = logger('TestrailReporter'); class TestRailAPI { constructor(options) { _TestRailAPI_config.set(this, {}); _TestRailAPI_projectId.set(this, void 0); _TestRailAPI_baseUrl.set(this, void 0); _TestRailAPI_includeAll.set(this, void 0); __classPrivateFieldSet(this, _TestRailAPI_baseUrl, `https://${options.domain}/index.php?/api/v2`, "f"); __classPrivateFieldSet(this, _TestRailAPI_projectId, options.projectId, "f"); __classPrivateFieldSet(this, _TestRailAPI_includeAll, options.includeAll, "f"); __classPrivateFieldGet(this, _TestRailAPI_config, "f").auth = { username: options.username, password: options.apiToken }; } waitForRateLimit(err) { const headers = err.response?.headers; const retryAfter = headers?.['retry-after']; new Promise((resolve) => setTimeout(resolve, retryAfter * 1000)); } async updateTestRunResults(runId, results, retry = false) { try { const resp = await axios.post(`${__classPrivateFieldGet(this, _TestRailAPI_baseUrl, "f")}/add_results_for_cases/${runId}`, { results }, __classPrivateFieldGet(this, _TestRailAPI_config, "f")); return resp; } catch (err) { if (axios.isAxiosError(err) && err.response) { const statusCode = err.response.status; if (statusCode === 429 && retry === false) { this.waitForRateLimit(err); await this.updateTestRunResults(runId, results, true); } else { log.error(`Failed to update test run results: ${err.message}`); } } else { log.error(`Failed to update test run results: ${err.message}`); } } } async updateTestRun(runId, caseIds, retry = false) { await axios.get(`${__classPrivateFieldGet(this, _TestRailAPI_baseUrl, "f")}/get_tests/${runId}`, __classPrivateFieldGet(this, _TestRailAPI_config, "f")).then((res) => { if (res.data.tests.length > 0) { const addCaseIds = res.data.tests.map((tests) => tests.case_id); addCaseIds.forEach((id) => { caseIds.push(id); }); } }).catch((err) => { log.error(`Error getting test run: ${err.message}`); }); try { const resp = await axios.post(`${__classPrivateFieldGet(this, _TestRailAPI_baseUrl, "f")}/update_run/${runId}`, { 'case_ids': caseIds }, __classPrivateFieldGet(this, _TestRailAPI_config, "f")); return resp; } catch (err) { if (axios.isAxiosError(err) && err.response) { const statusCode = err.response.status; if (statusCode === 429 && retry === false) { this.waitForRateLimit(err); await this.updateTestRun(runId, caseIds, true); } else { log.error(`Failed to update test run: ${err.message}`); } } else { log.error(`Failed to update test run: ${err.message}`); } } } async pushResults(runId, testId, results, retry = false) { try { const resp = axios.post(`${__classPrivateFieldGet(this, _TestRailAPI_baseUrl, "f")}/add_result_for_case/${runId}/${testId}`, results, __classPrivateFieldGet(this, _TestRailAPI_config, "f")); return resp; } catch (err) { if (axios.isAxiosError(err) && err.response) { const statusCode = err.response.status; if (statusCode === 429 && retry === false) { this.waitForRateLimit(err); await this.pushResults(runId, testId, results, true); } else { log.error(`Failed to push results: ${err.message}`); } } else { log.error(`Failed to push results: ${err.message}`); } } } async createTestRun(test, runName) { const now = new Date(); if (!test.name) { test.name = `${runName} ${now.getDate()}.${now.getMonth()} ${now.getHours()}:${now.getMinutes()}`; } const resp = await axios.post(`${__classPrivateFieldGet(this, _TestRailAPI_baseUrl, "f")}/add_run/${__classPrivateFieldGet(this, _TestRailAPI_projectId, "f")}`, test, __classPrivateFieldGet(this, _TestRailAPI_config, "f")); log.info(`Create new run '${test.name}' with id: ${resp.data.id}`); return resp.data.id; } async getLastTestRun(suiteId, runName, timeInMinutes = 30) { const timeAgo = new Date(); timeAgo.setMinutes(timeAgo.getMinutes() - timeInMinutes); const date = new Date(timeAgo); const unixTimeStamp = Math.floor(date.getTime() / 1000); try { const resp = await axios.get(`${__classPrivateFieldGet(this, _TestRailAPI_baseUrl, "f")}/get_runs/${__classPrivateFieldGet(this, _TestRailAPI_projectId, "f")}&is_completed=0&created_after=${unixTimeStamp}&suite_id=${suiteId}`, __classPrivateFieldGet(this, _TestRailAPI_config, "f")); const thisrun = resp.data.runs.filter(function (run) { return run.name ? run.name.startsWith(runName) : false; }); const runId = thisrun.length > 0 ? thisrun[0].id : await this.createTestRun({ suite_id: suiteId, name: runName, include_all: __classPrivateFieldGet(this, _TestRailAPI_includeAll, "f") }); return runId; } catch (err) { log.error(`Failed to get last test run: ${err.message}`); } } } _TestRailAPI_config = new WeakMap(), _TestRailAPI_projectId = new WeakMap(), _TestRailAPI_baseUrl = new WeakMap(), _TestRailAPI_includeAll = new WeakMap(); export default TestRailAPI;