qase-javascript-commons 2.4.12 → 2.4.14
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/changelog.md +7 -0
- package/dist/client/clientV1.d.ts +15 -2
- package/dist/client/clientV1.js +142 -22
- package/dist/client/clientV2.d.ts +3 -1
- package/dist/client/clientV2.js +63 -3
- package/dist/models/index.d.ts +7 -5
- package/dist/qase.d.ts +1 -0
- package/dist/qase.js +4 -3
- package/package.json +3 -3
package/changelog.md
CHANGED
|
@@ -21,11 +21,19 @@ export declare class ClientV1 implements IClient {
|
|
|
21
21
|
private getErrorMessage;
|
|
22
22
|
uploadAttachment(attachment: Attachment): Promise<string>;
|
|
23
23
|
protected uploadAttachments(attachments: Attachment[]): Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Group attachments into batches respecting API limits:
|
|
26
|
+
* - Up to 20 files per batch
|
|
27
|
+
* - Up to 128 MB per batch
|
|
28
|
+
* @param attachments Array of attachments to group
|
|
29
|
+
* @returns Array of attachment batches
|
|
30
|
+
*/
|
|
31
|
+
private groupAttachmentsIntoBatches;
|
|
24
32
|
/**
|
|
25
33
|
* Upload attachment with retry logic for 429 errors
|
|
26
34
|
* @param project Project code
|
|
27
|
-
* @param data Attachment data
|
|
28
|
-
* @param
|
|
35
|
+
* @param data Attachment data array (can contain multiple files)
|
|
36
|
+
* @param attachmentNames Attachment names for logging (comma-separated for batches)
|
|
29
37
|
* @param maxRetries Maximum number of retry attempts
|
|
30
38
|
* @param initialDelay Initial delay in milliseconds
|
|
31
39
|
* @returns Promise with upload response
|
|
@@ -42,6 +50,11 @@ export declare class ClientV1 implements IClient {
|
|
|
42
50
|
* @param ms Milliseconds to delay
|
|
43
51
|
*/
|
|
44
52
|
private delay;
|
|
53
|
+
/**
|
|
54
|
+
* Ensure attachment size is calculated if not set or is 0
|
|
55
|
+
* @param attachment Attachment to ensure size for
|
|
56
|
+
*/
|
|
57
|
+
private ensureAttachmentSize;
|
|
45
58
|
private prepareAttachmentData;
|
|
46
59
|
private getEnvironmentId;
|
|
47
60
|
private prepareRunObject;
|
package/dist/client/clientV1.js
CHANGED
|
@@ -15,6 +15,10 @@ const DEFAULT_API_HOST = 'qase.io';
|
|
|
15
15
|
const API_BASE_URL = 'https://api-';
|
|
16
16
|
const APP_BASE_URL = 'https://';
|
|
17
17
|
const API_VERSION = '/v1';
|
|
18
|
+
// Attachment upload limits
|
|
19
|
+
const MAX_FILE_SIZE = 32 * 1024 * 1024; // 32 MB per file
|
|
20
|
+
const MAX_REQUEST_SIZE = 128 * 1024 * 1024; // 128 MB per request
|
|
21
|
+
const MAX_FILES_PER_REQUEST = 20; // 20 files per request
|
|
18
22
|
var ApiErrorCode;
|
|
19
23
|
(function (ApiErrorCode) {
|
|
20
24
|
ApiErrorCode[ApiErrorCode["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
|
|
@@ -145,32 +149,64 @@ class ClientV1 {
|
|
|
145
149
|
return [];
|
|
146
150
|
}
|
|
147
151
|
const uploadedHashes = [];
|
|
152
|
+
// Filter out invalid attachments and check file size limits
|
|
153
|
+
const validAttachments = [];
|
|
154
|
+
for (const attachment of attachments) {
|
|
155
|
+
if (!attachment) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
// Ensure attachment size is calculated if not set or is 0
|
|
159
|
+
this.ensureAttachmentSize(attachment);
|
|
160
|
+
// Skip attachments with unknown size (0)
|
|
161
|
+
if (attachment.size === 0) {
|
|
162
|
+
this.logger.logError(`Cannot determine size for attachment "${attachment.file_path ?? attachment.file_name}". Skipping.`);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
// Check if file exceeds maximum size per file (32 MB)
|
|
166
|
+
if (attachment.size > MAX_FILE_SIZE) {
|
|
167
|
+
this.logger.logError(`Attachment "${attachment.file_path ?? attachment.file_name}" exceeds maximum file size (32 MB). ` +
|
|
168
|
+
`File size: ${(attachment.size / (1024 * 1024)).toFixed(2)} MB. Skipping.`);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
validAttachments.push(attachment);
|
|
172
|
+
}
|
|
173
|
+
if (validAttachments.length === 0) {
|
|
174
|
+
return uploadedHashes;
|
|
175
|
+
}
|
|
148
176
|
// Add initial random delay to spread out requests from different workers/shard
|
|
149
177
|
// This helps prevent all workers from hitting the API at the same time
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
178
|
+
const initialJitter = Math.random() * 500; // 0-500ms random delay
|
|
179
|
+
await this.delay(initialJitter);
|
|
180
|
+
// Group attachments into batches that respect API limits
|
|
181
|
+
const batches = this.groupAttachmentsIntoBatches(validAttachments);
|
|
182
|
+
this.logger.logDebug(`Uploading ${validAttachments.length} attachments in ${batches.length} batch(es)`);
|
|
183
|
+
// Upload each batch
|
|
184
|
+
for (let i = 0; i < batches.length; i++) {
|
|
185
|
+
const batch = batches[i];
|
|
186
|
+
if (!batch || batch.length === 0) {
|
|
157
187
|
continue;
|
|
158
188
|
}
|
|
159
189
|
try {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
190
|
+
const batchNames = batch.map(a => a.file_path ?? a.file_name).join(', ');
|
|
191
|
+
this.logger.logDebug(`Uploading batch ${i + 1}/${batches.length} with ${batch.length} file(s): ${batchNames}`);
|
|
192
|
+
const batchData = batch.map(attachment => this.prepareAttachmentData(attachment));
|
|
193
|
+
const response = await this.uploadAttachmentWithRetry(this.config.project, batchData, batchNames);
|
|
194
|
+
// Extract all hashes from the response
|
|
195
|
+
if (response.data.result) {
|
|
196
|
+
for (const result of response.data.result) {
|
|
197
|
+
if (result.hash) {
|
|
198
|
+
uploadedHashes.push(result.hash);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
166
201
|
}
|
|
167
202
|
}
|
|
168
203
|
catch (error) {
|
|
169
|
-
this.logger.logError(
|
|
204
|
+
this.logger.logError(`Cannot upload batch ${i + 1}:`, error);
|
|
205
|
+
// Continue with next batch even if current batch fails
|
|
170
206
|
}
|
|
171
|
-
// Add delay between
|
|
172
|
-
// Skip delay after the last
|
|
173
|
-
if (i <
|
|
207
|
+
// Add delay between batches to avoid rate limiting
|
|
208
|
+
// Skip delay after the last batch
|
|
209
|
+
if (i < batches.length - 1) {
|
|
174
210
|
// Increased delay with random jitter to prevent synchronization
|
|
175
211
|
const baseDelay = 1000; // 1000ms (1 second) base delay
|
|
176
212
|
const jitter = Math.random() * 300; // 0-300ms random jitter
|
|
@@ -179,16 +215,56 @@ class ClientV1 {
|
|
|
179
215
|
}
|
|
180
216
|
return uploadedHashes;
|
|
181
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Group attachments into batches respecting API limits:
|
|
220
|
+
* - Up to 20 files per batch
|
|
221
|
+
* - Up to 128 MB per batch
|
|
222
|
+
* @param attachments Array of attachments to group
|
|
223
|
+
* @returns Array of attachment batches
|
|
224
|
+
*/
|
|
225
|
+
groupAttachmentsIntoBatches(attachments) {
|
|
226
|
+
const batches = [];
|
|
227
|
+
let currentBatch = [];
|
|
228
|
+
let currentBatchSize = 0;
|
|
229
|
+
for (const attachment of attachments) {
|
|
230
|
+
const attachmentSize = attachment.size;
|
|
231
|
+
// Check if adding this attachment would exceed limits
|
|
232
|
+
const wouldExceedFileLimit = currentBatch.length >= MAX_FILES_PER_REQUEST;
|
|
233
|
+
const wouldExceedSizeLimit = currentBatchSize + attachmentSize > MAX_REQUEST_SIZE;
|
|
234
|
+
// If current batch is full or would exceed limits, start a new batch
|
|
235
|
+
if (wouldExceedFileLimit || wouldExceedSizeLimit) {
|
|
236
|
+
if (currentBatch.length > 0) {
|
|
237
|
+
batches.push(currentBatch);
|
|
238
|
+
currentBatch = [];
|
|
239
|
+
currentBatchSize = 0;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// If a single file exceeds request size limit, it should have been filtered earlier
|
|
243
|
+
// but we check again as a safety measure
|
|
244
|
+
if (attachmentSize > MAX_REQUEST_SIZE) {
|
|
245
|
+
this.logger.logError(`Attachment "${attachment.file_path ?? attachment.file_name}" exceeds maximum request size (128 MB). ` +
|
|
246
|
+
`File size: ${(attachmentSize / (1024 * 1024)).toFixed(2)} MB. Skipping.`);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
currentBatch.push(attachment);
|
|
250
|
+
currentBatchSize += attachmentSize;
|
|
251
|
+
}
|
|
252
|
+
// Add the last batch if it's not empty
|
|
253
|
+
if (currentBatch.length > 0) {
|
|
254
|
+
batches.push(currentBatch);
|
|
255
|
+
}
|
|
256
|
+
return batches;
|
|
257
|
+
}
|
|
182
258
|
/**
|
|
183
259
|
* Upload attachment with retry logic for 429 errors
|
|
184
260
|
* @param project Project code
|
|
185
|
-
* @param data Attachment data
|
|
186
|
-
* @param
|
|
261
|
+
* @param data Attachment data array (can contain multiple files)
|
|
262
|
+
* @param attachmentNames Attachment names for logging (comma-separated for batches)
|
|
187
263
|
* @param maxRetries Maximum number of retry attempts
|
|
188
264
|
* @param initialDelay Initial delay in milliseconds
|
|
189
265
|
* @returns Promise with upload response
|
|
190
266
|
*/
|
|
191
|
-
async uploadAttachmentWithRetry(project, data,
|
|
267
|
+
async uploadAttachmentWithRetry(project, data, attachmentNames, maxRetries = 5, initialDelay = 1000) {
|
|
192
268
|
let lastError;
|
|
193
269
|
let delay = initialDelay;
|
|
194
270
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
@@ -208,14 +284,14 @@ class ClientV1 {
|
|
|
208
284
|
const jitterPercent = 0.1 + Math.random() * 0.2; // 10-30%
|
|
209
285
|
const jitter = baseWaitTime * jitterPercent;
|
|
210
286
|
const waitTime = Math.floor(baseWaitTime + jitter);
|
|
211
|
-
this.logger.logDebug(`Rate limit exceeded (429) for attachment "${
|
|
287
|
+
this.logger.logDebug(`Rate limit exceeded (429) for attachment(s) "${attachmentNames}". ` +
|
|
212
288
|
`Retrying in ${waitTime}ms (attempt ${attempt + 1}/${maxRetries})`);
|
|
213
289
|
await this.delay(waitTime);
|
|
214
290
|
// Exponential backoff: double the delay for next attempt
|
|
215
291
|
delay = Math.min(delay * 2, 30000); // Cap at 30 seconds
|
|
216
292
|
}
|
|
217
293
|
else {
|
|
218
|
-
this.logger.logError(`Failed to upload attachment "${
|
|
294
|
+
this.logger.logError(`Failed to upload attachment(s) "${attachmentNames}" after ${maxRetries} retries due to rate limiting`);
|
|
219
295
|
}
|
|
220
296
|
}
|
|
221
297
|
else {
|
|
@@ -258,6 +334,50 @@ class ClientV1 {
|
|
|
258
334
|
delay(ms) {
|
|
259
335
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
260
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Ensure attachment size is calculated if not set or is 0
|
|
339
|
+
* @param attachment Attachment to ensure size for
|
|
340
|
+
*/
|
|
341
|
+
ensureAttachmentSize(attachment) {
|
|
342
|
+
// If size is already set and greater than 0, use it
|
|
343
|
+
if (attachment.size > 0) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
if (attachment.file_path) {
|
|
348
|
+
// Get file size from file system
|
|
349
|
+
const stats = (0, fs_1.statSync)(attachment.file_path);
|
|
350
|
+
attachment.size = stats.size;
|
|
351
|
+
}
|
|
352
|
+
else if (attachment.content) {
|
|
353
|
+
// Calculate size from content
|
|
354
|
+
if (typeof attachment.content === 'string') {
|
|
355
|
+
// For strings, check if it's base64 encoded
|
|
356
|
+
if (attachment.content.match(/^[A-Za-z0-9+/=]+$/)) {
|
|
357
|
+
// Base64 encoded string
|
|
358
|
+
attachment.size = Buffer.from(attachment.content, 'base64').length;
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
// Regular string - use byte length
|
|
362
|
+
attachment.size = Buffer.byteLength(attachment.content, 'utf8');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else if (Buffer.isBuffer(attachment.content)) {
|
|
366
|
+
// Buffer - use length
|
|
367
|
+
attachment.size = attachment.content.length;
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
// Fallback: try to convert to string and get byte length
|
|
371
|
+
attachment.size = Buffer.byteLength(String(attachment.content), 'utf8');
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
catch (error) {
|
|
376
|
+
// If we can't determine size, log warning and set to 0
|
|
377
|
+
this.logger.logDebug(`Could not determine size for attachment "${attachment.file_path ?? attachment.file_name}": ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
378
|
+
attachment.size = 0;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
261
381
|
prepareAttachmentData(attachment) {
|
|
262
382
|
if (attachment.file_path) {
|
|
263
383
|
return {
|
|
@@ -3,13 +3,15 @@ import { StepStatusEnum, TestResultType, TestStatusEnum } from "../models";
|
|
|
3
3
|
import { LoggerInterface } from "../utils/logger";
|
|
4
4
|
import { ClientV1 } from "./clientV1";
|
|
5
5
|
import { TestOpsOptionsType } from "../models/config/TestOpsOptionsType";
|
|
6
|
+
import { HostData } from "../models/host-data";
|
|
6
7
|
export declare class ClientV2 extends ClientV1 {
|
|
7
8
|
private readonly rootSuite;
|
|
8
9
|
static statusMap: Record<TestStatusEnum, string>;
|
|
9
10
|
static stepStatusMap: Record<StepStatusEnum, ResultStepStatus>;
|
|
10
11
|
private readonly resultsClient;
|
|
11
|
-
constructor(logger: LoggerInterface, config: TestOpsOptionsType, environment: string | undefined, rootSuite: string | undefined);
|
|
12
|
+
constructor(logger: LoggerInterface, config: TestOpsOptionsType, environment: string | undefined, rootSuite: string | undefined, hostData?: HostData, reporterName?: string, frameworkName?: string);
|
|
12
13
|
private createApiConfigV2;
|
|
14
|
+
private buildHeaders;
|
|
13
15
|
uploadResults(runId: number, results: TestResultType[]): Promise<void>;
|
|
14
16
|
private transformTestResult;
|
|
15
17
|
private transformParams;
|
package/dist/client/clientV2.js
CHANGED
|
@@ -31,19 +31,79 @@ class ClientV2 extends clientV1_1.ClientV1 {
|
|
|
31
31
|
[models_1.StepStatusEnum.skipped]: qase_api_v2_client_1.ResultStepStatus.SKIPPED,
|
|
32
32
|
};
|
|
33
33
|
resultsClient;
|
|
34
|
-
constructor(logger, config, environment, rootSuite) {
|
|
34
|
+
constructor(logger, config, environment, rootSuite, hostData, reporterName, frameworkName) {
|
|
35
35
|
super(logger, config, environment);
|
|
36
36
|
this.rootSuite = rootSuite;
|
|
37
|
-
const apiConfig = this.createApiConfigV2();
|
|
37
|
+
const apiConfig = this.createApiConfigV2(hostData, reporterName, frameworkName);
|
|
38
38
|
this.resultsClient = new qase_api_v2_client_1.ResultsApi(apiConfig);
|
|
39
39
|
}
|
|
40
|
-
createApiConfigV2() {
|
|
40
|
+
createApiConfigV2(hostData, reporterName, frameworkName) {
|
|
41
41
|
const apiConfig = new qase_api_v2_client_1.Configuration({ apiKey: this.config.api.token, formDataCtor: form_data_1.default });
|
|
42
42
|
apiConfig.basePath = this.config.api.host && this.config.api.host != API_CONFIG.DEFAULT_HOST
|
|
43
43
|
? `${API_CONFIG.BASE_URL}${this.config.api.host}${API_CONFIG.VERSION}`
|
|
44
44
|
: `https://api.${API_CONFIG.DEFAULT_HOST}${API_CONFIG.VERSION}`;
|
|
45
|
+
// Set default headers for all requests
|
|
46
|
+
if (hostData) {
|
|
47
|
+
const headers = this.buildHeaders(hostData, reporterName, frameworkName);
|
|
48
|
+
const existingHeaders = apiConfig.baseOptions?.headers || {};
|
|
49
|
+
const baseOptionsWithHeaders = {
|
|
50
|
+
...(apiConfig.baseOptions || {}),
|
|
51
|
+
headers: {
|
|
52
|
+
...existingHeaders,
|
|
53
|
+
...headers,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
apiConfig.baseOptions = baseOptionsWithHeaders;
|
|
57
|
+
}
|
|
45
58
|
return apiConfig;
|
|
46
59
|
}
|
|
60
|
+
buildHeaders(hostData, reporterName, frameworkName) {
|
|
61
|
+
const headers = {};
|
|
62
|
+
// Build X-Client header
|
|
63
|
+
const clientParts = [];
|
|
64
|
+
if (reporterName && reporterName.trim()) {
|
|
65
|
+
clientParts.push(`reporter=${reporterName}`);
|
|
66
|
+
}
|
|
67
|
+
if (hostData.reporter && hostData.reporter.trim()) {
|
|
68
|
+
clientParts.push(`reporter_version=v${hostData.reporter}`);
|
|
69
|
+
}
|
|
70
|
+
if (frameworkName && frameworkName.trim()) {
|
|
71
|
+
clientParts.push(`framework=${frameworkName}`);
|
|
72
|
+
}
|
|
73
|
+
if (hostData.framework && hostData.framework.trim()) {
|
|
74
|
+
clientParts.push(`framework_version=v${hostData.framework}`);
|
|
75
|
+
}
|
|
76
|
+
if (hostData.apiClientV1 && hostData.apiClientV1.trim()) {
|
|
77
|
+
clientParts.push(`client_version_v1=v${hostData.apiClientV1}`);
|
|
78
|
+
}
|
|
79
|
+
if (hostData.apiClientV2 && hostData.apiClientV2.trim()) {
|
|
80
|
+
clientParts.push(`client_version_v2=v${hostData.apiClientV2}`);
|
|
81
|
+
}
|
|
82
|
+
if (hostData.commons && hostData.commons.trim()) {
|
|
83
|
+
clientParts.push(`core_version=v${hostData.commons}`);
|
|
84
|
+
}
|
|
85
|
+
if (clientParts.length > 0) {
|
|
86
|
+
headers['X-Client'] = clientParts.join(';');
|
|
87
|
+
}
|
|
88
|
+
// Build X-Platform header
|
|
89
|
+
const platformParts = [];
|
|
90
|
+
if (hostData.system && hostData.system.trim()) {
|
|
91
|
+
platformParts.push(`os=${hostData.system}`);
|
|
92
|
+
}
|
|
93
|
+
if (hostData.arch && hostData.arch.trim()) {
|
|
94
|
+
platformParts.push(`arch=${hostData.arch}`);
|
|
95
|
+
}
|
|
96
|
+
if (hostData.node && hostData.node.trim()) {
|
|
97
|
+
platformParts.push(`node=${hostData.node}`);
|
|
98
|
+
}
|
|
99
|
+
if (hostData.npm && hostData.npm.trim()) {
|
|
100
|
+
platformParts.push(`npm=${hostData.npm}`);
|
|
101
|
+
}
|
|
102
|
+
if (platformParts.length > 0) {
|
|
103
|
+
headers['X-Platform'] = platformParts.join(';');
|
|
104
|
+
}
|
|
105
|
+
return headers;
|
|
106
|
+
}
|
|
47
107
|
async uploadResults(runId, results) {
|
|
48
108
|
try {
|
|
49
109
|
const models = await Promise.all(results.map(result => this.transformTestResult(result)));
|
package/dist/models/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export { TestResultType
|
|
1
|
+
export { TestResultType } from './test-result';
|
|
2
|
+
export type { Relation, Suite, SuiteData } from './test-result';
|
|
2
3
|
export { TestExecution, TestStatusEnum } from './test-execution';
|
|
3
4
|
export { TestStepType, StepType } from './test-step';
|
|
4
5
|
export { StepStatusEnum } from './step-execution';
|
|
5
|
-
export { Attachment } from './attachment';
|
|
6
|
-
export { Report } from './report';
|
|
6
|
+
export type { Attachment } from './attachment';
|
|
7
|
+
export type { Report } from './report';
|
|
7
8
|
export { CompoundError } from './error';
|
|
8
|
-
export { ConfigurationGroup, ConfigurationItem, ConfigurationGroupResponse } from './configuration';
|
|
9
|
-
export { ExternalLinkType
|
|
9
|
+
export type { ConfigurationGroup, ConfigurationItem, ConfigurationGroupResponse } from './configuration';
|
|
10
|
+
export { ExternalLinkType } from './config/TestOpsOptionsType';
|
|
11
|
+
export type { TestOpsOptionsType, TestOpsApiType, TestOpsRunType, TestOpsPlanType, TestOpsBatchType, TestOpsConfigurationType, TestOpsConfigurationValueType, TestOpsExternalLinkType } from './config/TestOpsOptionsType';
|
package/dist/qase.d.ts
CHANGED
package/dist/qase.js
CHANGED
|
@@ -63,6 +63,7 @@ class QaseReporter {
|
|
|
63
63
|
startTestRunOperation;
|
|
64
64
|
options;
|
|
65
65
|
withState;
|
|
66
|
+
hostData;
|
|
66
67
|
/**
|
|
67
68
|
* @param {OptionsType} options
|
|
68
69
|
*/
|
|
@@ -94,8 +95,8 @@ class QaseReporter {
|
|
|
94
95
|
}
|
|
95
96
|
this.logger = new logger_1.Logger(loggerOptions);
|
|
96
97
|
this.logger.logDebug(`Config: ${JSON.stringify(this.sanitizeOptions(composedOptions))}`);
|
|
97
|
-
|
|
98
|
-
this.logger.logDebug(`Host data: ${JSON.stringify(hostData)}`);
|
|
98
|
+
this.hostData = (0, hostData_1.getHostInfo)(options.frameworkPackage, options.reporterName);
|
|
99
|
+
this.logger.logDebug(`Host data: ${JSON.stringify(this.hostData)}`);
|
|
99
100
|
this.captureLogs = composedOptions.captureLogs;
|
|
100
101
|
try {
|
|
101
102
|
this.upstreamReporter = this.createReporter(
|
|
@@ -448,7 +449,7 @@ class QaseReporter {
|
|
|
448
449
|
if (!options.testops.project) {
|
|
449
450
|
throw new Error(`Either "testops.project" parameter or "${env_1.EnvTestOpsEnum.project}" environment variable is required in "testops" mode`);
|
|
450
451
|
}
|
|
451
|
-
const apiClient = new clientV2_1.ClientV2(this.logger, options.testops, options.environment, options.rootSuite);
|
|
452
|
+
const apiClient = new clientV2_1.ClientV2(this.logger, options.testops, options.environment, options.rootSuite, this.hostData, options.reporterName, options.frameworkPackage);
|
|
452
453
|
return new reporters_1.TestOpsReporter(this.logger, apiClient, this.withState, options.testops.project, options.testops.api.host, options.testops.batch?.size, options.testops.run?.id, options.testops.showPublicReportLink);
|
|
453
454
|
}
|
|
454
455
|
case options_1.ModeEnum.report: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qase-javascript-commons",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.14",
|
|
4
4
|
"description": "Qase JS Reporters",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"lodash.merge": "^4.6.2",
|
|
34
34
|
"lodash.mergewith": "^4.6.2",
|
|
35
35
|
"mime-types": "^2.1.35",
|
|
36
|
-
"qase-api-client": "~1.1.
|
|
37
|
-
"qase-api-v2-client": "~1.0.
|
|
36
|
+
"qase-api-client": "~1.1.1",
|
|
37
|
+
"qase-api-v2-client": "~1.0.4",
|
|
38
38
|
"strip-ansi": "^6.0.1",
|
|
39
39
|
"uuid": "^9.0.1"
|
|
40
40
|
},
|