@dev-blinq/cucumber-js 1.0.106-dev → 1.0.106

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.
Files changed (33) hide show
  1. package/bin/download-install.js +22 -2
  2. package/lib/configuration/axios_client.js +1 -1
  3. package/lib/configuration/axios_client.js.map +1 -1
  4. package/lib/formatter/api.js +7 -1
  5. package/lib/formatter/api.js.map +1 -1
  6. package/lib/formatter/bvt_analysis_formatter.d.ts +13 -1
  7. package/lib/formatter/bvt_analysis_formatter.js +159 -55
  8. package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
  9. package/lib/formatter/feature_data_format.js +4 -1
  10. package/lib/formatter/feature_data_format.js.map +1 -1
  11. package/lib/formatter/helpers/constants.d.ts +50 -0
  12. package/lib/formatter/helpers/constants.js +60 -0
  13. package/lib/formatter/helpers/constants.js.map +1 -0
  14. package/lib/formatter/helpers/report_generator.d.ts +31 -13
  15. package/lib/formatter/helpers/report_generator.js +322 -71
  16. package/lib/formatter/helpers/report_generator.js.map +1 -1
  17. package/lib/formatter/helpers/test_case_attempt_formatter.js +1 -1
  18. package/lib/formatter/helpers/test_case_attempt_formatter.js.map +1 -1
  19. package/lib/formatter/helpers/upload_serivce.d.ts +15 -3
  20. package/lib/formatter/helpers/upload_serivce.js +112 -47
  21. package/lib/formatter/helpers/upload_serivce.js.map +1 -1
  22. package/lib/formatter/helpers/uploader.d.ts +2 -1
  23. package/lib/formatter/helpers/uploader.js +16 -1
  24. package/lib/formatter/helpers/uploader.js.map +1 -1
  25. package/lib/formatter/summary_formatter.js +4 -0
  26. package/lib/formatter/summary_formatter.js.map +1 -1
  27. package/lib/runtime/test_case_runner.d.ts +1 -0
  28. package/lib/runtime/test_case_runner.js +10 -1
  29. package/lib/runtime/test_case_runner.js.map +1 -1
  30. package/lib/version.d.ts +1 -1
  31. package/lib/version.js +1 -1
  32. package/lib/version.js.map +1 -1
  33. package/package.json +4 -2
