-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexecutionUploader.js
179 lines (156 loc) · 8.39 KB
/
executionUploader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env node
import chalk from "chalk";
import boxen from "boxen";
import yargs from 'yargs'
import {JiraRestClient} from "./clients/jira_rest_client.js";
import {XrayGraphqlClient} from "./clients/xray_graphql_client.js";
import {XrayRestClient} from "./clients/xray_rest_client.js";
import {InputError} from "./errors/input_error.js";
import {XrayWorker} from "./workers/xray_worker.js";
import {Worker} from "./workers/worker.js";
const options = yargs
.option("xu", { alias: "xrayUrl", describe: "Xray Url", type: "string", demandOption: true })
.option("ci", { alias: "clientId", describe: "Client Id", type: "string", demandOption: true })
.option("cs", { alias: "clientSecret", describe: "Client secret", type: "string", demandOption: true })
.option("ju", { alias: "jiraUrl", describe: "Jira Url in case you want to link executions to jira issues", type: "string", demandOption: true })
.option("jbt", { alias: "jiraBasicToken", describe: "Jira Token (PAT) in case you want to link executions to jira issues", type: "string", demandOption: true })
.option("tt", { alias: "testType", describe: "Test type cucumber-specflow | allure-xml | cucumber-json | allure-json", type: "string", demandOption: true })
.option("f", { alias: "filePath", describe: "File path", type: "string", demandOption: true })
.option("pk", { alias: "projectKey", describe: "Project Key", type: "string", demandOption: true })
.option("ek", { alias: "executionKey", describe: "Execution Key, if not passed will create a new execution under test plan", type: "string", demandOption: false })
.option("pn", { alias: "planKey", describe: "Plan Key where the test execution will be linked", type: "string", demandOption: false })
.option("s", { alias: "summary", describe: "Test Execution Summary, if none provided will generate one automatically", type: "string", demandOption: false })
.option("d", { alias: "description", describe: "Test Execution Description, if none provided will generate one automatically", type: "string", demandOption: false })
.option("rv", { alias: "releaseVersion", describe: "Release version which this test execution is linked", type: "string", demandOption: false })
.option("i", { alias: "issueKey", describe: "Issue to be linked to executions, needs issueLinkType", type: "string", demandOption: false })
.option("ilt", { alias: "issueLinkType", describe: "Linking type between your execution and the issue", type: "string", demandOption: false })
.option("e", { alias: "environments", describe: "Xray test enviroment variable", type: "string", demandOption: false })
.option("jcf", { alias: "jiraCustomFields", describe: "Custom fields added to test case ticket, can be multiple passed like '$id,$value", type: "string", demandOption: false })
.argv;
const optionsText = chalk.white.bold(
`
Xray Url: ${options.xrayUrl}, \n
ClientID: ${options.clientId}, \n
ClientSecret: ************, \n
Jira Url: ${options.jiraUrl} \n
Jira Basic Token: ************ \n
Test type: ${options.testType}, \n
Path: ${options.filePath}, \n
Project Key: ${options.projectKey} \n
Execution Key: ${options.executionKey} \n
Plan Key: ${options.planKey} \n
Summary: ${options.summary} \n
Description: ${options.description} \n
Release version: ${options.releaseVersion} \n
Issue Key: ${options.issueKey} \n
Issue Key Link type: ${options.issueLinkType} \n
Environments: ${options.environments} \n
Jira Custom Fields: ${options.jiraCustomFields}
`);
const greenBox = {
padding: 1,
margin: 1,
borderStyle: "round",
borderColor: "green",
backgroundColor: "#555555"
};
const optionsSummary = boxen( optionsText, greenBox );
console.log(optionsSummary);
uploadExecution(options);
async function uploadExecution(options) {
const xrayWorker = new XrayWorker();
const restXrayClient = new XrayRestClient(options.xrayUrl + '/api/v2');
const jiraRestClient = new JiraRestClient(options.jiraUrl, options.jiraBasicToken);
await restXrayClient.login(options.clientId, options.clientSecret);
const graphqlXrayClient = new XrayGraphqlClient(options.xrayUrl + '/api/v2/graphql', await restXrayClient.getAuthToken())
let xrayBody;
switch(options.testType.toLowerCase()) {
case "cucumber-specflow":
console.log('Uploading specflow cucumber execution');
options.testType = 'Cucumber';
xrayBody = await xrayWorker.generateXrayJsonFromSpecflowResults(options);
break;
case "junit-xml":
console.log('Uploading allure xml execution');
options.testType = 'Manual';
xrayBody = await xrayWorker.generateXrayJsonFromJunitXmlResults(options);
break;
case "allure-xml":
console.log('Uploading allure xml execution');
options.testType = 'Manual';
xrayBody = await xrayWorker.generateXrayJsonFromAllureXmlResults(options);
break;
case "cucumber-json":
console.log('Uploading cucumber-json execution');
options.testType = 'Manual';
xrayBody = await xrayWorker.generateXrayJsonFromCucumberJsonResults(options);
break;
case "allure-json":
console.log('Uploading allure json execution');
options.testType = 'Manual';
xrayBody = await xrayWorker.generateXrayRequestFromAllureJson(options);
break;
default:
throw new InputError('Check test type input, options available are cucumber-specflow | allure-xml | cucumber-json | allure-xml | junit-xml');
}
let executionKey;
if(xrayBody.tests.length === 0) {
console.log('No tests were found to upload');
process.exit();
}
if(xrayBody.tests.length > 50) {
const worker = new Worker();
let testsArray = await worker.splitArray(xrayBody.tests, 50);
let initXrayBody = { tests: testsArray[0]}
if(xrayBody.testExecutionKey !== undefined) initXrayBody['testExecutionKey'] = xrayBody.testExecutionKey;
if(xrayBody.info !== undefined) initXrayBody['info'] = xrayBody.info;
let response = await restXrayClient.sendResultsAsXrayJson(initXrayBody)
executionKey = response.data.key;
testsArray.shift();
for (const testsTranche of testsArray) {
let body = {
tests: testsTranche,
testExecutionKey: executionKey
}
if(xrayBody.info !== undefined) body['info'] = xrayBody.info;
await restXrayClient.sendResultsAsXrayJson(body);
await new Promise(resolve => setTimeout(resolve, 3000));
}
} else {
let response = await restXrayClient.sendResultsAsXrayJson(xrayBody)
executionKey = response.data.key;
}
if(options.issueKey) {
if(options.jiraBasicToken == undefined) {
throw new InputError('You are passing a jira issue to link but no authorization token');
}
if(options.jiraUrl == undefined) {
console.log('You are passing a jira issue to link but no jira url');
}
if(options.issueLinkType == undefined) {
console.log('You are passing a jira issue to link but no the type of linking');
}
try{
await jiraRestClient.mapExecutionToIssue(options, executionKey);
console.log('Execution mapped correctly to issue');
} catch(error) {
console.log('Was not possible to map execution key to ticket being tested')
}
}
if(options.jiraCustomFields) {
try{
let issueKeys = await graphqlXrayClient.getTestsByTestPlanKey(options.planKey)
var customFields = options.jiraCustomFields.replace(/\s/g, "").split(',');
for (let index = 0; index < issueKeys.length; index++) {
try{
const element = issueKeys[index];
await jiraRestClient.addValueToCustomField(customFields[0], customFields[1], element);
} catch(error) {
console.log(`Was not possible to add jira custom field ${customFields[0]} to test ${element}, because error: ` + error.message)
}
}
} catch(error) {
console.log('Was not possible to add jira custom fields to tests in plan, because error: ' + error.message);
}
}
}