qase-javascript-commons 2.6.3 → 2.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/clientV1.d.ts +6 -83
- package/dist/client/clientV1.js +15 -549
- package/dist/client/clientV2.d.ts +6 -24
- package/dist/client/clientV2.js +8 -255
- package/dist/client/services/api-error-handler.d.ts +10 -0
- package/dist/client/services/api-error-handler.js +44 -0
- package/dist/client/services/attachment-service.d.ts +16 -0
- package/dist/client/services/attachment-service.js +209 -0
- package/dist/client/services/configuration-service.d.ts +12 -0
- package/dist/client/services/configuration-service.js +110 -0
- package/dist/client/services/result-transformer.d.ts +23 -0
- package/dist/client/services/result-transformer.js +188 -0
- package/dist/client/services/run-service.d.ts +17 -0
- package/dist/client/services/run-service.js +114 -0
- package/dist/client/transport/api-config-builder.d.ts +8 -0
- package/dist/client/transport/api-config-builder.js +96 -0
- package/package.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigurationService = void 0;
|
|
4
|
+
const api_error_handler_1 = require("./api-error-handler");
|
|
5
|
+
class ConfigurationService {
|
|
6
|
+
logger;
|
|
7
|
+
configurationClient;
|
|
8
|
+
constructor(logger, configurationClient) {
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
this.configurationClient = configurationClient;
|
|
11
|
+
}
|
|
12
|
+
async handleConfigurations(projectCode, configurations) {
|
|
13
|
+
if (!configurations.values.length) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const configurationIds = [];
|
|
17
|
+
try {
|
|
18
|
+
const existingGroups = await this.getConfigurations(projectCode);
|
|
19
|
+
for (const configValue of configurations.values) {
|
|
20
|
+
const { name: groupName, value: configName } = configValue;
|
|
21
|
+
const group = existingGroups.find(g => g.title === groupName);
|
|
22
|
+
let groupId;
|
|
23
|
+
if (group) {
|
|
24
|
+
groupId = group.id;
|
|
25
|
+
this.logger.logDebug(`Found existing configuration group: ${groupName}`);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
if (configurations.createIfNotExists) {
|
|
29
|
+
const newGroupId = await this.createConfigurationGroup(projectCode, groupName);
|
|
30
|
+
if (newGroupId) {
|
|
31
|
+
groupId = newGroupId;
|
|
32
|
+
this.logger.logDebug(`Created new configuration group: ${groupName} with ID: ${groupId}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.logger.logDebug(`Failed to create configuration group: ${groupName}, skipping`);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.logger.logDebug(`Configuration group not found: ${groupName}, skipping`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (groupId) {
|
|
45
|
+
const existingConfig = group?.configurations.find(c => c.title === configName);
|
|
46
|
+
if (!existingConfig) {
|
|
47
|
+
if (configurations.createIfNotExists) {
|
|
48
|
+
const configId = await this.createConfiguration(projectCode, configName, groupId);
|
|
49
|
+
if (configId) {
|
|
50
|
+
configurationIds.push(configId);
|
|
51
|
+
}
|
|
52
|
+
this.logger.logDebug(`Created configuration: ${configName} in group: ${groupName}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
this.logger.logDebug(`Configuration not found: ${configName} in group: ${groupName}, skipping`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
if (existingConfig.id) {
|
|
60
|
+
configurationIds.push(existingConfig.id);
|
|
61
|
+
}
|
|
62
|
+
this.logger.logDebug(`Configuration already exists: ${configName} in group: ${groupName}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.logger.logError('Error handling configurations:', error);
|
|
69
|
+
}
|
|
70
|
+
return configurationIds;
|
|
71
|
+
}
|
|
72
|
+
async getConfigurations(projectCode) {
|
|
73
|
+
try {
|
|
74
|
+
const { data } = await this.configurationClient.getConfigurations(projectCode);
|
|
75
|
+
const entities = data.result?.entities ?? [];
|
|
76
|
+
return entities.map(group => ({
|
|
77
|
+
id: group.id ?? 0,
|
|
78
|
+
title: group.title ?? '',
|
|
79
|
+
configurations: group.configurations?.map(config => ({
|
|
80
|
+
id: config.id ?? 0,
|
|
81
|
+
title: config.title ?? '',
|
|
82
|
+
})) ?? [],
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
throw (0, api_error_handler_1.processError)(error, 'Error getting configurations');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async createConfigurationGroup(projectCode, title) {
|
|
90
|
+
try {
|
|
91
|
+
const group = { title };
|
|
92
|
+
const { data } = await this.configurationClient.createConfigurationGroup(projectCode, group);
|
|
93
|
+
return data.result?.id;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw (0, api_error_handler_1.processError)(error, 'Error creating configuration group');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async createConfiguration(projectCode, title, groupId) {
|
|
100
|
+
try {
|
|
101
|
+
const config = { title, group_id: groupId };
|
|
102
|
+
const { data } = await this.configurationClient.createConfiguration(projectCode, config);
|
|
103
|
+
return data.result?.id;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
throw (0, api_error_handler_1.processError)(error, 'Error creating configuration');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.ConfigurationService = ConfigurationService;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ResultCreate } from 'qase-api-v2-client';
|
|
2
|
+
import { Attachment, TestResultType } from '../../models';
|
|
3
|
+
import { LoggerInterface } from '../../utils/logger';
|
|
4
|
+
export declare class ResultTransformer {
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private readonly rootSuite;
|
|
7
|
+
constructor(logger: LoggerInterface, rootSuite: string | undefined);
|
|
8
|
+
transform(result: TestResultType, attachmentUploader: (attachment: Attachment) => Promise<string>): Promise<ResultCreate>;
|
|
9
|
+
transformWithDefect(result: TestResultType, attachmentUploader: (attachment: Attachment) => Promise<string>, defect: boolean): Promise<ResultCreate>;
|
|
10
|
+
private uploadAttachments;
|
|
11
|
+
private transformSteps;
|
|
12
|
+
private transformStep;
|
|
13
|
+
private createBaseResultStep;
|
|
14
|
+
private processTextStep;
|
|
15
|
+
private processGherkinStep;
|
|
16
|
+
private processRequestStep;
|
|
17
|
+
private getExecution;
|
|
18
|
+
private transformParams;
|
|
19
|
+
private transformGroupParams;
|
|
20
|
+
private getRelation;
|
|
21
|
+
private getDefaultSuiteRelation;
|
|
22
|
+
private buildSuiteData;
|
|
23
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ResultTransformer = void 0;
|
|
7
|
+
const qase_api_v2_client_1 = require("qase-api-v2-client");
|
|
8
|
+
const models_1 = require("../../models");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const statusMap = {
|
|
11
|
+
[models_1.TestStatusEnum.passed]: 'passed',
|
|
12
|
+
[models_1.TestStatusEnum.failed]: 'failed',
|
|
13
|
+
[models_1.TestStatusEnum.skipped]: 'skipped',
|
|
14
|
+
[models_1.TestStatusEnum.disabled]: 'skipped',
|
|
15
|
+
[models_1.TestStatusEnum.blocked]: 'blocked',
|
|
16
|
+
[models_1.TestStatusEnum.invalid]: 'invalid',
|
|
17
|
+
};
|
|
18
|
+
const stepStatusMap = {
|
|
19
|
+
[models_1.StepStatusEnum.passed]: qase_api_v2_client_1.ResultStepStatus.PASSED,
|
|
20
|
+
[models_1.StepStatusEnum.failed]: qase_api_v2_client_1.ResultStepStatus.FAILED,
|
|
21
|
+
[models_1.StepStatusEnum.blocked]: qase_api_v2_client_1.ResultStepStatus.BLOCKED,
|
|
22
|
+
[models_1.StepStatusEnum.skipped]: qase_api_v2_client_1.ResultStepStatus.SKIPPED,
|
|
23
|
+
};
|
|
24
|
+
class ResultTransformer {
|
|
25
|
+
logger;
|
|
26
|
+
rootSuite;
|
|
27
|
+
constructor(logger, rootSuite) {
|
|
28
|
+
this.logger = logger;
|
|
29
|
+
this.rootSuite = rootSuite;
|
|
30
|
+
}
|
|
31
|
+
async transform(result, attachmentUploader) {
|
|
32
|
+
const attachments = await this.uploadAttachments(result.attachments, attachmentUploader);
|
|
33
|
+
if (result.preparedAttachments) {
|
|
34
|
+
attachments.push(...result.preparedAttachments);
|
|
35
|
+
}
|
|
36
|
+
const steps = await this.transformSteps(result.steps, result.title, attachmentUploader);
|
|
37
|
+
const params = this.transformParams(result.params);
|
|
38
|
+
const groupParams = this.transformGroupParams(result.group_params, params);
|
|
39
|
+
const relations = this.getRelation(result.relations);
|
|
40
|
+
const model = {
|
|
41
|
+
title: result.title,
|
|
42
|
+
execution: this.getExecution(result.execution),
|
|
43
|
+
testops_ids: Array.isArray(result.testops_id)
|
|
44
|
+
? result.testops_id
|
|
45
|
+
: result.testops_id !== null ? [result.testops_id] : null,
|
|
46
|
+
attachments: attachments,
|
|
47
|
+
steps: steps,
|
|
48
|
+
params: params,
|
|
49
|
+
param_groups: groupParams,
|
|
50
|
+
relations: relations,
|
|
51
|
+
message: result.message,
|
|
52
|
+
fields: result.fields,
|
|
53
|
+
defect: false,
|
|
54
|
+
signature: result.signature,
|
|
55
|
+
};
|
|
56
|
+
if (result.tags.length > 0) {
|
|
57
|
+
model.fields = {
|
|
58
|
+
...model.fields,
|
|
59
|
+
tags: [...new Set(result.tags)].join(','),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
this.logger.logDebug(`Transformed result: ${JSON.stringify(model)}`);
|
|
63
|
+
return model;
|
|
64
|
+
}
|
|
65
|
+
async transformWithDefect(result, attachmentUploader, defect) {
|
|
66
|
+
const model = await this.transform(result, attachmentUploader);
|
|
67
|
+
model.defect = defect;
|
|
68
|
+
return model;
|
|
69
|
+
}
|
|
70
|
+
async uploadAttachments(attachments, uploader) {
|
|
71
|
+
const hashes = [];
|
|
72
|
+
for (const attachment of attachments) {
|
|
73
|
+
const hash = await uploader(attachment);
|
|
74
|
+
if (hash)
|
|
75
|
+
hashes.push(hash);
|
|
76
|
+
}
|
|
77
|
+
return hashes;
|
|
78
|
+
}
|
|
79
|
+
async transformSteps(steps, testTitle, attachmentUploader) {
|
|
80
|
+
return Promise.all(steps.map(step => this.transformStep(step, testTitle, attachmentUploader)));
|
|
81
|
+
}
|
|
82
|
+
async transformStep(step, testTitle, attachmentUploader) {
|
|
83
|
+
const attachmentHashes = await this.uploadAttachments(step.attachments, attachmentUploader);
|
|
84
|
+
const resultStep = this.createBaseResultStep(attachmentHashes, step.execution.status);
|
|
85
|
+
if (step.step_type === models_1.StepType.TEXT) {
|
|
86
|
+
this.processTextStep(step, resultStep, testTitle);
|
|
87
|
+
}
|
|
88
|
+
else if (step.step_type === models_1.StepType.GHERKIN) {
|
|
89
|
+
this.processGherkinStep(step, resultStep);
|
|
90
|
+
}
|
|
91
|
+
else if (step.step_type === models_1.StepType.REQUEST) {
|
|
92
|
+
this.processRequestStep(step, resultStep);
|
|
93
|
+
}
|
|
94
|
+
if (step.steps.length > 0) {
|
|
95
|
+
resultStep.steps = await this.transformSteps(step.steps, testTitle, attachmentUploader);
|
|
96
|
+
}
|
|
97
|
+
return resultStep;
|
|
98
|
+
}
|
|
99
|
+
createBaseResultStep(attachmentHashes, status) {
|
|
100
|
+
return {
|
|
101
|
+
data: { action: '' },
|
|
102
|
+
execution: {
|
|
103
|
+
status: stepStatusMap[status],
|
|
104
|
+
attachments: attachmentHashes,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
processTextStep(step, resultStep, testTitle) {
|
|
109
|
+
if (!('action' in step.data) || !resultStep.data)
|
|
110
|
+
return;
|
|
111
|
+
const stepData = step.data;
|
|
112
|
+
resultStep.data.action = stepData.action || 'Unnamed step';
|
|
113
|
+
if (stepData.action === '') {
|
|
114
|
+
this.logger.log((0, chalk_1.default) `{magenta Test '${testTitle}' has empty action in step. The reporter will mark this step as unnamed step.}`);
|
|
115
|
+
}
|
|
116
|
+
if (stepData.expected_result != null) {
|
|
117
|
+
resultStep.data.expected_result = stepData.expected_result;
|
|
118
|
+
}
|
|
119
|
+
if (stepData.data != null) {
|
|
120
|
+
resultStep.data.input_data = stepData.data;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
processGherkinStep(step, resultStep) {
|
|
124
|
+
if (!('keyword' in step.data) || !resultStep.data)
|
|
125
|
+
return;
|
|
126
|
+
resultStep.data.action = step.data.keyword;
|
|
127
|
+
}
|
|
128
|
+
processRequestStep(step, resultStep) {
|
|
129
|
+
if (!('request_method' in step.data) || !resultStep.data)
|
|
130
|
+
return;
|
|
131
|
+
const stepData = step.data;
|
|
132
|
+
resultStep.data.action = `${stepData.request_method} ${stepData.request_url}`;
|
|
133
|
+
}
|
|
134
|
+
getExecution(exec) {
|
|
135
|
+
return {
|
|
136
|
+
status: statusMap[exec.status],
|
|
137
|
+
start_time: exec.start_time,
|
|
138
|
+
end_time: exec.end_time,
|
|
139
|
+
duration: exec.duration,
|
|
140
|
+
stacktrace: exec.stacktrace,
|
|
141
|
+
thread: exec.thread,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
transformParams(params) {
|
|
145
|
+
const transformedParams = {};
|
|
146
|
+
for (const [key, value] of Object.entries(params)) {
|
|
147
|
+
if (value != null) {
|
|
148
|
+
transformedParams[key] = String(value);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return transformedParams;
|
|
152
|
+
}
|
|
153
|
+
transformGroupParams(groupParams, params) {
|
|
154
|
+
const keys = Object.keys(groupParams);
|
|
155
|
+
if (keys.length === 0)
|
|
156
|
+
return [];
|
|
157
|
+
for (const [key, value] of Object.entries(groupParams)) {
|
|
158
|
+
if (value) {
|
|
159
|
+
params[key] = value;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return [keys];
|
|
163
|
+
}
|
|
164
|
+
getRelation(relation) {
|
|
165
|
+
if (!relation?.suite) {
|
|
166
|
+
return this.getDefaultSuiteRelation();
|
|
167
|
+
}
|
|
168
|
+
const suiteData = this.buildSuiteData(relation.suite.data);
|
|
169
|
+
return { suite: { data: suiteData } };
|
|
170
|
+
}
|
|
171
|
+
getDefaultSuiteRelation() {
|
|
172
|
+
if (!this.rootSuite)
|
|
173
|
+
return {};
|
|
174
|
+
return {
|
|
175
|
+
suite: {
|
|
176
|
+
data: [{ public_id: null, title: this.rootSuite }],
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
buildSuiteData(suiteData) {
|
|
181
|
+
const result = [];
|
|
182
|
+
if (this.rootSuite) {
|
|
183
|
+
result.push({ public_id: null, title: this.rootSuite });
|
|
184
|
+
}
|
|
185
|
+
return result.concat(suiteData.map(data => ({ public_id: null, title: data.title })));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.ResultTransformer = ResultTransformer;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RunsApi, EnvironmentsApi } from 'qase-api-client';
|
|
2
|
+
import { TestOpsOptionsType } from '../../models/config/TestOpsOptionsType';
|
|
3
|
+
import { LoggerInterface } from '../../utils/logger';
|
|
4
|
+
import { ConfigurationService } from './configuration-service';
|
|
5
|
+
export declare class RunService {
|
|
6
|
+
private readonly logger;
|
|
7
|
+
private readonly runClient;
|
|
8
|
+
private readonly environmentClient;
|
|
9
|
+
private readonly configurationService;
|
|
10
|
+
private readonly appUrl;
|
|
11
|
+
constructor(logger: LoggerInterface, runClient: RunsApi, environmentClient: EnvironmentsApi, configurationService: ConfigurationService, appUrl: string | undefined);
|
|
12
|
+
createRun(config: TestOpsOptionsType, environment?: string): Promise<number>;
|
|
13
|
+
completeRun(runId: number, config: TestOpsOptionsType): Promise<void>;
|
|
14
|
+
enablePublicReport(projectCode: string, runId: number): Promise<void>;
|
|
15
|
+
private getEnvironmentId;
|
|
16
|
+
private prepareRunObject;
|
|
17
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RunService = void 0;
|
|
7
|
+
const qase_api_client_1 = require("qase-api-client");
|
|
8
|
+
const qase_error_1 = require("../../utils/qase-error");
|
|
9
|
+
const dateUtils_1 = require("../dateUtils");
|
|
10
|
+
const api_error_handler_1 = require("./api-error-handler");
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
class RunService {
|
|
13
|
+
logger;
|
|
14
|
+
runClient;
|
|
15
|
+
environmentClient;
|
|
16
|
+
configurationService;
|
|
17
|
+
appUrl;
|
|
18
|
+
constructor(logger, runClient, environmentClient, configurationService, appUrl) {
|
|
19
|
+
this.logger = logger;
|
|
20
|
+
this.runClient = runClient;
|
|
21
|
+
this.environmentClient = environmentClient;
|
|
22
|
+
this.configurationService = configurationService;
|
|
23
|
+
this.appUrl = appUrl;
|
|
24
|
+
}
|
|
25
|
+
async createRun(config, environment) {
|
|
26
|
+
if (config.run.id) {
|
|
27
|
+
return config.run.id;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
let configurationIds = [];
|
|
31
|
+
if (config.configurations) {
|
|
32
|
+
configurationIds = await this.configurationService.handleConfigurations(config.project, config.configurations);
|
|
33
|
+
}
|
|
34
|
+
const environmentId = await this.getEnvironmentId(config.project, environment);
|
|
35
|
+
const runObject = this.prepareRunObject(config, environmentId, configurationIds);
|
|
36
|
+
this.logger.logDebug(`Creating test run: ${JSON.stringify(runObject)}`);
|
|
37
|
+
const { data } = await this.runClient.createRun(config.project, runObject);
|
|
38
|
+
if (!data.result?.id) {
|
|
39
|
+
throw new qase_error_1.QaseError('Failed to create test run');
|
|
40
|
+
}
|
|
41
|
+
this.logger.logDebug(`Test run created: ${JSON.stringify(data)}`);
|
|
42
|
+
if (config.run.externalLink && data.result.id) {
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
44
|
+
const apiType = config.run.externalLink.type === 'jiraCloud'
|
|
45
|
+
? qase_api_client_1.RunExternalIssuesTypeEnum.JIRA_CLOUD
|
|
46
|
+
: qase_api_client_1.RunExternalIssuesTypeEnum.JIRA_SERVER;
|
|
47
|
+
await this.runClient.runUpdateExternalIssue(config.project, {
|
|
48
|
+
type: apiType,
|
|
49
|
+
links: [{
|
|
50
|
+
run_id: data.result.id,
|
|
51
|
+
external_issue: config.run.externalLink.link,
|
|
52
|
+
}],
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return data.result.id;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
throw (0, api_error_handler_1.processError)(error, 'Error creating test run');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async completeRun(runId, config) {
|
|
62
|
+
if (!config.run.complete) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
await this.runClient.completeRun(config.project, runId);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw (0, api_error_handler_1.processError)(error, 'Error on completing run');
|
|
70
|
+
}
|
|
71
|
+
if (this.appUrl) {
|
|
72
|
+
const runUrl = `${this.appUrl}/run/${config.project}/dashboard/${runId}`;
|
|
73
|
+
this.logger.log((0, chalk_1.default) `{blue Test run link: ${runUrl}}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async enablePublicReport(projectCode, runId) {
|
|
77
|
+
try {
|
|
78
|
+
const { data } = await this.runClient.updateRunPublicity(projectCode, runId, { status: true });
|
|
79
|
+
if (data.result?.url) {
|
|
80
|
+
this.logger.log((0, chalk_1.default) `{blue Public report link: ${data.result.url}}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
this.logger.log((0, chalk_1.default) `{yellow Failed to generate public report link: ${(0, api_error_handler_1.getErrorMessage)(error)}}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async getEnvironmentId(projectCode, environment) {
|
|
88
|
+
if (!environment)
|
|
89
|
+
return undefined;
|
|
90
|
+
const { data } = await this.environmentClient.getEnvironments(projectCode, undefined, environment, 100);
|
|
91
|
+
return data.result?.entities?.find((env) => env.slug === environment)?.id;
|
|
92
|
+
}
|
|
93
|
+
prepareRunObject(config, environmentId, configurationIds) {
|
|
94
|
+
const runObject = {
|
|
95
|
+
title: config.run.title ?? `Automated run ${new Date().toISOString()}`,
|
|
96
|
+
description: config.run.description ?? '',
|
|
97
|
+
is_autotest: true,
|
|
98
|
+
cases: [],
|
|
99
|
+
start_time: (0, dateUtils_1.getStartTime)(),
|
|
100
|
+
tags: config.run.tags ?? [],
|
|
101
|
+
};
|
|
102
|
+
if (environmentId !== undefined) {
|
|
103
|
+
runObject.environment_id = environmentId;
|
|
104
|
+
}
|
|
105
|
+
if (config.plan.id) {
|
|
106
|
+
runObject.plan_id = config.plan.id;
|
|
107
|
+
}
|
|
108
|
+
if (configurationIds && configurationIds.length > 0) {
|
|
109
|
+
runObject.configurations = configurationIds;
|
|
110
|
+
}
|
|
111
|
+
return runObject;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.RunService = RunService;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Configuration as ConfigurationV1 } from 'qase-api-client';
|
|
2
|
+
import { Configuration as ConfigurationV2 } from 'qase-api-v2-client';
|
|
3
|
+
import { TestOpsOptionsType } from '../../models/config/TestOpsOptionsType';
|
|
4
|
+
import { HostData } from '../../models/host-data';
|
|
5
|
+
export declare function resolveAppUrl(config: TestOpsOptionsType): string;
|
|
6
|
+
export declare function createApiConfigV1(config: TestOpsOptionsType): ConfigurationV1;
|
|
7
|
+
export declare function createApiConfigV2(config: TestOpsOptionsType, hostData?: HostData, reporterName?: string, frameworkName?: string): ConfigurationV2;
|
|
8
|
+
export declare function buildHeaders(hostData: HostData, reporterName?: string, frameworkName?: string): Record<string, string>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveAppUrl = resolveAppUrl;
|
|
7
|
+
exports.createApiConfigV1 = createApiConfigV1;
|
|
8
|
+
exports.createApiConfigV2 = createApiConfigV2;
|
|
9
|
+
exports.buildHeaders = buildHeaders;
|
|
10
|
+
const qase_api_client_1 = require("qase-api-client");
|
|
11
|
+
const qase_api_v2_client_1 = require("qase-api-v2-client");
|
|
12
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
13
|
+
const DEFAULT_API_HOST = 'qase.io';
|
|
14
|
+
const API_BASE_URL = 'https://api-';
|
|
15
|
+
const APP_BASE_URL = 'https://';
|
|
16
|
+
const API_V1 = '/v1';
|
|
17
|
+
const API_V2 = '/v2';
|
|
18
|
+
function resolveBasePath(host, version) {
|
|
19
|
+
if (host && host !== DEFAULT_API_HOST) {
|
|
20
|
+
return `${API_BASE_URL}${host}${version}`;
|
|
21
|
+
}
|
|
22
|
+
return `https://api.${DEFAULT_API_HOST}${version}`;
|
|
23
|
+
}
|
|
24
|
+
function resolveAppUrl(config) {
|
|
25
|
+
if (config.api.host && config.api.host !== DEFAULT_API_HOST) {
|
|
26
|
+
return `${APP_BASE_URL}${config.api.host}`;
|
|
27
|
+
}
|
|
28
|
+
return `https://app.${DEFAULT_API_HOST}`;
|
|
29
|
+
}
|
|
30
|
+
function createApiConfigV1(config) {
|
|
31
|
+
const apiConfig = new qase_api_client_1.Configuration({ apiKey: config.api.token, formDataCtor: form_data_1.default });
|
|
32
|
+
apiConfig.basePath = resolveBasePath(config.api.host, API_V1);
|
|
33
|
+
return apiConfig;
|
|
34
|
+
}
|
|
35
|
+
function createApiConfigV2(config, hostData, reporterName, frameworkName) {
|
|
36
|
+
const apiConfig = new qase_api_v2_client_1.Configuration({ apiKey: config.api.token, formDataCtor: form_data_1.default });
|
|
37
|
+
apiConfig.basePath = resolveBasePath(config.api.host, API_V2);
|
|
38
|
+
if (hostData) {
|
|
39
|
+
const headers = buildHeaders(hostData, reporterName, frameworkName);
|
|
40
|
+
const existingHeaders = apiConfig.baseOptions?.headers ?? {};
|
|
41
|
+
const baseOptionsWithHeaders = {
|
|
42
|
+
...(apiConfig.baseOptions ?? {}),
|
|
43
|
+
headers: {
|
|
44
|
+
...existingHeaders,
|
|
45
|
+
...headers,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
apiConfig.baseOptions = baseOptionsWithHeaders;
|
|
49
|
+
}
|
|
50
|
+
return apiConfig;
|
|
51
|
+
}
|
|
52
|
+
function buildHeaders(hostData, reporterName, frameworkName) {
|
|
53
|
+
const headers = {};
|
|
54
|
+
const clientParts = [];
|
|
55
|
+
if (reporterName?.trim()) {
|
|
56
|
+
clientParts.push(`reporter=${reporterName}`);
|
|
57
|
+
}
|
|
58
|
+
if (hostData.reporter?.trim()) {
|
|
59
|
+
clientParts.push(`reporter_version=${hostData.reporter}`);
|
|
60
|
+
}
|
|
61
|
+
if (frameworkName?.trim()) {
|
|
62
|
+
clientParts.push(`framework=${frameworkName}`);
|
|
63
|
+
}
|
|
64
|
+
if (hostData.framework?.trim()) {
|
|
65
|
+
clientParts.push(`framework_version=${hostData.framework}`);
|
|
66
|
+
}
|
|
67
|
+
if (hostData.apiClientV1?.trim()) {
|
|
68
|
+
clientParts.push(`client_version_v1=${hostData.apiClientV1}`);
|
|
69
|
+
}
|
|
70
|
+
if (hostData.apiClientV2?.trim()) {
|
|
71
|
+
clientParts.push(`client_version_v2=${hostData.apiClientV2}`);
|
|
72
|
+
}
|
|
73
|
+
if (hostData.commons?.trim()) {
|
|
74
|
+
clientParts.push(`core_version=${hostData.commons}`);
|
|
75
|
+
}
|
|
76
|
+
if (clientParts.length > 0) {
|
|
77
|
+
headers['X-Client'] = clientParts.join(';');
|
|
78
|
+
}
|
|
79
|
+
const platformParts = [];
|
|
80
|
+
if (hostData.system?.trim()) {
|
|
81
|
+
platformParts.push(`os=${hostData.system}`);
|
|
82
|
+
}
|
|
83
|
+
if (hostData.arch?.trim()) {
|
|
84
|
+
platformParts.push(`arch=${hostData.arch}`);
|
|
85
|
+
}
|
|
86
|
+
if (hostData.language?.trim()) {
|
|
87
|
+
platformParts.push(`node=${hostData.language}`);
|
|
88
|
+
}
|
|
89
|
+
if (hostData.packageManager?.trim()) {
|
|
90
|
+
platformParts.push(`npm=${hostData.packageManager}`);
|
|
91
|
+
}
|
|
92
|
+
if (platformParts.length > 0) {
|
|
93
|
+
headers['X-Platform'] = platformParts.join(';');
|
|
94
|
+
}
|
|
95
|
+
return headers;
|
|
96
|
+
}
|