@@ -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");
10
- const URL = process.env.NODE_ENV_BLINQ === 'dev'
11
- ? 'https://dev.api.blinq.io/api/runs'
12
- : process.env.NODE_ENV_BLINQ === 'local'
13
- ? 'http://localhost:5001/api/runs'
14
- : process.env.NODE_ENV_BLINQ === 'stage'
15
- ? 'https://stage.api.blinq.io/api/runs'
16
- : 'https://api.blinq.io/api/runs';
34
+ const fs_extra_1 = require("fs-extra");
35
+ // type JsonException = messages.Exception
36
+ const object_path_1 = __importDefault(require("object-path"));
37
+ const URL = process.env.NODE_ENV_BLINQ === "dev"
38
+ ? "https://dev.api.blinq.io/api/runs"
39
+ : process.env.NODE_ENV_BLINQ === "local"
40
+ ? "http://localhost:5001/api/runs"
41
+ : process.env.NODE_ENV_BLINQ === "stage"
42
+ ? "https://stage.api.blinq.io/api/runs"
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;
@@ -22,12 +53,12 @@ class ReportGenerator {
22
53
  constructor() {
23
54
  this.report = {
24
55
  result: {
25
- status: 'UNKNOWN',
56
+ status: "UNKNOWN",
26
57
  },
27
58
  testCases: [],
28
59
  env: {
29
- name: '',
30
- baseUrl: '',
60
+ name: "",
61
+ baseUrl: "",
31
62
  },
32
63
  };
33
64
  this.gherkinDocumentMap = new Map();
@@ -40,72 +71,98 @@ class ReportGenerator {
40
71
  this.scenarioIterationCountMap = new Map();
41
72
  this.logs = [];
42
73
  this.networkLog = [];
43
- this.runName = '';
74
+ this.stepLogs = [];
75
+ this.stepNetworkLogs = [];
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);
46
83
  }
47
- async handleMessage(envelope) {
48
- if (envelope.meta && envelope.meta.runName) {
84
+ async handleMessage(envelope, reRunId) {
85
+ if (envelope.meta && "runName" in envelope.meta) {
49
86
  this.runName = envelope.meta.runName;
50
87
  }
51
88
  const type = Object.keys(envelope)[0];
52
89
  switch (type) {
53
90
  // case "meta": { break}
54
91
  // case "source": { break}
55
- case 'parseError': {
92
+ case "parseError": {
56
93
  const parseError = envelope[type];
57
94
  this.handleParseError(parseError);
58
95
  break;
59
96
  }
60
- case 'gherkinDocument': {
97
+ case "gherkinDocument": {
61
98
  const doc = envelope[type];
62
99
  this.onGherkinDocument(doc);
63
100
  break;
64
101
  }
65
- case 'pickle': {
102
+ case "pickle": {
66
103
  const pickle = envelope[type];
67
104
  this.onPickle(pickle);
68
105
  break;
69
106
  }
70
107
  // case "stepDefinition": { break}
71
108
  // case "hook": { break} // Before Hook
72
- case 'testRunStarted': {
109
+ case "testRunStarted": {
73
110
  const testRunStarted = envelope[type];
74
111
  this.onTestRunStarted(testRunStarted);
75
112
  break;
76
113
  }
77
- case 'testCase': {
114
+ case "testCase": {
78
115
  const testCase = envelope[type];
116
+ // Initialize the log storage
117
+ this.testCaseLog = [];
118
+ if (!this.loggingOverridden) {
119
+ this.loggingOverridden = true;
120
+ // Store the original process.stdout.write, and process.stderr.write
121
+ const originalStdoutWrite = process.stdout.write;
122
+ const originalStderrWrite = process.stderr.write;
123
+ // Override process.stdout.write
124
+ process.stdout.write = (chunk, ...args) => {
125
+ this.testCaseLog.push(chunk.toString());
126
+ return originalStdoutWrite.call(process.stdout, chunk, ...args);
127
+ };
128
+ // Override process.stderr.write
129
+ process.stderr.write = (chunk, ...args) => {
130
+ this.testCaseLog.push(chunk.toString());
131
+ return originalStderrWrite.call(process.stderr, chunk, ...args);
132
+ };
133
+ }
134
+ // Call the onTestCase method
79
135
  this.onTestCase(testCase);
80
136
  break;
81
137
  }
82
- case 'testCaseStarted': {
138
+ case "testCaseStarted": {
83
139
  const testCaseStarted = envelope[type];
84
140
  this.onTestCaseStarted(testCaseStarted);
85
141
  break;
86
142
  }
87
- case 'testStepStarted': {
143
+ case "testStepStarted": {
88
144
  const testStepStarted = envelope[type];
89
145
  this.onTestStepStarted(testStepStarted);
90
146
  break;
91
147
  }
92
- case 'attachment': {
148
+ case "attachment": {
93
149
  const attachment = envelope[type];
94
150
  this.onAttachment(attachment);
95
151
  break;
96
152
  }
97
- case 'testStepFinished': {
153
+ case "testStepFinished": {
98
154
  const testStepFinished = envelope[type];
99
155
  this.onTestStepFinished(testStepFinished);
100
156
  break;
101
157
  }
102
- case 'testCaseFinished': {
158
+ case "testCaseFinished": {
103
159
  const testCaseFinished = envelope[type];
104
- await this.onTestCaseFinished(testCaseFinished);
105
- break;
160
+ // Call the onTestCaseFinished method
161
+ const result = await this.onTestCaseFinished(testCaseFinished, reRunId);
162
+ return result;
106
163
  }
107
164
  // case "hook": { break} // After Hook
108
- case 'testRunFinished': {
165
+ case "testRunFinished": {
109
166
  const testRunFinished = envelope[type];
110
167
  this.onTestRunFinished(testRunFinished);
111
168
  break;
@@ -121,7 +178,7 @@ class ReportGenerator {
121
178
  const { message } = parseError;
122
179
  const timestamp = new Date().getTime();
123
180
  this.report.result = {
124
- status: 'FAILED',
181
+ status: "FAILED",
125
182
  startTime: timestamp,
126
183
  endTime: timestamp,
127
184
  message: message,
@@ -164,7 +221,7 @@ class ReportGenerator {
164
221
  }
165
222
  onTestRunStarted(testRunStarted) {
166
223
  this.report.result = {
167
- status: 'STARTED',
224
+ status: "STARTED",
168
225
  startTime: this.getTimeStamp(testRunStarted.timestamp),
169
226
  };
170
227
  }
@@ -197,8 +254,7 @@ class ReportGenerator {
197
254
  for (const tableRow of examples.tableBody) {
198
255
  if (tableRow.id === exampleId) {
199
256
  for (let i = 0; i < examples.tableHeader.cells.length; i++) {
200
- parameters[examples.tableHeader.cells[i].value] =
201
- tableRow.cells[i].value;
257
+ parameters[examples.tableHeader.cells[i].value] = tableRow.cells[i].value;
202
258
  }
203
259
  }
204
260
  }
@@ -236,8 +292,12 @@ class ReportGenerator {
236
292
  text: step.text,
237
293
  commands: [],
238
294
  result: {
239
- status: 'UNKNOWN',
295
+ status: "UNKNOWN",
240
296
  },
297
+ networkData: [],
298
+ webLog: [],
299
+ data: {},
300
+ ariaSnapshot: this.ariaSnapshot,
241
301
  });
242
302
  return this.stepReportMap.get(pickleStep.id);
243
303
  });
@@ -249,11 +309,15 @@ class ReportGenerator {
249
309
  parameters,
250
310
  steps,
251
311
  result: {
252
- status: 'STARTED',
312
+ status: "STARTED",
253
313
  startTime: this.getTimeStamp(timestamp),
254
314
  },
255
315
  webLog: [],
256
316
  networkLog: [],
317
+ env: {
318
+ name: this.report.env.name,
319
+ baseUrl: this.report.env.baseUrl,
320
+ },
257
321
  });
258
322
  this.report.testCases.push(this.testCaseReportMap.get(id));
259
323
  }
@@ -266,48 +330,113 @@ class ReportGenerator {
266
330
  return;
267
331
  const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
268
332
  stepProgess.result = {
269
- status: 'STARTED',
333
+ status: "STARTED",
270
334
  startTime: this.getTimeStamp(timestamp),
271
335
  };
272
336
  }
273
337
  onAttachment(attachment) {
274
338
  const { testStepId, body, mediaType } = attachment;
275
- if (mediaType === 'text/plain') {
276
- this.reportFolder = body.replaceAll('\\', '/');
339
+ if (mediaType === "text/plain") {
340
+ this.reportFolder = body.replaceAll("\\", "/");
341
+ return;
342
+ }
343
+ if (mediaType === "application/json+snapshot-before") {
344
+ this.initialAriaSnapshot = body;
277
345
  return;
278
346
  }
279
- if (mediaType === 'application/json+env') {
347
+ if (mediaType === "application/json+snapshot-after") {
348
+ this.ariaSnapshot = body;
349
+ return;
350
+ }
351
+ if (mediaType === "application/json+env") {
280
352
  const data = JSON.parse(body);
281
353
  this.report.env = data;
354
+ this.report.testCases.map((testCase) => {
355
+ testCase.env = data;
356
+ return testCase;
357
+ });
282
358
  }
283
- if (mediaType === 'application/json+log') {
359
+ if (mediaType === "application/json+log") {
284
360
  const log = JSON.parse(body);
285
- if (this.logs.length < 1000)
361
+ if (this.logs.length < 1000) {
286
362
  this.logs.push(log);
363
+ this.stepLogs.push(log);
364
+ }
287
365
  }
288
- if (mediaType === 'application/json+network') {
366
+ if (mediaType === "application/json+network") {
289
367
  const networkLog = JSON.parse(body);
290
368
  if (this.networkLog.length < 1000)
291
369
  this.networkLog.push(networkLog);
370
+ this.stepNetworkLogs.push(networkLog);
292
371
  }
293
372
  const testStep = this.testStepMap.get(testStepId);
294
373
  if (testStep.pickleStepId === undefined)
295
374
  return;
296
375
  const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
297
- if (mediaType === 'application/json') {
376
+ if (mediaType === "application/json") {
298
377
  const command = JSON.parse(body);
299
378
  stepProgess.commands.push(command);
300
379
  }
380
+ else if (mediaType === "application/json+trace") {
381
+ const data = JSON.parse(body);
382
+ stepProgess.traceFilePath = data.traceFilePath;
383
+ }
384
+ if (mediaType === "application/json+bruno") {
385
+ try {
386
+ const data = JSON.parse(body);
387
+ stepProgess.brunoData = data;
388
+ }
389
+ catch (error) {
390
+ console.error("Error parsing bruno data:", error);
391
+ }
392
+ }
393
+ }
394
+ getFailedTestStepResult({ commands, startTime, endTime, result, }) {
395
+ for (const command of commands) {
396
+ if (command.result.status === "FAILED") {
397
+ return {
398
+ status: "FAILED",
399
+ message: command.result.message,
400
+ startTime,
401
+ endTime,
402
+ };
403
+ }
404
+ }
405
+ return {
406
+ status: "FAILED",
407
+ startTime,
408
+ endTime,
409
+ message: result.message,
410
+ };
301
411
  }
302
412
  onTestStepFinished(testStepFinished) {
303
413
  const { testStepId, testStepResult, timestamp } = testStepFinished;
304
414
  const testStep = this.testStepMap.get(testStepId);
305
415
  if (testStep.pickleStepId === undefined) {
306
- if (testStepResult.status === 'FAILED') {
416
+ if (testStepResult.status === "FAILED") {
307
417
  console.error(`Before/After hook failed with message: ${testStepResult.message}`);
308
418
  }
309
419
  return;
310
420
  }
421
+ if (testStepResult.status === "UNDEFINED") {
422
+ const step = this.stepReportMap.get(testStep.pickleStepId);
423
+ const stepName = step ? step.keyword + " " + step.text : "Undefined step";
424
+ const undefinedCommand = {
425
+ testStepId: testStepId,
426
+ body: JSON.stringify({
427
+ type: "error",
428
+ text: "Undefined step: " + stepName,
429
+ result: {
430
+ status: "FAILED",
431
+ startTime: this.getTimeStamp(timestamp),
432
+ endTime: this.getTimeStamp(timestamp),
433
+ },
434
+ }),
435
+ mediaType: "application/json",
436
+ contentEncoding: messages.AttachmentContentEncoding.IDENTITY,
437
+ };
438
+ this.onAttachment(undefinedCommand);
439
+ }
311
440
  const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
312
441
  const prevStepResult = stepProgess.result;
313
442
  let data = {};
@@ -316,30 +445,85 @@ class ReportGenerator {
316
445
  if (reportFolder === null) {
317
446
  throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
318
447
  }
319
- if (fs_1.default.existsSync(path_1.default.join(reportFolder, 'data.json'))) {
320
- data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder, 'data.json'), 'utf8'));
448
+ if (fs_1.default.existsSync(path_1.default.join(reportFolder, "data.json"))) {
449
+ data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder, "data.json"), "utf8"));
321
450
  }
322
451
  }
323
452
  catch (error) {
324
- console.log('Error reading data.json');
453
+ console.log("Error reading data.json");
325
454
  }
326
- stepProgess.result = {
327
- status: testStepResult.status,
328
- startTime: prevStepResult.startTime,
329
- endTime: this.getTimeStamp(timestamp),
330
- message: testStepResult.message,
331
- // exception: testStepResult.exception,
332
- };
455
+ if (testStepResult.status === "FAILED") {
456
+ stepProgess.result = this.getFailedTestStepResult({
457
+ commands: stepProgess.commands,
458
+ startTime: prevStepResult.startTime,
459
+ endTime: this.getTimeStamp(timestamp),
460
+ result: testStepResult,
461
+ });
462
+ }
463
+ else {
464
+ stepProgess.result = {
465
+ status: testStepResult.status,
466
+ startTime: prevStepResult.startTime,
467
+ endTime: this.getTimeStamp(timestamp),
468
+ };
469
+ }
470
+ stepProgess.webLog = this.stepLogs;
471
+ stepProgess.networkData = this.stepNetworkLogs;
472
+ stepProgess.ariaSnapshot = this.ariaSnapshot;
473
+ this.ariaSnapshot = "";
474
+ this.stepNetworkLogs = [];
475
+ this.stepLogs = [];
333
476
  if (Object.keys(data).length > 0) {
334
477
  stepProgess.data = data;
478
+ const id = testStepFinished.testCaseStartedId;
479
+ const parameters = this.testCaseReportMap.get(id).parameters;
480
+ const _parameters = {};
481
+ Object.keys(parameters).map((key) => {
482
+ if (parameters[key].startsWith("{{") && parameters[key].endsWith("}}")) {
483
+ const path = parameters[key].slice(2, -2).split(".");
484
+ let value = String(object_path_1.default.get(data, path));
485
+ if (value) {
486
+ if (value.startsWith("secret:")) {
487
+ value = "secret:****";
488
+ }
489
+ else if (value.startsWith("totp:")) {
490
+ value = "totp:****";
491
+ }
492
+ else if (value.startsWith("mask:")) {
493
+ value = "mask:****";
494
+ }
495
+ _parameters[key] = value;
496
+ }
497
+ }
498
+ else {
499
+ _parameters[key] = parameters[key];
500
+ }
501
+ });
502
+ this.report.testCases.find((testCase) => {
503
+ return testCase.id === id;
504
+ }).parameters = _parameters;
335
505
  }
506
+ // if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
507
+ // this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH
508
+ // if (!fs.existsSync(this.reportFolder)) {
509
+ // fs.mkdirSync(this.reportFolder)
510
+ // }
511
+ // const reportFilePath = path.join(
512
+ // this.reportFolder,
513
+ // `report.json`
514
+ // )
515
+ // writeFileSync(reportFilePath, JSON.stringify(this.report, null, 2))
516
+ // return undefined
517
+ // // } else {
518
+ // // return await this.uploadTestCase(testProgress, reRunId)
519
+ // }
336
520
  }
337
521
  getLogFileContent() {
338
522
  let projectPath = process.cwd();
339
523
  if (process.env.PROJECT_PATH) {
340
524
  projectPath = process.env.PROJECT_PATH;
341
525
  }
342
- const logFolder = path_1.default.join(projectPath, 'logs', 'web');
526
+ const logFolder = path_1.default.join(projectPath, "logs", "web");
343
527
  if (!fs_1.default.existsSync(logFolder)) {
344
528
  return [];
345
529
  }
@@ -351,7 +535,7 @@ class ReportGenerator {
351
535
  return [];
352
536
  }
353
537
  try {
354
- const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`), 'utf8');
538
+ const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`), "utf8");
355
539
  return JSON.parse(logFileContent);
356
540
  }
357
541
  catch (error) {
@@ -361,47 +545,82 @@ class ReportGenerator {
361
545
  getTestCaseResult(steps) {
362
546
  for (const step of steps) {
363
547
  switch (step.result.status) {
364
- case 'FAILED':
548
+ case "FAILED":
365
549
  return {
366
550
  status: step.result.status,
367
551
  message: step.result.message,
368
552
  // exception: step.result.exception,
369
553
  };
370
- case 'AMBIGUOUS':
371
- case 'UNDEFINED':
372
- case 'PENDING':
554
+ case "AMBIGUOUS":
555
+ case "UNDEFINED":
556
+ case "PENDING":
373
557
  return {
374
- status: 'FAILED',
558
+ status: "FAILED",
375
559
  message: `step "${step.text}" is ${step.result.status}`,
376
560
  };
377
561
  }
378
562
  }
379
563
  return {
380
- status: 'PASSED',
564
+ status: "PASSED",
381
565
  };
382
566
  }
383
- async onTestCaseFinished(testCaseFinished) {
567
+ async onTestCaseFinished(testCaseFinished, reRunId) {
384
568
  const { testCaseStartedId, timestamp } = testCaseFinished;
385
569
  const testProgress = this.testCaseReportMap.get(testCaseStartedId);
386
570
  const prevResult = testProgress.result;
387
571
  const steps = Object.values(testProgress.steps);
388
572
  const result = this.getTestCaseResult(steps);
573
+ const endTime = this.getTimeStamp(timestamp);
389
574
  testProgress.result = {
390
575
  ...result,
391
576
  startTime: prevResult.startTime,
392
- endTime: this.getTimeStamp(timestamp),
577
+ endTime,
393
578
  };
394
579
  testProgress.webLog = this.logs;
395
580
  testProgress.networkLog = this.networkLog;
581
+ testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
582
+ this.initialAriaSnapshot = "";
396
583
  this.networkLog = [];
397
584
  this.logs = [];
398
- await this.uploadTestCase(testProgress);
585
+ if (this.testCaseLog && this.testCaseLog.length > 0) {
586
+ // Create the logs directory
587
+ const logsDir = path_1.default.join(this.reportFolder, 'editorLogs');
588
+ const fileName = `testCaseLog_${testCaseStartedId}.log`;
589
+ const filePath = path_1.default.join(logsDir, fileName);
590
+ // Ensure the logs directory exists
591
+ fs_1.default.mkdirSync(logsDir, { recursive: true });
592
+ // Write the logs to the file
593
+ fs_1.default.writeFileSync(filePath, this.testCaseLog.join('\n'), 'utf8');
594
+ // Store this ID in the testProgress object so it can be accessed later
595
+ testProgress.logFileId = testCaseStartedId;
596
+ }
597
+ this.testCaseLog = [];
598
+ if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
599
+ this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH;
600
+ if (!fs_1.default.existsSync(this.reportFolder)) {
601
+ fs_1.default.mkdirSync(this.reportFolder);
602
+ }
603
+ const reportFilePath = path_1.default.join(this.reportFolder, `${endTime}_${testProgress.scenarioName}.json`);
604
+ (0, fs_extra_1.writeFileSync)(reportFilePath, JSON.stringify(testProgress, null, 2));
605
+ return undefined;
606
+ }
607
+ else {
608
+ return await this.uploadTestCase(testProgress, reRunId);
609
+ }
399
610
  }
400
- async uploadTestCase(testCase) {
401
- let runId = '';
402
- let projectId = '';
611
+ async uploadTestCase(testCase, rerunId) {
612
+ let runId = "";
613
+ let projectId = "";
614
+ if (!process.env.UPLOADING_TEST_CASE) {
615
+ process.env.UPLOADING_TEST_CASE = "[]";
616
+ }
617
+ const anyRemArr = JSON.parse(process.env.UPLOADING_TEST_CASE);
618
+ const randomID = Math.random().toString(36).substring(7);
619
+ anyRemArr.push(randomID);
620
+ let data;
621
+ process.env.UPLOADING_TEST_CASE = JSON.stringify(anyRemArr);
403
622
  try {
404
- if (process.env.RUN_ID && process.env.PROJECT_ID) {
623
+ if (process.env.RUN_ID && process.env.PROJECT_ID && !process.env.IGNORE_ENV_VARIABLES) {
405
624
  runId = process.env.RUN_ID;
406
625
  projectId = process.env.PROJECT_ID;
407
626
  }
@@ -409,20 +628,52 @@ class ReportGenerator {
409
628
  const runDoc = await this.uploadService.createRunDocument(this.runName);
410
629
  runId = runDoc._id;
411
630
  projectId = runDoc.project_id;
412
- process.env.RUN_ID = runId;
413
- process.env.PROJECT_ID = projectId;
631
+ if (!process.env.IGNORE_ENV_VARIABLES) {
632
+ process.env.RUN_ID = runId;
633
+ process.env.PROJECT_ID = projectId;
634
+ }
414
635
  }
415
- await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder);
636
+ data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
637
+ this.writeTestCaseReportToDisk(testCase);
416
638
  }
417
639
  catch (e) {
418
- console.error('Error uploading test case:', e);
640
+ console.error("Error uploading test case:", e);
641
+ }
642
+ finally {
643
+ const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
644
+ arrRem.splice(arrRem.indexOf(randomID), 1);
645
+ process.env.UPLOADING_TEST_CASE = JSON.stringify(arrRem);
646
+ }
647
+ return data ? data : null;
648
+ }
649
+ writeTestCaseReportToDisk(testCase) {
650
+ var _a;
651
+ const reportFolder = (_a = this.reportFolder) !== null && _a !== void 0 ? _a : process.env.TESTCASE_REPORT_FOLDER_PATH;
652
+ if (!reportFolder) {
653
+ console.error("Report folder is not defined");
654
+ return;
655
+ }
656
+ try {
657
+ let i = 0;
658
+ while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
659
+ i++;
660
+ }
661
+ fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
662
+ //exclude network log from the saved report
663
+ const networkLog = testCase.networkLog;
664
+ delete testCase.networkLog;
665
+ fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
666
+ fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
667
+ }
668
+ catch (error) {
669
+ console.error("Error writing test case report to disk:", error);
419
670
  }
420
671
  }
421
672
  onTestRunFinished(testRunFinished) {
422
673
  const { timestamp, success, message } = testRunFinished;
423
674
  const prevResult = this.report.result;
424
675
  this.report.result = {
425
- status: success ? 'PASSED' : 'FAILED',
676
+ status: success ? "PASSED" : "FAILED",
426
677
  startTime: prevResult.startTime,
427
678
  endTime: this.getTimeStamp(timestamp),
428
679
  message,