@dev-blinq/cucumber-js 1.0.93 → 1.0.94-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 +14 -2
  2. package/lib/cli/validate_node_engine_version.js +3 -1
  3. package/lib/cli/validate_node_engine_version.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 +12 -1
  7. package/lib/formatter/bvt_analysis_formatter.js +137 -50
  8. package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
  9. package/lib/formatter/feature_data_format.js +0 -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 +17 -1
  15. package/lib/formatter/helpers/report_generator.js +286 -25
  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 +14 -1
  20. package/lib/formatter/helpers/upload_serivce.js +86 -4
  21. package/lib/formatter/helpers/upload_serivce.js.map +1 -1
  22. package/lib/formatter/helpers/uploader.js +11 -14
  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 +3 -1
@@ -0,0 +1,50 @@
1
+ export declare const LOCAL: {
2
+ SSO: string;
3
+ WORKSPACE: string;
4
+ RUNS: string;
5
+ STORAGE: string;
6
+ };
7
+ export declare const DEV: {
8
+ SSO: string;
9
+ WORKSPACE: string;
10
+ RUNS: string;
11
+ STORAGE: string;
12
+ };
13
+ export declare const PROD: {
14
+ SSO: string;
15
+ WORKSPACE: string;
16
+ RUNS: string;
17
+ STORAGE: string;
18
+ };
19
+ export declare const STAGE: {
20
+ SSO: string;
21
+ WORKSPACE: string;
22
+ RUNS: string;
23
+ STORAGE: string;
24
+ };
25
+ export declare const CUSTOM: {
26
+ SSO: string;
27
+ WORKSPACE: string;
28
+ RUNS: string;
29
+ STORAGE: string;
30
+ };
31
+ export declare const SERVICES_URI: {
32
+ SSO: string;
33
+ WORKSPACE: string;
34
+ RUNS: string;
35
+ STORAGE: string;
36
+ };
37
+ export declare enum ActionEvents {
38
+ record_scenario = "record_scenario",
39
+ download_editor = "download_editor",
40
+ launch_editor = "launch_editor",
41
+ click_start_recording = "click_start_recording",
42
+ click_run_scenario = "click_run_scenario",
43
+ publish_scenario = "publish_scenario",
44
+ click_ai_generate = "click_ai_generate",
45
+ click_run_all = "click_run_all",
46
+ click_open_vscode = "click_open_vscode",
47
+ error_open_vscode = "error_open_vscode",
48
+ cli_run_tests = "cli_run_tests",
49
+ upload_report = "upload_report"
50
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionEvents = exports.SERVICES_URI = exports.CUSTOM = exports.STAGE = exports.PROD = exports.DEV = exports.LOCAL = void 0;
4
+ exports.LOCAL = {
5
+ SSO: 'http://localhost:5000/api/auth',
6
+ WORKSPACE: 'http://localhost:6000/api/workspace',
7
+ RUNS: 'http://localhost:5001/api/runs',
8
+ STORAGE: 'http://localhost:5050/api/storage',
9
+ };
10
+ exports.DEV = {
11
+ SSO: 'https://dev.api.blinq.io/api/auth',
12
+ WORKSPACE: 'https://dev.api.blinq.io/api/workspace',
13
+ RUNS: 'https://dev.api.blinq.io/api/runs',
14
+ STORAGE: 'https://dev.api.blinq.io/api/storage',
15
+ };
16
+ exports.PROD = {
17
+ SSO: 'https://api.blinq.io/api/auth',
18
+ WORKSPACE: 'https://api.blinq.io/api/workspace',
19
+ RUNS: 'https://api.blinq.io/api/runs',
20
+ STORAGE: 'https://api.blinq.io/api/storage',
21
+ };
22
+ exports.STAGE = {
23
+ SSO: 'https://stage.api.blinq.io/api/auth',
24
+ WORKSPACE: 'https://stage.api.blinq.io/api/workspace',
25
+ RUNS: 'https://stage.api.blinq.io/api/runs',
26
+ STORAGE: 'https://stage.api.blinq.io/api/storage',
27
+ };
28
+ exports.CUSTOM = {
29
+ SSO: `${process.env.NODE_ENV_BLINQ}/api/auth`,
30
+ WORKSPACE: `${process.env.NODE_ENV_BLINQ}/api/workspace`,
31
+ RUNS: `${process.env.NODE_ENV_BLINQ}/api/runs`,
32
+ STORAGE: `${process.env.NODE_ENV_BLINQ}/api/storage`,
33
+ };
34
+ exports.SERVICES_URI = process.env.NODE_ENV_BLINQ === 'local'
35
+ ? exports.LOCAL // eslint-disable-line
36
+ : process.env.NODE_ENV_BLINQ === 'dev'
37
+ ? exports.DEV // eslint-disable-line
38
+ : process.env.NODE_ENV_BLINQ === 'stage'
39
+ ? exports.STAGE // eslint-disable-line
40
+ : process.env.NODE_ENV_BLINQ === 'prod'
41
+ ? exports.PROD // eslint-disable-line
42
+ : !process.env.NODE_ENV_BLINQ
43
+ ? exports.PROD // eslint-disable-line
44
+ : exports.CUSTOM; // eslint-disable-line
45
+ var ActionEvents;
46
+ (function (ActionEvents) {
47
+ ActionEvents["record_scenario"] = "record_scenario";
48
+ ActionEvents["download_editor"] = "download_editor";
49
+ ActionEvents["launch_editor"] = "launch_editor";
50
+ ActionEvents["click_start_recording"] = "click_start_recording";
51
+ ActionEvents["click_run_scenario"] = "click_run_scenario";
52
+ ActionEvents["publish_scenario"] = "publish_scenario";
53
+ ActionEvents["click_ai_generate"] = "click_ai_generate";
54
+ ActionEvents["click_run_all"] = "click_run_all";
55
+ ActionEvents["click_open_vscode"] = "click_open_vscode";
56
+ ActionEvents["error_open_vscode"] = "error_open_vscode";
57
+ ActionEvents["cli_run_tests"] = "cli_run_tests";
58
+ ActionEvents["upload_report"] = "upload_report";
59
+ })(ActionEvents = exports.ActionEvents || (exports.ActionEvents = {}));
60
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/formatter/helpers/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,KAAK,GAAG;IACnB,GAAG,EAAE,gCAAgC;IACrC,SAAS,EAAE,qCAAqC;IAChD,IAAI,EAAE,gCAAgC;IACtC,OAAO,EAAE,mCAAmC;CAC7C,CAAA;AACY,QAAA,GAAG,GAAG;IACjB,GAAG,EAAE,mCAAmC;IACxC,SAAS,EAAE,wCAAwC;IACnD,IAAI,EAAE,mCAAmC;IACzC,OAAO,EAAE,sCAAsC;CAChD,CAAA;AACY,QAAA,IAAI,GAAG;IAClB,GAAG,EAAE,+BAA+B;IACpC,SAAS,EAAE,oCAAoC;IAC/C,IAAI,EAAE,+BAA+B;IACrC,OAAO,EAAE,kCAAkC;CAC5C,CAAA;AACY,QAAA,KAAK,GAAG;IACnB,GAAG,EAAE,qCAAqC;IAC1C,SAAS,EAAE,0CAA0C;IACrD,IAAI,EAAE,qCAAqC;IAC3C,OAAO,EAAE,wCAAwC;CAClD,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,WAAW;IAC7C,SAAS,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,gBAAgB;IACxD,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,WAAW;IAC9C,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,cAAc;CACrD,CAAA;AAEY,QAAA,YAAY,GACvB,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,OAAO;IACpC,CAAC,CAAC,aAAK,CAAC,sBAAsB;IAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,KAAK;QACtC,CAAC,CAAC,WAAG,CAAC,sBAAsB;QAC5B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,OAAO;YACxC,CAAC,CAAC,aAAK,CAAC,sBAAsB;YAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM;gBACvC,CAAC,CAAC,YAAI,CAAC,sBAAsB;gBAC7B,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc;oBAC7B,CAAC,CAAC,YAAI,CAAC,sBAAsB;oBAC7B,CAAC,CAAC,cAAM,CAAA,CAAC,sBAAsB;AAEnC,IAAY,YAaX;AAbD,WAAY,YAAY;IACtB,mDAAmC,CAAA;IACnC,mDAAmC,CAAA;IACnC,+CAA+B,CAAA;IAC/B,+DAA+C,CAAA;IAC/C,yDAAyC,CAAA;IACzC,qDAAqC,CAAA;IACrC,uDAAuC,CAAA;IACvC,+CAA+B,CAAA;IAC/B,uDAAuC,CAAA;IACvC,uDAAuC,CAAA;IACvC,+CAA+B,CAAA;IAC/B,+CAA+B,CAAA;AACjC,CAAC,EAbW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAavB","sourcesContent":["export const LOCAL = {\n SSO: 'http://localhost:5000/api/auth',\n WORKSPACE: 'http://localhost:6000/api/workspace',\n RUNS: 'http://localhost:5001/api/runs',\n STORAGE: 'http://localhost:5050/api/storage',\n}\nexport const DEV = {\n SSO: 'https://dev.api.blinq.io/api/auth',\n WORKSPACE: 'https://dev.api.blinq.io/api/workspace',\n RUNS: 'https://dev.api.blinq.io/api/runs',\n STORAGE: 'https://dev.api.blinq.io/api/storage',\n}\nexport const PROD = {\n SSO: 'https://api.blinq.io/api/auth',\n WORKSPACE: 'https://api.blinq.io/api/workspace',\n RUNS: 'https://api.blinq.io/api/runs',\n STORAGE: 'https://api.blinq.io/api/storage',\n}\nexport const STAGE = {\n SSO: 'https://stage.api.blinq.io/api/auth',\n WORKSPACE: 'https://stage.api.blinq.io/api/workspace',\n RUNS: 'https://stage.api.blinq.io/api/runs',\n STORAGE: 'https://stage.api.blinq.io/api/storage',\n}\n\nexport const CUSTOM = {\n SSO: `${process.env.NODE_ENV_BLINQ}/api/auth`,\n WORKSPACE: `${process.env.NODE_ENV_BLINQ}/api/workspace`,\n RUNS: `${process.env.NODE_ENV_BLINQ}/api/runs`,\n STORAGE: `${process.env.NODE_ENV_BLINQ}/api/storage`,\n}\n\nexport const SERVICES_URI =\n process.env.NODE_ENV_BLINQ === 'local'\n ? LOCAL // eslint-disable-line\n : process.env.NODE_ENV_BLINQ === 'dev'\n ? DEV // eslint-disable-line\n : process.env.NODE_ENV_BLINQ === 'stage'\n ? STAGE // eslint-disable-line\n : process.env.NODE_ENV_BLINQ === 'prod'\n ? PROD // eslint-disable-line\n : !process.env.NODE_ENV_BLINQ\n ? PROD // eslint-disable-line\n : CUSTOM // eslint-disable-line\n\nexport enum ActionEvents {\n record_scenario = 'record_scenario',\n download_editor = 'download_editor',\n launch_editor = 'launch_editor',\n click_start_recording = 'click_start_recording',\n click_run_scenario = 'click_run_scenario',\n publish_scenario = 'publish_scenario',\n click_ai_generate = 'click_ai_generate',\n click_run_all = 'click_run_all',\n click_open_vscode = 'click_open_vscode',\n error_open_vscode = 'error_open_vscode',\n cli_run_tests = 'cli_run_tests',\n upload_report = 'upload_report',\n}\n"]}
@@ -63,7 +63,12 @@ export type JsonStep = {
63
63
  commands: JsonCommand[];
64
64
  result: JsonStepResult;
65
65
  webLog: webLog[];
66
+ networkData: any[];
66
67
  data?: any;
68
+ ariaSnapshot: string;
69
+ traceFilePath?: string;
70
+ brunoData?: any;
71
+ interceptResults?: any;
67
72
  };
68
73
  export type RetrainStats = {
69
74
  result: JsonTestResult;
@@ -80,8 +85,10 @@ export type JsonTestProgress = {
80
85
  steps: JsonStep[];
81
86
  result: JsonTestResult;
82
87
  retrainStats?: RetrainStats;
88
+ initialAriaSnapshot?: string;
83
89
  webLog: any;
84
90
  networkLog: any;
91
+ logFileId?: string;
85
92
  env: {
86
93
  name: string;
87
94
  baseUrl: string;
@@ -114,10 +121,15 @@ export default class ReportGenerator {
114
121
  private logs;
115
122
  private networkLog;
116
123
  private stepLogs;
124
+ private stepNetworkLogs;
117
125
  private runName;
126
+ private ariaSnapshot;
127
+ private initialAriaSnapshot;
128
+ private testCaseLog;
129
+ private loggingOverridden;
118
130
  reportFolder: null | string;
119
131
  private uploadService;
120
- handleMessage(envelope: EnvelopeWithMetaMessage): Promise<void>;
132
+ handleMessage(envelope: EnvelopeWithMetaMessage | messages.Envelope, reRunId?: string): Promise<any>;
121
133
  getReport(): JsonReport;
122
134
  private handleParseError;
123
135
  private onGherkinDocument;
@@ -130,11 +142,15 @@ export default class ReportGenerator {
130
142
  private onTestCaseStarted;
131
143
  private onTestStepStarted;
132
144
  private onAttachment;
145
+ private getFailedTestStepResult;
133
146
  private onTestStepFinished;
134
147
  getLogFileContent(): any;
135
148
  private getTestCaseResult;
136
149
  private onTestCaseFinished;
150
+ private readonly retryCount;
137
151
  private uploadTestCase;
152
+ private tryUpload;
153
+ private writeTestCaseReportToDisk;
138
154
  private onTestRunFinished;
139
155
  }
140
156
  export {};
@@ -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
- : 'https://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;
@@ -41,12 +72,18 @@ class ReportGenerator {
41
72
  this.logs = [];
42
73
  this.networkLog = [];
43
74
  this.stepLogs = [];
75
+ this.stepNetworkLogs = [];
44
76
  this.runName = '';
77
+ this.ariaSnapshot = '';
78
+ this.initialAriaSnapshot = '';
79
+ this.testCaseLog = [];
80
+ this.loggingOverridden = false; // Flag to track if logging is overridden
45
81
  this.reportFolder = null;
46
82
  this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
83
+ this.retryCount = 3;
47
84
  }
48
- async handleMessage(envelope) {
49
- if (envelope.meta && envelope.meta.runName) {
85
+ async handleMessage(envelope, reRunId) {
86
+ if (envelope.meta && 'runName' in envelope.meta) {
50
87
  this.runName = envelope.meta.runName;
51
88
  }
52
89
  const type = Object.keys(envelope)[0];
@@ -73,10 +110,30 @@ class ReportGenerator {
73
110
  case 'testRunStarted': {
74
111
  const testRunStarted = envelope[type];
75
112
  this.onTestRunStarted(testRunStarted);
113
+ await this.uploadService.createStatus('running');
76
114
  break;
77
115
  }
78
116
  case 'testCase': {
79
117
  const testCase = envelope[type];
118
+ // Initialize the log storage
119
+ this.testCaseLog = [];
120
+ if (!this.loggingOverridden) {
121
+ this.loggingOverridden = true;
122
+ // Store the original process.stdout.write, and process.stderr.write
123
+ const originalStdoutWrite = process.stdout.write;
124
+ const originalStderrWrite = process.stderr.write;
125
+ // Override process.stdout.write
126
+ process.stdout.write = (chunk, ...args) => {
127
+ this.testCaseLog.push(chunk.toString());
128
+ return originalStdoutWrite.call(process.stdout, chunk, ...args);
129
+ };
130
+ // Override process.stderr.write
131
+ process.stderr.write = (chunk, ...args) => {
132
+ this.testCaseLog.push(chunk.toString());
133
+ return originalStderrWrite.call(process.stderr, chunk, ...args);
134
+ };
135
+ }
136
+ // Call the onTestCase method
80
137
  this.onTestCase(testCase);
81
138
  break;
82
139
  }
@@ -102,13 +159,14 @@ class ReportGenerator {
102
159
  }
103
160
  case 'testCaseFinished': {
104
161
  const testCaseFinished = envelope[type];
105
- await this.onTestCaseFinished(testCaseFinished);
106
- break;
162
+ // Call the onTestCaseFinished method
163
+ const result = await this.onTestCaseFinished(testCaseFinished, reRunId);
164
+ return result;
107
165
  }
108
166
  // case "hook": { break} // After Hook
109
167
  case 'testRunFinished': {
110
168
  const testRunFinished = envelope[type];
111
- this.onTestRunFinished(testRunFinished);
169
+ await this.onTestRunFinished(testRunFinished);
112
170
  break;
113
171
  }
114
172
  // case "parameterType" : { break}
@@ -239,7 +297,10 @@ class ReportGenerator {
239
297
  result: {
240
298
  status: 'UNKNOWN',
241
299
  },
300
+ networkData: [],
242
301
  webLog: [],
302
+ data: {},
303
+ ariaSnapshot: this.ariaSnapshot,
243
304
  });
244
305
  return this.stepReportMap.get(pickleStep.id);
245
306
  });
@@ -282,6 +343,14 @@ class ReportGenerator {
282
343
  this.reportFolder = body.replaceAll('\\', '/');
283
344
  return;
284
345
  }
346
+ if (mediaType === 'application/json+snapshot-before') {
347
+ this.initialAriaSnapshot = body;
348
+ return;
349
+ }
350
+ if (mediaType === 'application/json+snapshot-after') {
351
+ this.ariaSnapshot = body;
352
+ return;
353
+ }
285
354
  if (mediaType === 'application/json+env') {
286
355
  const data = JSON.parse(body);
287
356
  this.report.env = data;
@@ -301,6 +370,7 @@ class ReportGenerator {
301
370
  const networkLog = JSON.parse(body);
302
371
  if (this.networkLog.length < 1000)
303
372
  this.networkLog.push(networkLog);
373
+ this.stepNetworkLogs.push(networkLog);
304
374
  }
305
375
  const testStep = this.testStepMap.get(testStepId);
306
376
  if (testStep.pickleStepId === undefined)
@@ -310,6 +380,46 @@ class ReportGenerator {
310
380
  const command = JSON.parse(body);
311
381
  stepProgess.commands.push(command);
312
382
  }
383
+ else if (mediaType === 'application/json+trace') {
384
+ const data = JSON.parse(body);
385
+ stepProgess.traceFilePath = data.traceFilePath;
386
+ }
387
+ if (mediaType === 'application/json+bruno') {
388
+ try {
389
+ const data = JSON.parse(body);
390
+ stepProgess.brunoData = data;
391
+ }
392
+ catch (error) {
393
+ console.error('Error parsing bruno data:', error);
394
+ }
395
+ }
396
+ if (mediaType === 'application/json+intercept-results') {
397
+ try {
398
+ const data = JSON.parse(body);
399
+ stepProgess.interceptResults = data;
400
+ }
401
+ catch (error) {
402
+ console.error('Error parsing intercept results:', error);
403
+ }
404
+ }
405
+ }
406
+ getFailedTestStepResult({ commands, startTime, endTime, result, }) {
407
+ for (const command of commands) {
408
+ if (command.result.status === 'FAILED') {
409
+ return {
410
+ status: 'FAILED',
411
+ message: command.result.message,
412
+ startTime,
413
+ endTime,
414
+ };
415
+ }
416
+ }
417
+ return {
418
+ status: 'FAILED',
419
+ startTime,
420
+ endTime,
421
+ message: result.message,
422
+ };
313
423
  }
314
424
  onTestStepFinished(testStepFinished) {
315
425
  const { testStepId, testStepResult, timestamp } = testStepFinished;
@@ -320,6 +430,25 @@ class ReportGenerator {
320
430
  }
321
431
  return;
322
432
  }
433
+ if (testStepResult.status === 'UNDEFINED') {
434
+ const step = this.stepReportMap.get(testStep.pickleStepId);
435
+ const stepName = step ? step.keyword + ' ' + step.text : 'Undefined step';
436
+ const undefinedCommand = {
437
+ testStepId: testStepId,
438
+ body: JSON.stringify({
439
+ type: 'error',
440
+ text: 'Undefined step: ' + stepName,
441
+ result: {
442
+ status: 'FAILED',
443
+ startTime: this.getTimeStamp(timestamp),
444
+ endTime: this.getTimeStamp(timestamp),
445
+ },
446
+ }),
447
+ mediaType: 'application/json',
448
+ contentEncoding: messages.AttachmentContentEncoding.IDENTITY,
449
+ };
450
+ this.onAttachment(undefinedCommand);
451
+ }
323
452
  const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
324
453
  const prevStepResult = stepProgess.result;
325
454
  let data = {};
@@ -335,18 +464,73 @@ class ReportGenerator {
335
464
  catch (error) {
336
465
  console.log('Error reading data.json');
337
466
  }
338
- stepProgess.result = {
339
- status: testStepResult.status,
340
- startTime: prevStepResult.startTime,
341
- endTime: this.getTimeStamp(timestamp),
342
- message: testStepResult.message,
343
- // exception: testStepResult.exception,
344
- };
467
+ if (testStepResult.status === 'FAILED') {
468
+ stepProgess.result = this.getFailedTestStepResult({
469
+ commands: stepProgess.commands,
470
+ startTime: prevStepResult.startTime,
471
+ endTime: this.getTimeStamp(timestamp),
472
+ result: testStepResult,
473
+ });
474
+ }
475
+ else {
476
+ stepProgess.result = {
477
+ status: testStepResult.status,
478
+ startTime: prevStepResult.startTime,
479
+ endTime: this.getTimeStamp(timestamp),
480
+ };
481
+ }
345
482
  stepProgess.webLog = this.stepLogs;
483
+ stepProgess.networkData = this.stepNetworkLogs;
484
+ stepProgess.ariaSnapshot = this.ariaSnapshot;
485
+ this.ariaSnapshot = '';
486
+ this.stepNetworkLogs = [];
346
487
  this.stepLogs = [];
347
488
  if (Object.keys(data).length > 0) {
348
489
  stepProgess.data = data;
490
+ const id = testStepFinished.testCaseStartedId;
491
+ const parameters = this.testCaseReportMap.get(id).parameters;
492
+ const _parameters = {};
493
+ Object.keys(parameters).map((key) => {
494
+ var _a;
495
+ if (parameters[key].startsWith('{{') &&
496
+ parameters[key].endsWith('}}')) {
497
+ const path = parameters[key].slice(2, -2).split('.');
498
+ let value = String((_a = object_path_1.default.get(data, path)) !== null && _a !== void 0 ? _a : parameters[key]);
499
+ if (value) {
500
+ if (value.startsWith('secret:')) {
501
+ value = 'secret:****';
502
+ }
503
+ else if (value.startsWith('totp:')) {
504
+ value = 'totp:****';
505
+ }
506
+ else if (value.startsWith('mask:')) {
507
+ value = 'mask:****';
508
+ }
509
+ _parameters[key] = value;
510
+ }
511
+ }
512
+ else {
513
+ _parameters[key] = parameters[key];
514
+ }
515
+ });
516
+ this.report.testCases.find((testCase) => {
517
+ return testCase.id === id;
518
+ }).parameters = _parameters;
349
519
  }
520
+ // if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
521
+ // this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH
522
+ // if (!fs.existsSync(this.reportFolder)) {
523
+ // fs.mkdirSync(this.reportFolder)
524
+ // }
525
+ // const reportFilePath = path.join(
526
+ // this.reportFolder,
527
+ // `report.json`
528
+ // )
529
+ // writeFileSync(reportFilePath, JSON.stringify(this.report, null, 2))
530
+ // return undefined
531
+ // // } else {
532
+ // // return await this.uploadTestCase(testProgress, reRunId)
533
+ // }
350
534
  }
351
535
  getLogFileContent() {
352
536
  let projectPath = process.cwd();
@@ -394,24 +578,74 @@ class ReportGenerator {
394
578
  status: 'PASSED',
395
579
  };
396
580
  }
397
- async onTestCaseFinished(testCaseFinished) {
581
+ async onTestCaseFinished(testCaseFinished, reRunId) {
398
582
  const { testCaseStartedId, timestamp } = testCaseFinished;
399
583
  const testProgress = this.testCaseReportMap.get(testCaseStartedId);
400
584
  const prevResult = testProgress.result;
401
585
  const steps = Object.values(testProgress.steps);
402
586
  const result = this.getTestCaseResult(steps);
587
+ if (result.status === 'PASSED' && reRunId) {
588
+ this.uploadService.updateProjectAnalytics(process.env.PROJECT_ID);
589
+ }
590
+ const endTime = this.getTimeStamp(timestamp);
403
591
  testProgress.result = {
404
592
  ...result,
405
593
  startTime: prevResult.startTime,
406
- endTime: this.getTimeStamp(timestamp),
594
+ endTime,
407
595
  };
408
596
  testProgress.webLog = this.logs;
409
597
  testProgress.networkLog = this.networkLog;
598
+ testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
599
+ this.initialAriaSnapshot = '';
410
600
  this.networkLog = [];
411
601
  this.logs = [];
412
- await this.uploadTestCase(testProgress);
602
+ if (this.testCaseLog && this.testCaseLog.length > 0) {
603
+ // Create the logs directory
604
+ const logsDir = path_1.default.join(this.reportFolder, 'editorLogs');
605
+ const fileName = `testCaseLog_${testCaseStartedId}.log`;
606
+ const filePath = path_1.default.join(logsDir, fileName);
607
+ // Ensure the logs directory exists
608
+ fs_1.default.mkdirSync(logsDir, { recursive: true });
609
+ // Write the logs to the file
610
+ fs_1.default.writeFileSync(filePath, this.testCaseLog.join('\n'), 'utf8');
611
+ // Store this ID in the testProgress object so it can be accessed later
612
+ testProgress.logFileId = testCaseStartedId;
613
+ }
614
+ this.testCaseLog = [];
615
+ if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
616
+ this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH;
617
+ if (!fs_1.default.existsSync(this.reportFolder)) {
618
+ fs_1.default.mkdirSync(this.reportFolder);
619
+ }
620
+ const reportFilePath = path_1.default.join(this.reportFolder, `${endTime}_${testProgress.scenarioName}.json`);
621
+ (0, fs_extra_1.writeFileSync)(reportFilePath, JSON.stringify(testProgress, null, 2));
622
+ return undefined;
623
+ }
624
+ else {
625
+ return await this.uploadTestCase(testProgress, reRunId);
626
+ }
413
627
  }
414
- async uploadTestCase(testCase) {
628
+ async uploadTestCase(testCase, rerunId) {
629
+ let data = null;
630
+ for (let attempt = 1; attempt <= this.retryCount; attempt++) {
631
+ try {
632
+ data = await this.tryUpload(testCase, rerunId);
633
+ break;
634
+ }
635
+ catch (e) {
636
+ console.error(`Attempt ${attempt} to upload testcase failed:`, e);
637
+ if (attempt === this.retryCount) {
638
+ console.error('All retry attempts failed, failed to upload testcase.');
639
+ }
640
+ else {
641
+ const waitTime = 1000 * 2 ** (attempt - 1); //? exponential backoff: 1s, 2s, 4s...
642
+ await new Promise((r) => setTimeout(r, waitTime));
643
+ }
644
+ }
645
+ }
646
+ return data;
647
+ }
648
+ async tryUpload(testCase, rerunId) {
415
649
  let runId = '';
416
650
  let projectId = '';
417
651
  if (!process.env.UPLOADING_TEST_CASE) {
@@ -422,7 +656,9 @@ class ReportGenerator {
422
656
  anyRemArr.push(randomID);
423
657
  process.env.UPLOADING_TEST_CASE = JSON.stringify(anyRemArr);
424
658
  try {
425
- if (process.env.RUN_ID && process.env.PROJECT_ID) {
659
+ if (process.env.RUN_ID &&
660
+ process.env.PROJECT_ID &&
661
+ !process.env.IGNORE_ENV_VARIABLES) {
426
662
  runId = process.env.RUN_ID;
427
663
  projectId = process.env.PROJECT_ID;
428
664
  }
@@ -430,13 +666,14 @@ class ReportGenerator {
430
666
  const runDoc = await this.uploadService.createRunDocument(this.runName);
431
667
  runId = runDoc._id;
432
668
  projectId = runDoc.project_id;
433
- process.env.RUN_ID = runId;
434
- process.env.PROJECT_ID = projectId;
669
+ if (!process.env.IGNORE_ENV_VARIABLES) {
670
+ process.env.RUN_ID = runId;
671
+ process.env.PROJECT_ID = projectId;
672
+ }
435
673
  }
436
- await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder);
437
- }
438
- catch (e) {
439
- console.error('Error uploading test case:', e);
674
+ const data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
675
+ this.writeTestCaseReportToDisk(testCase);
676
+ return data;
440
677
  }
441
678
  finally {
442
679
  const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
@@ -444,7 +681,30 @@ class ReportGenerator {
444
681
  process.env.UPLOADING_TEST_CASE = JSON.stringify(arrRem);
445
682
  }
446
683
  }
447
- onTestRunFinished(testRunFinished) {
684
+ writeTestCaseReportToDisk(testCase) {
685
+ var _a;
686
+ const reportFolder = (_a = this.reportFolder) !== null && _a !== void 0 ? _a : process.env.TESTCASE_REPORT_FOLDER_PATH;
687
+ if (!reportFolder) {
688
+ console.error('Report folder is not defined');
689
+ return;
690
+ }
691
+ try {
692
+ let i = 0;
693
+ while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
694
+ i++;
695
+ }
696
+ fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
697
+ //exclude network log from the saved report
698
+ const networkLog = testCase.networkLog;
699
+ delete testCase.networkLog;
700
+ fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
701
+ fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
702
+ }
703
+ catch (error) {
704
+ console.error('Error writing test case report to disk:', error);
705
+ }
706
+ }
707
+ async onTestRunFinished(testRunFinished) {
448
708
  const { timestamp, success, message } = testRunFinished;
449
709
  const prevResult = this.report.result;
450
710
  this.report.result = {
@@ -454,6 +714,7 @@ class ReportGenerator {
454
714
  message,
455
715
  // exception,
456
716
  };
717
+ await this.uploadService.createStatus(success ? 'passed' : 'failed');
457
718
  }
458
719
  }
459
720
  exports.default = ReportGenerator;