UNPKG

@xray-app/xray-automation

Version:

Library for uploading test results to Xray Test Management

335 lines (334 loc) 14.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.XrayCloudClient = void 0; const graphql_request_1 = require("graphql-request"); const axios_1 = __importDefault(require("axios")); const fs_1 = __importDefault(require("fs")); const form_data_1 = __importDefault(require("form-data")); const xray_error_response_1 = __importDefault(require("./xray-error-response")); const xray_cloud_response_v2_1 = __importDefault(require("./xray-cloud-response-v2")); // import XrayCloudGraphQLResponseV2 from './xray-cloud-graphql-response-v2'; const xray_cloud_graphql_error_response_1 = __importDefault(require("./xray-cloud-graphql-error-response")); const index_1 = require("./index"); const xrayCloudBaseUrl = "https://xray.cloud.getxray.app/api/v2"; const authenticateUrl = xrayCloudBaseUrl + "/authenticate"; class XrayCloudClient { constructor(xraySettings) { this.supportedFormats = [ index_1.XRAY_FORMAT, index_1.JUNIT_FORMAT, index_1.TESTNG_FORMAT, index_1.ROBOT_FORMAT, index_1.NUNIT_FORMAT, index_1.XUNIT_FORMAT, index_1.CUCUMBER_FORMAT, index_1.BEHAVE_FORMAT, ]; this.clientId = xraySettings.clientId; this.clientSecret = xraySettings.clientSecret; if (xraySettings.timeout !== undefined) this.timeout = xraySettings.timeout; else this.timeout = 50000; axios_1.default.defaults.timeout = this.timeout; } async submitResults(reportPath, config) { if (config.format === undefined) throw new xray_error_response_1.default("ERROR: format must be specified"); if (!this.supportedFormats.includes(config.format)) throw new xray_error_response_1.default("ERROR: unsupported format " + config.format); let reportContent; try { reportContent = fs_1.default.readFileSync(reportPath).toString(); } catch (error) { throw new xray_error_response_1.default(error.message); } // use a CancelToken as the timeout setting is not reliable const cancelTokenSource = axios_1.default.CancelToken.source(); const timeoutFn = setTimeout(() => { cancelTokenSource.cancel("request timeout"); }, this.timeout); return axios_1.default .post(authenticateUrl, { client_id: this.clientId, client_secret: this.clientSecret }, { timeout: this.timeout, cancelToken: cancelTokenSource.token, }) .then((response) => { const authToken = response.data; return authToken; }) .then((authToken) => { let endpointUrl; if (config.format === index_1.XRAY_FORMAT) { endpointUrl = xrayCloudBaseUrl + "/import/execution"; } else { endpointUrl = xrayCloudBaseUrl + "/import/execution/" + config.format; } const params = {}; let url = endpointUrl; // all formats support GET parameters, except for xray and cucumber if (![index_1.XRAY_FORMAT, index_1.CUCUMBER_FORMAT, index_1.BEHAVE_FORMAT].includes(config.format)) { if (config.projectKey === undefined && config.testExecKey === undefined) { throw new xray_error_response_1.default("ERROR: projectKey or testExecKey must be defined"); } if (config.projectKey !== undefined) { params.projectKey = config.projectKey; } if (config.testPlanKey !== undefined) { params.testPlanKey = config.testPlanKey; } if (config.testExecKey !== undefined) { params.testExecKey = config.testExecKey; } if (config.version !== undefined) { params.fixVersion = config.version; } if (config.revision !== undefined) { params.revision = config.revision; } if (config.testEnvironment !== undefined) { params.testEnvironments = config.testEnvironment; } if (config.testEnvironments !== undefined) { params.testEnvironments = config.testEnvironments.join(";"); } const urlParams = new URLSearchParams({ ...params }).toString(); url = endpointUrl + "?" + urlParams; } let contentType; if ([ index_1.JUNIT_FORMAT, index_1.TESTNG_FORMAT, index_1.NUNIT_FORMAT, index_1.XUNIT_FORMAT, index_1.ROBOT_FORMAT, ].includes(config.format)) { contentType = "application/xml"; } else { contentType = "application/json"; } return axios_1.default.post(url, reportContent, { timeout: this.timeout, cancelToken: cancelTokenSource.token, headers: { Authorization: "Bearer " + authToken, "Content-Type": contentType, }, }); }) .then((response) => { clearTimeout(timeoutFn); return new xray_cloud_response_v2_1.default(response); }) .catch((error) => { if (error.response !== undefined) throw new xray_error_response_1.default(error.response); else throw new xray_error_response_1.default(error.message || error._response); }); } async submitResultsMultipart(reportPath, config) { if (config.format === undefined) throw new xray_error_response_1.default("ERROR: format must be specified"); if (!this.supportedFormats.includes(config.format)) throw new xray_error_response_1.default("ERROR: unsupported format " + config.format); if (config.testExecInfoFile === undefined && config.testExecInfo === undefined) throw new xray_error_response_1.default("ERROR: testExecInfoFile or testExecInfo must be defined"); // use a CancelToken as the timeout setting is not reliable const cancelTokenSource = axios_1.default.CancelToken.source(); const timeoutFn = setTimeout(() => { cancelTokenSource.cancel("request timeout"); }, this.timeout); return axios_1.default .post(authenticateUrl, { client_id: this.clientId, client_secret: this.clientSecret }, { timeout: this.timeout, cancelToken: cancelTokenSource.token, }) .then((response) => { // clearTimeout(timeoutFn); const authToken = response.data; return authToken; }) .then((authToken) => { let endpointUrl; if (config.format === index_1.XRAY_FORMAT) { endpointUrl = xrayCloudBaseUrl + "/import/execution/multipart"; } else { endpointUrl = xrayCloudBaseUrl + "/import/execution/" + config.format + "/multipart"; } let reportContent; let testInfoContent; let testExecInfoContent; try { reportContent = fs_1.default.readFileSync(reportPath).toString(); if (config.testInfoFile !== undefined) testInfoContent = fs_1.default.readFileSync(config.testInfoFile).toString(); if (config.testInfo !== undefined) testInfoContent = config.testInfo.toString(); if (config.testExecInfoFile !== undefined) testExecInfoContent = fs_1.default .readFileSync(config.testExecInfoFile) .toString(); else testExecInfoContent = config.testExecInfo.toString(); } catch (error) { throw new xray_error_response_1.default(error.message); } const bodyFormData = new form_data_1.default(); let fileName; if ([ index_1.JUNIT_FORMAT, index_1.TESTNG_FORMAT, index_1.NUNIT_FORMAT, index_1.XUNIT_FORMAT, index_1.ROBOT_FORMAT, ].includes(config.format)) { fileName = "report.xml"; } else { fileName = "report.json"; } bodyFormData.append("results", reportContent, fileName); bodyFormData.append("info", testExecInfoContent, "info.json"); if (testInfoContent !== undefined && [ index_1.JUNIT_FORMAT, index_1.TESTNG_FORMAT, index_1.NUNIT_FORMAT, index_1.XUNIT_FORMAT, index_1.ROBOT_FORMAT, ].includes(config.format)) bodyFormData.append("testInfo", testInfoContent, "testInfo.json"); return axios_1.default.post(endpointUrl, bodyFormData, { timeout: this.timeout, cancelToken: cancelTokenSource.token, headers: { Authorization: "Bearer " + authToken, ...bodyFormData.getHeaders(), }, }); }) .then((response) => { clearTimeout(timeoutFn); return new xray_cloud_response_v2_1.default(response); }) .catch((error) => { if (error.response !== undefined) throw new xray_error_response_1.default(error.response); else throw new xray_error_response_1.default(error.message || error._response); }); } async authenticate() { // use a CancelToken as the timeout setting is not reliable const cancelTokenSource = axios_1.default.CancelToken.source(); const timeoutFn = setTimeout(() => { cancelTokenSource.cancel("request timeout"); }, this.timeout); return axios_1.default .post(authenticateUrl, { client_id: this.clientId, client_secret: this.clientSecret }, { timeout: this.timeout, cancelToken: cancelTokenSource.token, }) .then((response) => { clearTimeout(timeoutFn); const authToken = response.data; return authToken; }); } async associateTestExecutionToTestPlanByIds(testExecIssueId, testPlanIssueId) { // use a CancelToken as the timeout setting is not reliable const cancelTokenSource = axios_1.default.CancelToken.source(); const timeoutFn = setTimeout(() => { cancelTokenSource.cancel("request timeout"); }, this.timeout); return axios_1.default .post(authenticateUrl, { client_id: this.clientId, client_secret: this.clientSecret }, { timeout: this.timeout, cancelToken: cancelTokenSource.token, }) .then((response) => { clearTimeout(timeoutFn); const authToken = response.data; return authToken; }) .then((authToken) => { const graphQLEndpoint = xrayCloudBaseUrl + "/graphql"; const graphQLClient = new graphql_request_1.GraphQLClient(graphQLEndpoint, { headers: { authorization: "Bearer " + authToken, }, }); const mutation = (0, graphql_request_1.gql) ` mutation { addTestExecutionsToTestPlan( issueId: "${testPlanIssueId}", testExecIssueIds: ["${testExecIssueId}"] ) { addedTestExecutions warning } } `; return graphQLClient.request(mutation); }) .then((response) => { return (response.data.addTestExecutionsToTestPlan.addedTestExecutions[0] || testExecIssueId); // return new XrayCloudGraphQLResponseV2(response, response.data.addTestExecutionsToTestPlan.addedTestExecutions[0] || testExecIssueId); }) .catch((error) => { const errorMessages = error.response.errors.map((err) => { return err.message; }); throw new xray_cloud_graphql_error_response_1.default(error, errorMessages); }); } async getTestPlanId(testPlanIssueKey) { return this.authenticate() .then((authToken) => { const graphQLEndpoint = xrayCloudBaseUrl + "/graphql"; const graphQLClient = new graphql_request_1.GraphQLClient(graphQLEndpoint, { headers: { authorization: "Bearer " + authToken, }, }); const query = (0, graphql_request_1.gql) ` { getTestPlans(jql: "key = ${testPlanIssueKey}", limit: 1) { total results { issueId } } } `; return graphQLClient.request(query); }) .then((response) => { return response.getTestPlans.results[0].issueId; }) .catch((error) => { const errorMessages = error.response.errors.map((err) => { return err.message; }); throw new xray_cloud_graphql_error_response_1.default(error, errorMessages); }); } } exports.XrayCloudClient = XrayCloudClient; exports.default = XrayCloudClient;