@dev-blinq/cucumber-js 1.0.110-dev → 1.0.110-stage
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/bin/cucumber.ts +1 -0
- package/bin/download-install.js +22 -2
- package/lib/api/console_logger.js.map +1 -1
- package/lib/cli/run.js +1 -0
- package/lib/cli/run.js.map +1 -1
- package/lib/cli/validate_node_engine_version.js +3 -1
- package/lib/cli/validate_node_engine_version.js.map +1 -1
- package/lib/configuration/axios_client.js +1 -1
- package/lib/configuration/axios_client.js.map +1 -1
- package/lib/formatter/api.js +16 -5
- package/lib/formatter/api.js.map +1 -1
- package/lib/formatter/builder.js +1 -3
- package/lib/formatter/builder.js.map +1 -1
- package/lib/formatter/bvt_analysis_formatter.d.ts +13 -1
- package/lib/formatter/bvt_analysis_formatter.js +174 -58
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.js +12 -3
- package/lib/formatter/feature_data_format.js.map +1 -1
- package/lib/formatter/helpers/constants.d.ts +50 -0
- package/lib/formatter/helpers/constants.js +60 -0
- package/lib/formatter/helpers/constants.js.map +1 -0
- package/lib/formatter/helpers/report_generator.d.ts +21 -3
- package/lib/formatter/helpers/report_generator.js +336 -26
- package/lib/formatter/helpers/report_generator.js.map +1 -1
- package/lib/formatter/helpers/test_case_attempt_formatter.js +1 -1
- package/lib/formatter/helpers/test_case_attempt_formatter.js.map +1 -1
- package/lib/formatter/helpers/test_case_attempt_parser.js.map +1 -1
- package/lib/formatter/helpers/upload_serivce.d.ts +15 -1
- package/lib/formatter/helpers/upload_serivce.js +160 -4
- package/lib/formatter/helpers/upload_serivce.js.map +1 -1
- package/lib/formatter/helpers/uploader.d.ts +2 -1
- package/lib/formatter/helpers/uploader.js +16 -1
- package/lib/formatter/helpers/uploader.js.map +1 -1
- package/lib/formatter/summary_formatter.js +4 -0
- package/lib/formatter/summary_formatter.js.map +1 -1
- package/lib/runtime/test_case_runner.d.ts +2 -0
- package/lib/runtime/test_case_runner.js +17 -1
- package/lib/runtime/test_case_runner.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +6 -3
|
@@ -1,19 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
var _a, _b;
|
|
6
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const messages = __importStar(require("@cucumber/messages"));
|
|
7
31
|
const fs_1 = __importDefault(require("fs"));
|
|
8
32
|
const path_1 = __importDefault(require("path"));
|
|
9
33
|
const upload_serivce_1 = require("./upload_serivce");
|
|
34
|
+
const fs_extra_1 = require("fs-extra");
|
|
35
|
+
// type JsonException = messages.Exception
|
|
36
|
+
const object_path_1 = __importDefault(require("object-path"));
|
|
10
37
|
const URL = process.env.NODE_ENV_BLINQ === 'dev'
|
|
11
38
|
? 'https://dev.api.blinq.io/api/runs'
|
|
12
39
|
: process.env.NODE_ENV_BLINQ === 'local'
|
|
13
40
|
? 'http://localhost:5001/api/runs'
|
|
14
41
|
: process.env.NODE_ENV_BLINQ === 'stage'
|
|
15
42
|
? 'https://stage.api.blinq.io/api/runs'
|
|
16
|
-
:
|
|
43
|
+
: process.env.NODE_ENV_BLINQ === 'prod'
|
|
44
|
+
? 'https://api.blinq.io/api/runs'
|
|
45
|
+
: !process.env.NODE_ENV_BLINQ
|
|
46
|
+
? 'https://api.blinq.io/api/runs'
|
|
47
|
+
: `${process.env.NODE_ENV_BLINQ}/api/runs`;
|
|
17
48
|
const REPORT_SERVICE_URL = (_a = process.env.REPORT_SERVICE_URL) !== null && _a !== void 0 ? _a : URL;
|
|
18
49
|
const BATCH_SIZE = 10;
|
|
19
50
|
const MAX_RETRIES = 3;
|
|
@@ -40,12 +71,20 @@ class ReportGenerator {
|
|
|
40
71
|
this.scenarioIterationCountMap = new Map();
|
|
41
72
|
this.logs = [];
|
|
42
73
|
this.networkLog = [];
|
|
74
|
+
this.stepLogs = [];
|
|
75
|
+
this.stepNetworkLogs = [];
|
|
43
76
|
this.runName = '';
|
|
77
|
+
this.ariaSnapshot = '';
|
|
78
|
+
this.initialAriaSnapshot = '';
|
|
79
|
+
this.testCaseLog = [];
|
|
80
|
+
this.loggingOverridden = false; // Flag to track if logging is overridden
|
|
44
81
|
this.reportFolder = null;
|
|
45
82
|
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
83
|
+
this.retryTestCaseId = null;
|
|
84
|
+
this.retryCount = 3;
|
|
46
85
|
}
|
|
47
|
-
async handleMessage(envelope) {
|
|
48
|
-
if (envelope.meta && envelope.meta
|
|
86
|
+
async handleMessage(envelope, reRunId) {
|
|
87
|
+
if (envelope.meta && 'runName' in envelope.meta) {
|
|
49
88
|
this.runName = envelope.meta.runName;
|
|
50
89
|
}
|
|
51
90
|
const type = Object.keys(envelope)[0];
|
|
@@ -72,14 +111,35 @@ class ReportGenerator {
|
|
|
72
111
|
case 'testRunStarted': {
|
|
73
112
|
const testRunStarted = envelope[type];
|
|
74
113
|
this.onTestRunStarted(testRunStarted);
|
|
114
|
+
await this.uploadService.createStatus('running');
|
|
75
115
|
break;
|
|
76
116
|
}
|
|
77
117
|
case 'testCase': {
|
|
78
118
|
const testCase = envelope[type];
|
|
119
|
+
// Initialize the log storage
|
|
120
|
+
this.testCaseLog = [];
|
|
121
|
+
if (!this.loggingOverridden) {
|
|
122
|
+
this.loggingOverridden = true;
|
|
123
|
+
// Store the original process.stdout.write, and process.stderr.write
|
|
124
|
+
const originalStdoutWrite = process.stdout.write;
|
|
125
|
+
const originalStderrWrite = process.stderr.write;
|
|
126
|
+
// Override process.stdout.write
|
|
127
|
+
process.stdout.write = (chunk, ...args) => {
|
|
128
|
+
this.testCaseLog.push(chunk.toString());
|
|
129
|
+
return originalStdoutWrite.call(process.stdout, chunk, ...args);
|
|
130
|
+
};
|
|
131
|
+
// Override process.stderr.write
|
|
132
|
+
process.stderr.write = (chunk, ...args) => {
|
|
133
|
+
this.testCaseLog.push(chunk.toString());
|
|
134
|
+
return originalStderrWrite.call(process.stderr, chunk, ...args);
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Call the onTestCase method
|
|
79
138
|
this.onTestCase(testCase);
|
|
80
139
|
break;
|
|
81
140
|
}
|
|
82
141
|
case 'testCaseStarted': {
|
|
142
|
+
this.retryTestCaseId = envelope[type].retryTestCaseId;
|
|
83
143
|
const testCaseStarted = envelope[type];
|
|
84
144
|
this.onTestCaseStarted(testCaseStarted);
|
|
85
145
|
break;
|
|
@@ -101,13 +161,18 @@ class ReportGenerator {
|
|
|
101
161
|
}
|
|
102
162
|
case 'testCaseFinished': {
|
|
103
163
|
const testCaseFinished = envelope[type];
|
|
104
|
-
|
|
105
|
-
|
|
164
|
+
let reRunIdFinal = this.retryTestCaseId;
|
|
165
|
+
if (reRunId) {
|
|
166
|
+
reRunIdFinal = reRunId;
|
|
167
|
+
}
|
|
168
|
+
// Call the onTestCaseFinished method
|
|
169
|
+
const result = await this.onTestCaseFinished(testCaseFinished, reRunIdFinal);
|
|
170
|
+
return result;
|
|
106
171
|
}
|
|
107
172
|
// case "hook": { break} // After Hook
|
|
108
173
|
case 'testRunFinished': {
|
|
109
174
|
const testRunFinished = envelope[type];
|
|
110
|
-
this.onTestRunFinished(testRunFinished);
|
|
175
|
+
await this.onTestRunFinished(testRunFinished);
|
|
111
176
|
break;
|
|
112
177
|
}
|
|
113
178
|
// case "parameterType" : { break}
|
|
@@ -238,6 +303,10 @@ class ReportGenerator {
|
|
|
238
303
|
result: {
|
|
239
304
|
status: 'UNKNOWN',
|
|
240
305
|
},
|
|
306
|
+
networkData: [],
|
|
307
|
+
webLog: [],
|
|
308
|
+
data: {},
|
|
309
|
+
ariaSnapshot: this.ariaSnapshot,
|
|
241
310
|
});
|
|
242
311
|
return this.stepReportMap.get(pickleStep.id);
|
|
243
312
|
});
|
|
@@ -280,19 +349,34 @@ class ReportGenerator {
|
|
|
280
349
|
this.reportFolder = body.replaceAll('\\', '/');
|
|
281
350
|
return;
|
|
282
351
|
}
|
|
352
|
+
if (mediaType === 'application/json+snapshot-before') {
|
|
353
|
+
this.initialAriaSnapshot = body;
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (mediaType === 'application/json+snapshot-after') {
|
|
357
|
+
this.ariaSnapshot = body;
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
283
360
|
if (mediaType === 'application/json+env') {
|
|
284
361
|
const data = JSON.parse(body);
|
|
285
362
|
this.report.env = data;
|
|
363
|
+
this.report.testCases.map((testCase) => {
|
|
364
|
+
testCase.env = data;
|
|
365
|
+
return testCase;
|
|
366
|
+
});
|
|
286
367
|
}
|
|
287
368
|
if (mediaType === 'application/json+log') {
|
|
288
369
|
const log = JSON.parse(body);
|
|
289
|
-
if (this.logs.length < 1000)
|
|
370
|
+
if (this.logs.length < 1000) {
|
|
290
371
|
this.logs.push(log);
|
|
372
|
+
this.stepLogs.push(log);
|
|
373
|
+
}
|
|
291
374
|
}
|
|
292
375
|
if (mediaType === 'application/json+network') {
|
|
293
376
|
const networkLog = JSON.parse(body);
|
|
294
377
|
if (this.networkLog.length < 1000)
|
|
295
378
|
this.networkLog.push(networkLog);
|
|
379
|
+
this.stepNetworkLogs.push(networkLog);
|
|
296
380
|
}
|
|
297
381
|
const testStep = this.testStepMap.get(testStepId);
|
|
298
382
|
if (testStep.pickleStepId === undefined)
|
|
@@ -302,16 +386,100 @@ class ReportGenerator {
|
|
|
302
386
|
const command = JSON.parse(body);
|
|
303
387
|
stepProgess.commands.push(command);
|
|
304
388
|
}
|
|
389
|
+
else if (mediaType === 'application/json+trace') {
|
|
390
|
+
const data = JSON.parse(body);
|
|
391
|
+
stepProgess.traceFilePath = data.traceFilePath;
|
|
392
|
+
}
|
|
393
|
+
if (mediaType === 'application/json+bruno') {
|
|
394
|
+
try {
|
|
395
|
+
const data = JSON.parse(body);
|
|
396
|
+
stepProgess.brunoData = data;
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
console.error('Error parsing bruno data:', error);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (mediaType === 'application/json+intercept-results') {
|
|
403
|
+
try {
|
|
404
|
+
const data = JSON.parse(body);
|
|
405
|
+
stepProgess.interceptResults = data;
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
console.error('Error parsing intercept results:', error);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
getFailedTestStepResult({ commands, startTime, endTime, result, }) {
|
|
413
|
+
for (const command of commands) {
|
|
414
|
+
if (command.result.status === 'FAILED') {
|
|
415
|
+
return {
|
|
416
|
+
status: 'FAILED',
|
|
417
|
+
message: command.result.message,
|
|
418
|
+
startTime,
|
|
419
|
+
endTime,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return {
|
|
424
|
+
status: 'FAILED',
|
|
425
|
+
startTime,
|
|
426
|
+
endTime,
|
|
427
|
+
message: result.message,
|
|
428
|
+
};
|
|
305
429
|
}
|
|
306
430
|
onTestStepFinished(testStepFinished) {
|
|
307
431
|
const { testStepId, testStepResult, timestamp } = testStepFinished;
|
|
308
432
|
const testStep = this.testStepMap.get(testStepId);
|
|
309
433
|
if (testStep.pickleStepId === undefined) {
|
|
310
434
|
if (testStepResult.status === 'FAILED') {
|
|
435
|
+
const testCase = this.testCaseReportMap.get(testStepFinished.testCaseStartedId);
|
|
436
|
+
const type = testCase.steps[0].result.status === 'UNKNOWN' ? 'Before' : 'After';
|
|
437
|
+
const hookStep = {
|
|
438
|
+
ariaSnapshot: null,
|
|
439
|
+
commands: [],
|
|
440
|
+
keyword: type,
|
|
441
|
+
data: {},
|
|
442
|
+
networkData: [],
|
|
443
|
+
result: {
|
|
444
|
+
status: 'FAILED',
|
|
445
|
+
message: testStepResult.message,
|
|
446
|
+
startTime: this.getTimeStamp(timestamp),
|
|
447
|
+
endTime: this.getTimeStamp(timestamp),
|
|
448
|
+
},
|
|
449
|
+
text: 'Failed hook',
|
|
450
|
+
type,
|
|
451
|
+
webLog: [],
|
|
452
|
+
};
|
|
453
|
+
if (type === 'Before') {
|
|
454
|
+
testCase.steps = [hookStep, ...testCase.steps];
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
testCase.steps = [...testCase.steps, hookStep];
|
|
458
|
+
}
|
|
459
|
+
this.testCaseReportMap.set(testStepFinished.testCaseStartedId, testCase);
|
|
311
460
|
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
312
461
|
}
|
|
313
462
|
return;
|
|
314
463
|
}
|
|
464
|
+
if (testStepResult.status === 'UNDEFINED') {
|
|
465
|
+
const step = this.stepReportMap.get(testStep.pickleStepId);
|
|
466
|
+
const stepName = step ? step.keyword + ' ' + step.text : 'Undefined step';
|
|
467
|
+
const undefinedCommand = {
|
|
468
|
+
testStepId: testStepId,
|
|
469
|
+
body: JSON.stringify({
|
|
470
|
+
type: 'error',
|
|
471
|
+
text: 'Undefined step: ' + stepName,
|
|
472
|
+
result: {
|
|
473
|
+
status: 'FAILED',
|
|
474
|
+
startTime: this.getTimeStamp(timestamp),
|
|
475
|
+
endTime: this.getTimeStamp(timestamp),
|
|
476
|
+
},
|
|
477
|
+
}),
|
|
478
|
+
mediaType: 'application/json',
|
|
479
|
+
contentEncoding: messages.AttachmentContentEncoding.IDENTITY,
|
|
480
|
+
};
|
|
481
|
+
this.onAttachment(undefinedCommand);
|
|
482
|
+
}
|
|
315
483
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
316
484
|
const prevStepResult = stepProgess.result;
|
|
317
485
|
let data = {};
|
|
@@ -327,16 +495,73 @@ class ReportGenerator {
|
|
|
327
495
|
catch (error) {
|
|
328
496
|
console.log('Error reading data.json');
|
|
329
497
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
498
|
+
if (testStepResult.status === 'FAILED') {
|
|
499
|
+
stepProgess.result = this.getFailedTestStepResult({
|
|
500
|
+
commands: stepProgess.commands,
|
|
501
|
+
startTime: prevStepResult.startTime,
|
|
502
|
+
endTime: this.getTimeStamp(timestamp),
|
|
503
|
+
result: testStepResult,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
stepProgess.result = {
|
|
508
|
+
status: testStepResult.status,
|
|
509
|
+
startTime: prevStepResult.startTime,
|
|
510
|
+
endTime: this.getTimeStamp(timestamp),
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
stepProgess.webLog = this.stepLogs;
|
|
514
|
+
stepProgess.networkData = this.stepNetworkLogs;
|
|
515
|
+
stepProgess.ariaSnapshot = this.ariaSnapshot;
|
|
516
|
+
this.ariaSnapshot = '';
|
|
517
|
+
this.stepNetworkLogs = [];
|
|
518
|
+
this.stepLogs = [];
|
|
337
519
|
if (Object.keys(data).length > 0) {
|
|
338
520
|
stepProgess.data = data;
|
|
521
|
+
const id = testStepFinished.testCaseStartedId;
|
|
522
|
+
const parameters = this.testCaseReportMap.get(id).parameters;
|
|
523
|
+
const _parameters = {};
|
|
524
|
+
Object.keys(parameters).map((key) => {
|
|
525
|
+
var _a;
|
|
526
|
+
if (parameters[key].startsWith('{{') &&
|
|
527
|
+
parameters[key].endsWith('}}')) {
|
|
528
|
+
const path = parameters[key].slice(2, -2).split('.');
|
|
529
|
+
let value = String((_a = object_path_1.default.get(data, path)) !== null && _a !== void 0 ? _a : parameters[key]);
|
|
530
|
+
if (value) {
|
|
531
|
+
if (value.startsWith('secret:')) {
|
|
532
|
+
value = 'secret:****';
|
|
533
|
+
}
|
|
534
|
+
else if (value.startsWith('totp:')) {
|
|
535
|
+
value = 'totp:****';
|
|
536
|
+
}
|
|
537
|
+
else if (value.startsWith('mask:')) {
|
|
538
|
+
value = 'mask:****';
|
|
539
|
+
}
|
|
540
|
+
_parameters[key] = value;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
_parameters[key] = parameters[key];
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
this.report.testCases.find((testCase) => {
|
|
548
|
+
return testCase.id === id;
|
|
549
|
+
}).parameters = _parameters;
|
|
339
550
|
}
|
|
551
|
+
// if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
552
|
+
// this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH
|
|
553
|
+
// if (!fs.existsSync(this.reportFolder)) {
|
|
554
|
+
// fs.mkdirSync(this.reportFolder)
|
|
555
|
+
// }
|
|
556
|
+
// const reportFilePath = path.join(
|
|
557
|
+
// this.reportFolder,
|
|
558
|
+
// `report.json`
|
|
559
|
+
// )
|
|
560
|
+
// writeFileSync(reportFilePath, JSON.stringify(this.report, null, 2))
|
|
561
|
+
// return undefined
|
|
562
|
+
// // } else {
|
|
563
|
+
// // return await this.uploadTestCase(testProgress, reRunId)
|
|
564
|
+
// }
|
|
340
565
|
}
|
|
341
566
|
getLogFileContent() {
|
|
342
567
|
let projectPath = process.cwd();
|
|
@@ -363,6 +588,12 @@ class ReportGenerator {
|
|
|
363
588
|
}
|
|
364
589
|
}
|
|
365
590
|
getTestCaseResult(steps) {
|
|
591
|
+
if (steps[0] && steps[0].result.status === 'SKIPPED') {
|
|
592
|
+
return {
|
|
593
|
+
status: 'FAILED',
|
|
594
|
+
message: 'Test skipped due to failure in before hooks',
|
|
595
|
+
};
|
|
596
|
+
}
|
|
366
597
|
for (const step of steps) {
|
|
367
598
|
switch (step.result.status) {
|
|
368
599
|
case 'FAILED':
|
|
@@ -384,24 +615,76 @@ class ReportGenerator {
|
|
|
384
615
|
status: 'PASSED',
|
|
385
616
|
};
|
|
386
617
|
}
|
|
387
|
-
async onTestCaseFinished(testCaseFinished) {
|
|
618
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
388
619
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
389
620
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
390
621
|
const prevResult = testProgress.result;
|
|
391
622
|
const steps = Object.values(testProgress.steps);
|
|
392
623
|
const result = this.getTestCaseResult(steps);
|
|
624
|
+
if (result.status === 'PASSED' && reRunId) {
|
|
625
|
+
this.uploadService.updateProjectAnalytics(process.env.PROJECT_ID);
|
|
626
|
+
}
|
|
627
|
+
const endTime = this.getTimeStamp(timestamp);
|
|
393
628
|
testProgress.result = {
|
|
394
629
|
...result,
|
|
395
630
|
startTime: prevResult.startTime,
|
|
396
|
-
endTime
|
|
631
|
+
endTime,
|
|
397
632
|
};
|
|
398
633
|
testProgress.webLog = this.logs;
|
|
399
634
|
testProgress.networkLog = this.networkLog;
|
|
635
|
+
testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
|
|
636
|
+
this.initialAriaSnapshot = '';
|
|
400
637
|
this.networkLog = [];
|
|
401
638
|
this.logs = [];
|
|
402
|
-
|
|
639
|
+
if (this.testCaseLog &&
|
|
640
|
+
this.testCaseLog.length > 0 &&
|
|
641
|
+
!testProgress.logFileId) {
|
|
642
|
+
// Create the logs directory
|
|
643
|
+
const logsDir = path_1.default.join(this.reportFolder, 'editorLogs');
|
|
644
|
+
const fileName = `testCaseLog_${testCaseStartedId}.log`;
|
|
645
|
+
const filePath = path_1.default.join(logsDir, fileName);
|
|
646
|
+
// Ensure the logs directory exists
|
|
647
|
+
fs_1.default.mkdirSync(logsDir, { recursive: true });
|
|
648
|
+
// Write the logs to the file
|
|
649
|
+
fs_1.default.writeFileSync(filePath, this.testCaseLog.join('\n'), 'utf8');
|
|
650
|
+
// Store this ID in the testProgress object so it can be accessed later
|
|
651
|
+
testProgress.logFileId = testCaseStartedId;
|
|
652
|
+
}
|
|
653
|
+
this.testCaseLog = [];
|
|
654
|
+
if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
655
|
+
this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
656
|
+
if (!fs_1.default.existsSync(this.reportFolder)) {
|
|
657
|
+
fs_1.default.mkdirSync(this.reportFolder);
|
|
658
|
+
}
|
|
659
|
+
const reportFilePath = path_1.default.join(this.reportFolder, `${endTime}_${testProgress.scenarioName}.json`);
|
|
660
|
+
(0, fs_extra_1.writeFileSync)(reportFilePath, JSON.stringify(testProgress, null, 2));
|
|
661
|
+
return undefined;
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
return await this.uploadTestCase(testProgress, reRunId);
|
|
665
|
+
}
|
|
403
666
|
}
|
|
404
|
-
async uploadTestCase(testCase) {
|
|
667
|
+
async uploadTestCase(testCase, rerunId) {
|
|
668
|
+
let data = null;
|
|
669
|
+
for (let attempt = 1; attempt <= this.retryCount; attempt++) {
|
|
670
|
+
try {
|
|
671
|
+
data = await this.tryUpload(testCase, rerunId);
|
|
672
|
+
break;
|
|
673
|
+
}
|
|
674
|
+
catch (e) {
|
|
675
|
+
console.error(`Attempt ${attempt} to upload testcase failed:`, e);
|
|
676
|
+
if (attempt === this.retryCount) {
|
|
677
|
+
console.error('All retry attempts failed, failed to upload testcase.');
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
const waitTime = 1000 * 2 ** (attempt - 1); //? exponential backoff: 1s, 2s, 4s...
|
|
681
|
+
await new Promise((r) => setTimeout(r, waitTime));
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return data;
|
|
686
|
+
}
|
|
687
|
+
async tryUpload(testCase, rerunId) {
|
|
405
688
|
let runId = '';
|
|
406
689
|
let projectId = '';
|
|
407
690
|
if (!process.env.UPLOADING_TEST_CASE) {
|
|
@@ -412,7 +695,9 @@ class ReportGenerator {
|
|
|
412
695
|
anyRemArr.push(randomID);
|
|
413
696
|
process.env.UPLOADING_TEST_CASE = JSON.stringify(anyRemArr);
|
|
414
697
|
try {
|
|
415
|
-
if (process.env.RUN_ID &&
|
|
698
|
+
if (process.env.RUN_ID &&
|
|
699
|
+
process.env.PROJECT_ID &&
|
|
700
|
+
!process.env.IGNORE_ENV_VARIABLES) {
|
|
416
701
|
runId = process.env.RUN_ID;
|
|
417
702
|
projectId = process.env.PROJECT_ID;
|
|
418
703
|
}
|
|
@@ -420,13 +705,14 @@ class ReportGenerator {
|
|
|
420
705
|
const runDoc = await this.uploadService.createRunDocument(this.runName);
|
|
421
706
|
runId = runDoc._id;
|
|
422
707
|
projectId = runDoc.project_id;
|
|
423
|
-
process.env.
|
|
424
|
-
|
|
708
|
+
if (!process.env.IGNORE_ENV_VARIABLES) {
|
|
709
|
+
process.env.RUN_ID = runId;
|
|
710
|
+
process.env.PROJECT_ID = projectId;
|
|
711
|
+
}
|
|
425
712
|
}
|
|
426
|
-
await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder);
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
console.error('Error uploading test case:', e);
|
|
713
|
+
const data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
|
|
714
|
+
this.writeTestCaseReportToDisk(testCase);
|
|
715
|
+
return data;
|
|
430
716
|
}
|
|
431
717
|
finally {
|
|
432
718
|
const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
@@ -434,7 +720,30 @@ class ReportGenerator {
|
|
|
434
720
|
process.env.UPLOADING_TEST_CASE = JSON.stringify(arrRem);
|
|
435
721
|
}
|
|
436
722
|
}
|
|
437
|
-
|
|
723
|
+
writeTestCaseReportToDisk(testCase) {
|
|
724
|
+
var _a;
|
|
725
|
+
const reportFolder = (_a = this.reportFolder) !== null && _a !== void 0 ? _a : process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
726
|
+
if (!reportFolder) {
|
|
727
|
+
console.error('Report folder is not defined');
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
try {
|
|
731
|
+
let i = 0;
|
|
732
|
+
while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
|
|
733
|
+
i++;
|
|
734
|
+
}
|
|
735
|
+
fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
|
|
736
|
+
//exclude network log from the saved report
|
|
737
|
+
const networkLog = testCase.networkLog;
|
|
738
|
+
delete testCase.networkLog;
|
|
739
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
|
|
740
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
|
|
741
|
+
}
|
|
742
|
+
catch (error) {
|
|
743
|
+
console.error('Error writing test case report to disk:', error);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
async onTestRunFinished(testRunFinished) {
|
|
438
747
|
const { timestamp, success, message } = testRunFinished;
|
|
439
748
|
const prevResult = this.report.result;
|
|
440
749
|
this.report.result = {
|
|
@@ -444,6 +753,7 @@ class ReportGenerator {
|
|
|
444
753
|
message,
|
|
445
754
|
// exception,
|
|
446
755
|
};
|
|
756
|
+
await this.uploadService.createStatus(success ? 'passed' : 'failed');
|
|
447
757
|
}
|
|
448
758
|
}
|
|
449
759
|
exports.default = ReportGenerator;
|