@dev-blinq/cucumber-js 1.0.83-main → 1.0.83-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.
Files changed (32) hide show
  1. package/bin/download-install.js +31 -19
  2. package/lib/formatter/api.d.ts +2 -0
  3. package/lib/formatter/api.js +59 -0
  4. package/lib/formatter/api.js.map +1 -0
  5. package/lib/formatter/bvt_analysis_formatter.d.ts +13 -1
  6. package/lib/formatter/bvt_analysis_formatter.js +197 -71
  7. package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
  8. package/lib/formatter/feature_data_format.js +14 -1
  9. package/lib/formatter/feature_data_format.js.map +1 -1
  10. package/lib/formatter/helpers/constants.d.ts +50 -0
  11. package/lib/formatter/helpers/constants.js +60 -0
  12. package/lib/formatter/helpers/constants.js.map +1 -0
  13. package/lib/formatter/helpers/report_generator.d.ts +40 -13
  14. package/lib/formatter/helpers/report_generator.js +353 -58
  15. package/lib/formatter/helpers/report_generator.js.map +1 -1
  16. package/lib/formatter/helpers/test_case_attempt_formatter.js +1 -1
  17. package/lib/formatter/helpers/test_case_attempt_formatter.js.map +1 -1
  18. package/lib/formatter/helpers/upload_serivce.d.ts +16 -3
  19. package/lib/formatter/helpers/upload_serivce.js +176 -34
  20. package/lib/formatter/helpers/upload_serivce.js.map +1 -1
  21. package/lib/formatter/helpers/uploader.d.ts +2 -1
  22. package/lib/formatter/helpers/uploader.js +63 -18
  23. package/lib/formatter/helpers/uploader.js.map +1 -1
  24. package/lib/formatter/summary_formatter.js +4 -0
  25. package/lib/formatter/summary_formatter.js.map +1 -1
  26. package/lib/runtime/test_case_runner.d.ts +1 -0
  27. package/lib/runtime/test_case_runner.js +10 -1
  28. package/lib/runtime/test_case_runner.js.map +1 -1
  29. package/lib/version.d.ts +1 -1
  30. package/lib/version.js +1 -1
  31. package/lib/version.js.map +1 -1
  32. package/package.json +4 -2
@@ -1,20 +1,64 @@
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
  };
28
+ var _a, _b;
5
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
+ const messages = __importStar(require("@cucumber/messages"));
6
31
  const fs_1 = __importDefault(require("fs"));
