@wdio/testrail-reporter
Version:
Create or update a run on testrail and publish the test case results.
143 lines (142 loc) • 7.36 kB
JavaScript
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;