7
32
  const path_1 = __importDefault(require("path"));
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"));
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`;
48
+ const REPORT_SERVICE_URL = (_a = process.env.REPORT_SERVICE_URL) !== null && _a !== void 0 ? _a : URL;
49
+ const BATCH_SIZE = 10;
50
+ const MAX_RETRIES = 3;
51
+ const REPORT_SERVICE_TOKEN = (_b = process.env.TOKEN) !== null && _b !== void 0 ? _b : process.env.REPORT_SERVICE_TOKEN;
8
52
  class ReportGenerator {
9
53
  constructor() {
10
54
  this.report = {
11
55
  result: {
12
- status: 'UNKNOWN',
56
+ status: "UNKNOWN",
13
57
  },
14
58
  testCases: [],
15
59
  env: {
16
- name: '',
17
- baseUrl: '',
60
+ name: "",
61
+ baseUrl: "",
18
62
  },
19
63
  };
20
64
  this.gherkinDocumentMap = new Map();
@@ -27,67 +71,98 @@ class ReportGenerator {
27
71
  this.scenarioIterationCountMap = new Map();
28
72
  this.logs = [];
29
73
  this.networkLog = [];
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
30
81
  this.reportFolder = null;
82
+ this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
31
83
  }
32
- handleMessage(envelope) {
84
+ async handleMessage(envelope, reRunId) {
85
+ if (envelope.meta && "runName" in envelope.meta) {
86
+ this.runName = envelope.meta.runName;
87
+ }
33
88
  const type = Object.keys(envelope)[0];
34
89
  switch (type) {
35
90
  // case "meta": { break}
36
91
  // case "source": { break}
37
- case 'parseError': {
92
+ case "parseError": {
38
93
  const parseError = envelope[type];
39
94
  this.handleParseError(parseError);
40
95
  break;
41
96
  }
42
- case 'gherkinDocument': {
97
+ case "gherkinDocument": {
43
98
  const doc = envelope[type];
44
99
  this.onGherkinDocument(doc);
45
100
  break;
46
101
  }
47
- case 'pickle': {
102
+ case "pickle": {
48
103
  const pickle = envelope[type];
49
104
  this.onPickle(pickle);
50
105
  break;
51
106
  }
52
107
  // case "stepDefinition": { break}
53
108
  // case "hook": { break} // Before Hook
54
- case 'testRunStarted': {
109
+ case "testRunStarted": {
55
110
  const testRunStarted = envelope[type];
56
111
  this.onTestRunStarted(testRunStarted);
57
112
  break;
58
113
  }
59
- case 'testCase': {
114
+ case "testCase": {
60
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
61
135
  this.onTestCase(testCase);
62
136
  break;
63
137
  }
64
- case 'testCaseStarted': {
138
+ case "testCaseStarted": {
65
139
  const testCaseStarted = envelope[type];
66
140
  this.onTestCaseStarted(testCaseStarted);
67
141
  break;
68
142
  }
69
- case 'testStepStarted': {
143
+ case "testStepStarted": {
70
144
  const testStepStarted = envelope[type];
71
145
  this.onTestStepStarted(testStepStarted);
72
146
  break;
73
147
  }
74
- case 'attachment': {
148
+ case "attachment": {
75
149
  const attachment = envelope[type];
76
150
  this.onAttachment(attachment);
77
151
  break;
78
152
  }
79
- case 'testStepFinished': {
153
+ case "testStepFinished": {
80
154
  const testStepFinished = envelope[type];
81
155
  this.onTestStepFinished(testStepFinished);
82
156
  break;
83
157
  }
84
- case 'testCaseFinished': {
158
+ case "testCaseFinished": {
85
159
  const testCaseFinished = envelope[type];
86
- this.onTestCaseFinished(testCaseFinished);
87
- break;
160
+ // Call the onTestCaseFinished method
161
+ const result = await this.onTestCaseFinished(testCaseFinished, reRunId);
162
+ return result;
88
163
  }
89
164
  // case "hook": { break} // After Hook
90
- case 'testRunFinished': {
165
+ case "testRunFinished": {
91
166
  const testRunFinished = envelope[type];
92
167
  this.onTestRunFinished(testRunFinished);
93
168
  break;
@@ -103,7 +178,7 @@ class ReportGenerator {
103
178
  const { message } = parseError;
104
179
  const timestamp = new Date().getTime();
105
180
  this.report.result = {
106
- status: 'FAILED',
181
+ status: "FAILED",
107
182
  startTime: timestamp,
108
183
  endTime: timestamp,
109
184
  message: message,
@@ -146,7 +221,7 @@ class ReportGenerator {
146
221
  }
147
222
  onTestRunStarted(testRunStarted) {
148
223
  this.report.result = {
149
- status: 'STARTED',
224
+ status: "STARTED",
150
225
  startTime: this.getTimeStamp(testRunStarted.timestamp),
151
226
  };
152
227
  }
@@ -179,8 +254,7 @@ class ReportGenerator {
179
254
  for (const tableRow of examples.tableBody) {
180
255
  if (tableRow.id === exampleId) {
181
256
  for (let i = 0; i < examples.tableHeader.cells.length; i++) {
182
- parameters[examples.tableHeader.cells[i].value] =
183
- tableRow.cells[i].value;
257
+ parameters[examples.tableHeader.cells[i].value] = tableRow.cells[i].value;
184
258
  }
185
259
  }
186
260
  }
@@ -218,8 +292,12 @@ class ReportGenerator {
218
292
  text: step.text,
219
293
  commands: [],
220
294
  result: {
221
- status: 'UNKNOWN',
295
+ status: "UNKNOWN",
222
296
  },
297
+ networkData: [],
298
+ webLog: [],
299
+ data: {},
300
+ ariaSnapshot: this.ariaSnapshot,
223
301
  });
224
302
  return this.stepReportMap.get(pickleStep.id);
225
303
  });
@@ -231,11 +309,15 @@ class ReportGenerator {
231
309
  parameters,
232
310
  steps,
233
311
  result: {
234
- status: 'STARTED',
312
+ status: "STARTED",
235
313
  startTime: this.getTimeStamp(timestamp),
236
314
  },
237
315
  webLog: [],
238
316
  networkLog: [],
317
+ env: {
318
+ name: this.report.env.name,
319
+ baseUrl: this.report.env.baseUrl,
320
+ },
239
321
  });
240
322
  this.report.testCases.push(this.testCaseReportMap.get(id));
241
323
  }
@@ -248,78 +330,200 @@ class ReportGenerator {
248
330
  return;
249
331
  const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
250
332
  stepProgess.result = {
251
- status: 'STARTED',
333
+ status: "STARTED",
252
334
  startTime: this.getTimeStamp(timestamp),
253
335
  };
254
336
  }
255
337
  onAttachment(attachment) {
256
338
  const { testStepId, body, mediaType } = attachment;
257
- if (mediaType === 'text/plain') {
258
- 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;
345
+ return;
346
+ }
347
+ if (mediaType === "application/json+snapshot-after") {
348
+ this.ariaSnapshot = body;
259
349
  return;
260
350
  }
261
- if (mediaType === 'application/json+env') {
351
+ if (mediaType === "application/json+env") {
262
352
  const data = JSON.parse(body);
263
353
  this.report.env = data;
354
+ this.report.testCases.map((testCase) => {
355
+ testCase.env = data;
356
+ return testCase;
357
+ });
264
358
  }
265
- if (mediaType === 'application/json+log') {
359
+ if (mediaType === "application/json+log") {
266
360
  const log = JSON.parse(body);
267
- this.logs.push(log);
361
+ if (this.logs.length < 1000) {
362
+ this.logs.push(log);
363
+ this.stepLogs.push(log);
364
+ }
268
365
  }
269
- if (mediaType === 'application/json+network') {
366
+ if (mediaType === "application/json+network") {
270
367
  const networkLog = JSON.parse(body);
271
- this.networkLog.push(networkLog);
368
+ if (this.networkLog.length < 1000)
369
+ this.networkLog.push(networkLog);
370
+ this.stepNetworkLogs.push(networkLog);
272
371
  }
273
372
  const testStep = this.testStepMap.get(testStepId);
274
373
  if (testStep.pickleStepId === undefined)
275
374
  return;
276
375
  const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
277
- if (mediaType === 'application/json') {
376
+ if (mediaType === "application/json") {
278
377
  const command = JSON.parse(body);
279
378
  stepProgess.commands.push(command);
280
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
+ };
281
411
  }
282
412
  onTestStepFinished(testStepFinished) {
283
413
  const { testStepId, testStepResult, timestamp } = testStepFinished;
284
414
  const testStep = this.testStepMap.get(testStepId);
285
415
  if (testStep.pickleStepId === undefined) {
286
- if (testStepResult.status === 'FAILED') {
416
+ if (testStepResult.status === "FAILED") {
287
417
  console.error(`Before/After hook failed with message: ${testStepResult.message}`);
288
418
  }
289
419
  return;
290
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
+ }
291
440
  const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
292
441
  const prevStepResult = stepProgess.result;
293
442
  let data = {};
294
- const reportFolder = this.reportFolder;
295
- if (reportFolder === null) {
296
- throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
297
- }
298
443
  try {
299
- if (fs_1.default.existsSync(path_1.default.join(reportFolder, 'data.json'))) {
300
- data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder, 'data.json'), 'utf8'));
444
+ const reportFolder = this.reportFolder;
445
+ if (reportFolder === null) {
446
+ throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
447
+ }
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"));
301
450
  }
302
451
  }
303
452
  catch (error) {
304
- console.log('Error reading data.json');
453
+ console.log("Error reading data.json");
305
454
  }
306
- stepProgess.result = {
307
- status: testStepResult.status,
308
- startTime: prevStepResult.startTime,
309
- endTime: this.getTimeStamp(timestamp),
310
- message: testStepResult.message,
311
- // exception: testStepResult.exception,
312
- };
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 = [];
313
476
  if (Object.keys(data).length > 0) {
314
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;
315
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
+ // }
316
520
  }
317
521
  getLogFileContent() {
318
522
  let projectPath = process.cwd();
319
523
  if (process.env.PROJECT_PATH) {
320
524
  projectPath = process.env.PROJECT_PATH;
321
525
  }
322
- const logFolder = path_1.default.join(projectPath, 'logs', 'web');
526
+ const logFolder = path_1.default.join(projectPath, "logs", "web");
323
527
  if (!fs_1.default.existsSync(logFolder)) {
324
528
  return [];
325
529
  }
@@ -331,7 +535,7 @@ class ReportGenerator {
331
535
  return [];
332
536
  }
333
537
  try {
334
- 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");
335
539
  return JSON.parse(logFileContent);
336
540
  }
337
541
  catch (error) {
@@ -341,44 +545,135 @@ class ReportGenerator {
341
545
  getTestCaseResult(steps) {
342
546
  for (const step of steps) {
343
547
  switch (step.result.status) {
344
- case 'FAILED':
548
+ case "FAILED":
345
549
  return {
346
550
  status: step.result.status,
347
551
  message: step.result.message,
348
552
  // exception: step.result.exception,
349
553
  };
350
- case 'AMBIGUOUS':
351
- case 'UNDEFINED':
352
- case 'PENDING':
554
+ case "AMBIGUOUS":
555
+ case "UNDEFINED":
556
+ case "PENDING":
353
557
  return {
354
- status: 'FAILED',
558
+ status: "FAILED",
355
559
  message: `step "${step.text}" is ${step.result.status}`,
356
560
  };
357
561
  }
358
562
  }
359
563
  return {
360
- status: 'PASSED',
564
+ status: "PASSED",
361
565
  };
362
566
  }
363
- onTestCaseFinished(testCaseFinished) {
567
+ async onTestCaseFinished(testCaseFinished, reRunId) {
364
568
  const { testCaseStartedId, timestamp } = testCaseFinished;
365
569
  const testProgress = this.testCaseReportMap.get(testCaseStartedId);
366
570
  const prevResult = testProgress.result;
367
571
  const steps = Object.values(testProgress.steps);
368
572
  const result = this.getTestCaseResult(steps);
573
+ const endTime = this.getTimeStamp(timestamp);
369
574
  testProgress.result = {
370
575
  ...result,
371
576
  startTime: prevResult.startTime,
372
- endTime: this.getTimeStamp(timestamp),
577
+ endTime,
373
578
  };
374
579
  testProgress.webLog = this.logs;
375
580
  testProgress.networkLog = this.networkLog;
581
+ testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
582
+ this.initialAriaSnapshot = "";
583
+ this.networkLog = [];
584
+ this.logs = [];
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
+ }
610
+ }
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);
622
+ try {
623
+ if (process.env.RUN_ID && process.env.PROJECT_ID && !process.env.IGNORE_ENV_VARIABLES) {
624
+ runId = process.env.RUN_ID;
625
+ projectId = process.env.PROJECT_ID;
626
+ }
627
+ else {
628
+ const runDoc = await this.uploadService.createRunDocument(this.runName);
629
+ runId = runDoc._id;
630
+ projectId = runDoc.project_id;
631
+ if (!process.env.IGNORE_ENV_VARIABLES) {
632
+ process.env.RUN_ID = runId;
633
+ process.env.PROJECT_ID = projectId;
634
+ }
635
+ }
636
+ data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
637
+ this.writeTestCaseReportToDisk(testCase);
638
+ }
639
+ catch (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);
670
+ }
376
671
  }
377
672
  onTestRunFinished(testRunFinished) {
378
673
  const { timestamp, success, message } = testRunFinished;
379
674
  const prevResult = this.report.result;
380
675
  this.report.result = {
381
- status: success ? 'PASSED' : 'FAILED',
676
+ status: success ? "PASSED" : "FAILED",
382
677
  startTime: prevResult.startTime,
383
678
  endTime: this.getTimeStamp(timestamp),
384
679
  message,