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

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 (50) hide show
  1. package/bin/cucumber.ts +1 -0
  2. package/bin/download-install.js +22 -2
  3. package/lib/api/console_logger.js.map +1 -1
  4. package/lib/cli/run.js +1 -0
  5. package/lib/cli/run.js.map +1 -1
  6. package/lib/cli/validate_node_engine_version.js +3 -1
  7. package/lib/cli/validate_node_engine_version.js.map +1 -1
  8. package/lib/configuration/axios_client.js +1 -1
  9. package/lib/configuration/axios_client.js.map +1 -1
  10. package/lib/formatter/api.js +16 -5
  11. package/lib/formatter/api.js.map +1 -1
  12. package/lib/formatter/builder.js +1 -3
  13. package/lib/formatter/builder.js.map +1 -1
  14. package/lib/formatter/bvt_analysis_formatter.d.ts +13 -1
  15. package/lib/formatter/bvt_analysis_formatter.js +198 -68
  16. package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
  17. package/lib/formatter/feature_data_format.js +22 -8
  18. package/lib/formatter/feature_data_format.js.map +1 -1
  19. package/lib/formatter/helpers/constants.d.ts +20 -1
  20. package/lib/formatter/helpers/constants.js +26 -3
  21. package/lib/formatter/helpers/constants.js.map +1 -1
  22. package/lib/formatter/helpers/report_generator.d.ts +18 -2
  23. package/lib/formatter/helpers/report_generator.js +264 -27
  24. package/lib/formatter/helpers/report_generator.js.map +1 -1
  25. package/lib/formatter/helpers/test_case_attempt_parser.js.map +1 -1
  26. package/lib/formatter/helpers/upload_serivce.d.ts +22 -2
  27. package/lib/formatter/helpers/upload_serivce.js +198 -46
  28. package/lib/formatter/helpers/upload_serivce.js.map +1 -1
  29. package/lib/formatter/helpers/uploader.js +6 -2
  30. package/lib/formatter/helpers/uploader.js.map +1 -1
  31. package/lib/formatter/progress_formatter.d.ts +2 -1
  32. package/lib/formatter/progress_formatter.js.map +1 -1
  33. package/lib/formatter/snippets_formatter.js.map +1 -1
  34. package/lib/formatter/summary_formatter.js +4 -0
  35. package/lib/formatter/summary_formatter.js.map +1 -1
  36. package/lib/formatter/usage_formatter.js.map +1 -1
  37. package/lib/formatter/usage_json_formatter.js.map +1 -1
  38. package/lib/models/definition.js.map +1 -1
  39. package/lib/pickle_filter.d.ts +3 -2
  40. package/lib/pickle_filter.js.map +1 -1
  41. package/lib/runtime/test_case_runner.d.ts +2 -0
  42. package/lib/runtime/test_case_runner.js +17 -1
  43. package/lib/runtime/test_case_runner.js.map +1 -1
  44. package/lib/support_code_library_builder/world.js.map +1 -1
  45. package/lib/uncaught_exception_manager.d.ts +1 -1
  46. package/lib/uncaught_exception_manager.js.map +1 -1
  47. package/lib/version.d.ts +1 -1
  48. package/lib/version.js +1 -1
  49. package/lib/version.js.map +1 -1
  50. package/package.json +7 -3
@@ -22,6 +22,12 @@ export declare const STAGE: {
22
22
  RUNS: string;
23
23
  STORAGE: string;
24
24
  };
25
+ export declare const CUSTOM: {
26
+ SSO: string;
27
+ WORKSPACE: string;
28
+ RUNS: string;
29
+ STORAGE: string;
30
+ };
25
31
  export declare const SERVICES_URI: {
26
32
  SSO: string;
27
33
  WORKSPACE: string;
@@ -40,5 +46,18 @@ export declare enum ActionEvents {
40
46
  click_open_vscode = "click_open_vscode",
41
47
  error_open_vscode = "error_open_vscode",
42
48
  cli_run_tests = "cli_run_tests",
43
- upload_report = "upload_report"
49
+ upload_report = "upload_report",
50
+ signup = "signup",
51
+ create_project = "create_project",
52
+ create_scenario = "create_scenario",
53
+ launched_chromium_success = "launched_chromium_success",
54
+ launched_chromium_failed = "launched_chromium_failed",
55
+ update_started = "update_started",
56
+ update_downloaded = "update_downloaded",
57
+ update_error = "update_error",
58
+ package_sync_error_minor = "package_sync_error_minor",
59
+ package_sync_error_major = "package_sync_error_major",
60
+ package_sync_error_fatal = "package_sync_error_fatal",
61
+ draft_recovered = "draft_recovered",
62
+ draft_deleted = "draft_deleted"
44
63
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ActionEvents = exports.SERVICES_URI = exports.STAGE = exports.PROD = exports.DEV = exports.LOCAL = void 0;
3
+ exports.ActionEvents = exports.SERVICES_URI = exports.CUSTOM = exports.STAGE = exports.PROD = exports.DEV = exports.LOCAL = void 0;
4
4
  exports.LOCAL = {
5
5
  SSO: 'http://localhost:5000/api/auth',
6
6
  WORKSPACE: 'http://localhost:6000/api/workspace',
@@ -25,13 +25,23 @@ exports.STAGE = {
25
25
  RUNS: 'https://stage.api.blinq.io/api/runs',
26
26
  STORAGE: 'https://stage.api.blinq.io/api/storage',
27
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
+ };
28
34
  exports.SERVICES_URI = process.env.NODE_ENV_BLINQ === 'local'
29
35
  ? exports.LOCAL // eslint-disable-line
30
36
  : process.env.NODE_ENV_BLINQ === 'dev'
31
37
  ? exports.DEV // eslint-disable-line
32
38
  : process.env.NODE_ENV_BLINQ === 'stage'
33
- ? exports.STAGE
34
- : exports.PROD; // eslint-disable-line
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
35
45
  var ActionEvents;
36
46
  (function (ActionEvents) {
37
47
  ActionEvents["record_scenario"] = "record_scenario";
@@ -46,5 +56,18 @@ var ActionEvents;
46
56
  ActionEvents["error_open_vscode"] = "error_open_vscode";
47
57
  ActionEvents["cli_run_tests"] = "cli_run_tests";
48
58
  ActionEvents["upload_report"] = "upload_report";
59
+ ActionEvents["signup"] = "signup";
60
+ ActionEvents["create_project"] = "create_project";
61
+ ActionEvents["create_scenario"] = "create_scenario";
62
+ ActionEvents["launched_chromium_success"] = "launched_chromium_success";
63
+ ActionEvents["launched_chromium_failed"] = "launched_chromium_failed";
64
+ ActionEvents["update_started"] = "update_started";
65
+ ActionEvents["update_downloaded"] = "update_downloaded";
66
+ ActionEvents["update_error"] = "update_error";
67
+ ActionEvents["package_sync_error_minor"] = "package_sync_error_minor";
68
+ ActionEvents["package_sync_error_major"] = "package_sync_error_major";
69
+ ActionEvents["package_sync_error_fatal"] = "package_sync_error_fatal";
70
+ ActionEvents["draft_recovered"] = "draft_recovered";
71
+ ActionEvents["draft_deleted"] = "draft_deleted";
49
72
  })(ActionEvents = exports.ActionEvents || (exports.ActionEvents = {}));
50
73
  //# sourceMappingURL=constants.js.map
@@ -1 +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,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;YACP,CAAC,CAAC,YAAI,CAAA,CAAC,sBAAsB;AAEjC,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 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\n : PROD // 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"]}
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;QACpC,CAAC,CAAC,WAAG,CAAC,sBAAsB;QAC5B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,OAAO;YACtC,CAAC,CAAC,aAAK,CAAC,sBAAsB;YAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM;gBACrC,CAAC,CAAC,YAAI,CAAC,sBAAsB;gBAC7B,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc;oBAC3B,CAAC,CAAC,YAAI,CAAC,sBAAsB;oBAC7B,CAAC,CAAC,cAAM,CAAA,CAAC,sBAAsB;AAE3C,IAAY,YA0BX;AA1BD,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;IAC/B,iCAAiB,CAAA;IACjB,iDAAiC,CAAA;IACjC,mDAAmC,CAAA;IACnC,uEAAuD,CAAA;IACvD,qEAAqD,CAAA;IACrD,iDAAiC,CAAA;IACjC,uDAAuC,CAAA;IACvC,6CAA6B,CAAA;IAC7B,qEAAqD,CAAA;IACrD,qEAAqD,CAAA;IACrD,qEAAqD,CAAA;IACrD,mDAAmC,CAAA;IACnC,+CAA+B,CAAA;AACjC,CAAC,EA1BW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QA0BvB","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 signup = 'signup',\n create_project = 'create_project',\n create_scenario = 'create_scenario',\n launched_chromium_success = 'launched_chromium_success',\n launched_chromium_failed = 'launched_chromium_failed',\n update_started = 'update_started',\n update_downloaded = 'update_downloaded',\n update_error = 'update_error',\n package_sync_error_minor = 'package_sync_error_minor', // Detected but did not block operation\n package_sync_error_major = 'package_sync_error_major', // Detected and caused degraded experience\n package_sync_error_fatal = 'package_sync_error_fatal', // Undetected and blocked operation\n draft_recovered = 'draft_recovered',\n draft_deleted = 'draft_deleted',\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import * as messages from '@cucumber/messages';
2
2
  type JsonTimestamp = number;
3
- type JsonStepType = 'Unknown' | 'Context' | 'Action' | 'Outcome' | 'Conjunction';
3
+ type JsonStepType = 'Unknown' | 'Context' | 'Action' | 'Outcome' | 'Conjunction' | 'After' | 'Before';
4
4
  export type JsonResultUnknown = {
5
5
  status: 'UNKNOWN';
6
6
  };
@@ -32,6 +32,7 @@ export type JsonResultFailed = {
32
32
  startTime: JsonTimestamp;
33
33
  endTime: JsonTimestamp;
34
34
  message?: string;
35
+ name?: string;
35
36
  };
36
37
  export type JsonFixedByAi = {
37
38
  status: 'FIXED_BY_AI';
@@ -65,6 +66,10 @@ export type JsonStep = {
65
66
  webLog: webLog[];
66
67
  networkData: any[];
67
68
  data?: any;
69
+ ariaSnapshot: string;
70
+ traceFilePath?: string;
71
+ brunoData?: any;
72
+ interceptResults?: any;
68
73
  };
69
74
  export type RetrainStats = {
70
75
  result: JsonTestResult;
@@ -81,12 +86,15 @@ export type JsonTestProgress = {
81
86
  steps: JsonStep[];
82
87
  result: JsonTestResult;
83
88
  retrainStats?: RetrainStats;
89
+ initialAriaSnapshot?: string;
84
90
  webLog: any;
85
91
  networkLog: any;
92
+ logFileId?: string;
86
93
  env: {
87
94
  name: string;
88
95
  baseUrl: string;
89
96
  };
97
+ traceFileId?: string;
90
98
  };
91
99
  export type JsonReport = {
92
100
  testCases: JsonTestProgress[];
@@ -117,9 +125,14 @@ export default class ReportGenerator {
117
125
  private stepLogs;
118
126
  private stepNetworkLogs;
119
127
  private runName;
128
+ private ariaSnapshot;
129
+ private initialAriaSnapshot;
130
+ private testCaseLog;
131
+ private loggingOverridden;
120
132
  reportFolder: null | string;
121
133
  private uploadService;
122
- handleMessage(envelope: EnvelopeWithMetaMessage): Promise<void>;
134
+ private retryTestCaseId;
135
+ handleMessage(envelope: EnvelopeWithMetaMessage | messages.Envelope, reRunId?: string): Promise<any>;
123
136
  getReport(): JsonReport;
124
137
  private handleParseError;
125
138
  private onGherkinDocument;
@@ -132,11 +145,14 @@ export default class ReportGenerator {
132
145
  private onTestCaseStarted;
133
146
  private onTestStepStarted;
134
147
  private onAttachment;
148
+ private getFailedTestStepResult;
135
149
  private onTestStepFinished;
136
150
  getLogFileContent(): any;
137
151
  private getTestCaseResult;
138
152
  private onTestCaseFinished;
153
+ private readonly retryCount;
139
154
  private uploadTestCase;
155
+ private tryUpload;
140
156
  private writeTestCaseReportToDisk;
141
157
  private onTestRunFinished;
142
158
  }
@@ -31,13 +31,20 @@ const messages = __importStar(require("@cucumber/messages"));
31
31
  const fs_1 = __importDefault(require("fs"));
32
32
  const path_1 = __importDefault(require("path"));
33
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"));
34
37
  const URL = process.env.NODE_ENV_BLINQ === 'dev'
35
38
  ? 'https://dev.api.blinq.io/api/runs'
36
39
  : process.env.NODE_ENV_BLINQ === 'local'
37
40
  ? 'http://localhost:5001/api/runs'
38
41
  : process.env.NODE_ENV_BLINQ === 'stage'
39
42
  ? 'https://stage.api.blinq.io/api/runs'
40
- : '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`;
41
48
  const REPORT_SERVICE_URL = (_a = process.env.REPORT_SERVICE_URL) !== null && _a !== void 0 ? _a : URL;
42
49
  const BATCH_SIZE = 10;
43
50
  const MAX_RETRIES = 3;
@@ -67,11 +74,17 @@ class ReportGenerator {
67
74
  this.stepLogs = [];
68
75
  this.stepNetworkLogs = [];
69
76
  this.runName = '';
77
+ this.ariaSnapshot = '';
78
+ this.initialAriaSnapshot = '';
79
+ this.testCaseLog = [];
80
+ this.loggingOverridden = false; // Flag to track if logging is overridden
70
81
  this.reportFolder = null;
71
82
  this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
83
+ this.retryTestCaseId = null;
84
+ this.retryCount = 3;
72
85
  }
73
- async handleMessage(envelope) {
74
- if (envelope.meta && envelope.meta.runName) {
86
+ async handleMessage(envelope, reRunId) {
87
+ if (envelope.meta && 'runName' in envelope.meta) {
75
88
  this.runName = envelope.meta.runName;
76
89
  }
77
90
  const type = Object.keys(envelope)[0];
@@ -98,14 +111,35 @@ class ReportGenerator {
98
111
  case 'testRunStarted': {
99
112
  const testRunStarted = envelope[type];
100
113
  this.onTestRunStarted(testRunStarted);
114
+ await this.uploadService.createStatus('running');
101
115
  break;
102
116
  }
103
117
  case 'testCase': {
104
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
105
138
  this.onTestCase(testCase);
106
139
  break;
107
140
  }
108
141
  case 'testCaseStarted': {
142
+ this.retryTestCaseId = envelope[type].retryTestCaseId;
109
143
  const testCaseStarted = envelope[type];
110
144
  this.onTestCaseStarted(testCaseStarted);
111
145
  break;
@@ -127,13 +161,18 @@ class ReportGenerator {
127
161
  }
128
162
  case 'testCaseFinished': {
129
163
  const testCaseFinished = envelope[type];
130
- await this.onTestCaseFinished(testCaseFinished);
131
- break;
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;
132
171
  }
133
172
  // case "hook": { break} // After Hook
134
173
  case 'testRunFinished': {
135
174
  const testRunFinished = envelope[type];
136
- this.onTestRunFinished(testRunFinished);
175
+ await this.onTestRunFinished(testRunFinished);
137
176
  break;
138
177
  }
139
178
  // case "parameterType" : { break}
@@ -266,6 +305,8 @@ class ReportGenerator {
266
305
  },
267
306
  networkData: [],
268
307
  webLog: [],
308
+ data: {},
309
+ ariaSnapshot: this.ariaSnapshot,
269
310
  });
270
311
  return this.stepReportMap.get(pickleStep.id);
271
312
  });
@@ -308,6 +349,14 @@ class ReportGenerator {
308
349
  this.reportFolder = body.replaceAll('\\', '/');
309
350
  return;
310
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
+ }
311
360
  if (mediaType === 'application/json+env') {
312
361
  const data = JSON.parse(body);
313
362
  this.report.env = data;
@@ -337,12 +386,79 @@ class ReportGenerator {
337
386
  const command = JSON.parse(body);
338
387
  stepProgess.commands.push(command);
339
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, stepName, }) {
413
+ for (const command of commands) {
414
+ if (command.result.status === 'FAILED') {
415
+ return {
416
+ status: 'FAILED',
417
+ message: command.result.message,
418
+ name: stepName,
419
+ startTime,
420
+ endTime,
421
+ };
422
+ }
423
+ }
424
+ return {
425
+ status: 'FAILED',
426
+ startTime,
427
+ endTime,
428
+ message: result.message,
429
+ name: stepName,
430
+ };
340
431
  }
341
432
  onTestStepFinished(testStepFinished) {
342
433
  const { testStepId, testStepResult, timestamp } = testStepFinished;
343
434
  const testStep = this.testStepMap.get(testStepId);
344
435
  if (testStep.pickleStepId === undefined) {
345
436
  if (testStepResult.status === 'FAILED') {
437
+ const testCase = this.testCaseReportMap.get(testStepFinished.testCaseStartedId);
438
+ const type = testCase.steps[0].result.status === 'UNKNOWN' ? 'Before' : 'After';
439
+ const hookStep = {
440
+ ariaSnapshot: null,
441
+ commands: [],
442
+ keyword: type,
443
+ data: {},
444
+ networkData: [],
445
+ result: {
446
+ status: 'FAILED',
447
+ message: testStepResult.message,
448
+ startTime: this.getTimeStamp(timestamp),
449
+ endTime: this.getTimeStamp(timestamp),
450
+ },
451
+ text: 'Failed hook',
452
+ type,
453
+ webLog: [],
454
+ };
455
+ if (type === 'Before') {
456
+ testCase.steps = [hookStep, ...testCase.steps];
457
+ }
458
+ else {
459
+ testCase.steps = [...testCase.steps, hookStep];
460
+ }
461
+ this.testCaseReportMap.set(testStepFinished.testCaseStartedId, testCase);
346
462
  console.error(`Before/After hook failed with message: ${testStepResult.message}`);
347
463
  }
348
464
  return;
@@ -381,20 +497,74 @@ class ReportGenerator {
381
497
  catch (error) {
382
498
  console.log('Error reading data.json');
383
499
  }
384
- stepProgess.result = {
385
- status: testStepResult.status,
386
- startTime: prevStepResult.startTime,
387
- endTime: this.getTimeStamp(timestamp),
388
- message: testStepResult.message,
389
- // exception: testStepResult.exception,
390
- };
500
+ if (testStepResult.status === 'FAILED') {
501
+ stepProgess.result = this.getFailedTestStepResult({
502
+ commands: stepProgess.commands,
503
+ startTime: prevStepResult.startTime,
504
+ endTime: this.getTimeStamp(timestamp),
505
+ result: testStepResult,
506
+ stepName: stepProgess.text,
507
+ });
508
+ }
509
+ else {
510
+ stepProgess.result = {
511
+ status: testStepResult.status,
512
+ startTime: prevStepResult.startTime,
513
+ endTime: this.getTimeStamp(timestamp),
514
+ };
515
+ }
391
516
  stepProgess.webLog = this.stepLogs;
392
517
  stepProgess.networkData = this.stepNetworkLogs;
518
+ stepProgess.ariaSnapshot = this.ariaSnapshot;
519
+ this.ariaSnapshot = '';
393
520
  this.stepNetworkLogs = [];
394
521
  this.stepLogs = [];
395
522
  if (Object.keys(data).length > 0) {
396
523
  stepProgess.data = data;
524
+ const id = testStepFinished.testCaseStartedId;
525
+ const parameters = this.testCaseReportMap.get(id).parameters;
526
+ const _parameters = {};
527
+ Object.keys(parameters).map((key) => {
528
+ var _a;
529
+ const valueParam = parameters[key].toString();
530
+ if (valueParam.startsWith('{{') && valueParam.endsWith('}}')) {
531
+ const path = valueParam.slice(2, -2).split('.');
532
+ let value = String((_a = object_path_1.default.get(data, path)) !== null && _a !== void 0 ? _a : valueParam);
533
+ if (value) {
534
+ if (value.startsWith('secret:')) {
535
+ value = 'secret:****';
536
+ }
537
+ else if (value.startsWith('totp:')) {
538
+ value = 'totp:****';
539
+ }
540
+ else if (value.startsWith('mask:')) {
541
+ value = 'mask:****';
542
+ }
543
+ _parameters[key] = value;
544
+ }
545
+ }
546
+ else {
547
+ _parameters[key] = parameters[key];
548
+ }
549
+ });
550
+ this.report.testCases.find((testCase) => {
551
+ return testCase.id === id;
552
+ }).parameters = _parameters;
397
553
  }
554
+ // if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
555
+ // this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH
556
+ // if (!fs.existsSync(this.reportFolder)) {
557
+ // fs.mkdirSync(this.reportFolder)
558
+ // }
559
+ // const reportFilePath = path.join(
560
+ // this.reportFolder,
561
+ // `report.json`
562
+ // )
563
+ // writeFileSync(reportFilePath, JSON.stringify(this.report, null, 2))
564
+ // return undefined
565
+ // // } else {
566
+ // // return await this.uploadTestCase(testProgress, reRunId)
567
+ // }
398
568
  }
399
569
  getLogFileContent() {
400
570
  let projectPath = process.cwd();
@@ -421,6 +591,12 @@ class ReportGenerator {
421
591
  }
422
592
  }
423
593
  getTestCaseResult(steps) {
594
+ if (steps[0] && steps[0].result.status === 'SKIPPED') {
595
+ return {
596
+ status: 'FAILED',
597
+ message: 'Test skipped due to failure in before hooks',
598
+ };
599
+ }
424
600
  for (const step of steps) {
425
601
  switch (step.result.status) {
426
602
  case 'FAILED':
@@ -442,24 +618,79 @@ class ReportGenerator {
442
618
  status: 'PASSED',
443
619
  };
444
620
  }
445
- async onTestCaseFinished(testCaseFinished) {
621
+ async onTestCaseFinished(testCaseFinished, reRunId) {
446
622
  const { testCaseStartedId, timestamp } = testCaseFinished;
447
623
  const testProgress = this.testCaseReportMap.get(testCaseStartedId);
448
624
  const prevResult = testProgress.result;
449
625
  const steps = Object.values(testProgress.steps);
450
626
  const result = this.getTestCaseResult(steps);
627
+ if (result.status === 'PASSED' && reRunId) {
628
+ this.uploadService.updateProjectAnalytics(process.env.PROJECT_ID);
629
+ }
630
+ const endTime = this.getTimeStamp(timestamp);
451
631
  testProgress.result = {
452
632
  ...result,
453
633
  startTime: prevResult.startTime,
454
- endTime: this.getTimeStamp(timestamp),
634
+ endTime,
455
635
  };
456
636
  testProgress.webLog = this.logs;
457
637
  testProgress.networkLog = this.networkLog;
638
+ testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
639
+ if (process.env.TRACE) {
640
+ testProgress.traceFileId = path_1.default.join(`trace-${testCaseStartedId}.zip`);
641
+ }
642
+ this.initialAriaSnapshot = '';
458
643
  this.networkLog = [];
459
644
  this.logs = [];
460
- await this.uploadTestCase(testProgress);
645
+ if (this.testCaseLog &&
646
+ this.testCaseLog.length > 0 &&
647
+ !testProgress.logFileId) {
648
+ // Create the logs directory
649
+ const logsDir = path_1.default.join(this.reportFolder, 'editorLogs');
650
+ const fileName = `testCaseLog_${testCaseStartedId}.log`;
651
+ const filePath = path_1.default.join(logsDir, fileName);
652
+ // Ensure the logs directory exists
653
+ fs_1.default.mkdirSync(logsDir, { recursive: true });
654
+ // Write the logs to the file
655
+ fs_1.default.writeFileSync(filePath, this.testCaseLog.join('\n'), 'utf8');
656
+ // Store this ID in the testProgress object so it can be accessed later
657
+ testProgress.logFileId = testCaseStartedId;
658
+ }
659
+ this.testCaseLog = [];
660
+ if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
661
+ this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH;
662
+ if (!fs_1.default.existsSync(this.reportFolder)) {
663
+ fs_1.default.mkdirSync(this.reportFolder);
664
+ }
665
+ const reportFilePath = path_1.default.join(this.reportFolder, `${endTime}_${testProgress.scenarioName}.json`);
666
+ (0, fs_extra_1.writeFileSync)(reportFilePath, JSON.stringify(testProgress, null, 2));
667
+ return undefined;
668
+ }
669
+ else {
670
+ return await this.uploadTestCase(testProgress, reRunId);
671
+ }
461
672
  }
462
- async uploadTestCase(testCase) {
673
+ async uploadTestCase(testCase, rerunId) {
674
+ let data = null;
675
+ for (let attempt = 1; attempt <= this.retryCount; attempt++) {
676
+ try {
677
+ data = await this.tryUpload(testCase, rerunId);
678
+ break;
679
+ }
680
+ catch (e) {
681
+ console.error(`Attempt ${attempt} to upload testcase failed:`, e);
682
+ if (attempt === this.retryCount) {
683
+ console.error('All retry attempts failed, failed to upload testcase.');
684
+ }
685
+ else {
686
+ const waitTime = 1000 * 2 ** (attempt - 1); //? exponential backoff: 1s, 2s, 4s...
687
+ await new Promise((r) => setTimeout(r, waitTime));
688
+ }
689
+ }
690
+ }
691
+ return data;
692
+ }
693
+ async tryUpload(testCase, rerunId) {
463
694
  let runId = '';
464
695
  let projectId = '';
465
696
  if (!process.env.UPLOADING_TEST_CASE) {
@@ -477,7 +708,7 @@ class ReportGenerator {
477
708
  projectId = process.env.PROJECT_ID;
478
709
  }
479
710
  else {
480
- const runDoc = await this.uploadService.createRunDocument(this.runName);
711
+ const runDoc = await this.uploadService.createRunDocument(this.runName, testCase.env);
481
712
  runId = runDoc._id;
482
713
  projectId = runDoc.project_id;
483
714
  if (!process.env.IGNORE_ENV_VARIABLES) {
@@ -485,11 +716,9 @@ class ReportGenerator {
485
716
  process.env.PROJECT_ID = projectId;
486
717
  }
487
718
  }
488
- await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder);
489
719
  this.writeTestCaseReportToDisk(testCase);
490
- }
491
- catch (e) {
492
- console.error('Error uploading test case:', e);
720
+ const data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
721
+ return data;
493
722
  }
494
723
  finally {
495
724
  const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
@@ -498,23 +727,30 @@ class ReportGenerator {
498
727
  }
499
728
  }
500
729
  writeTestCaseReportToDisk(testCase) {
730
+ var _a;
731
+ const reportFolder = (_a = this.reportFolder) !== null && _a !== void 0 ? _a : process.env.TESTCASE_REPORT_FOLDER_PATH;
732
+ if (!reportFolder) {
733
+ console.error('Report folder is not defined');
734
+ return;
735
+ }
501
736
  try {
502
737
  let i = 0;
503
- while (fs_1.default.existsSync(path_1.default.join(this.reportFolder, `${i}`))) {
738
+ while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
504
739
  i++;
505
740
  }
506
- fs_1.default.mkdirSync(path_1.default.join(this.reportFolder, `${i}`));
741
+ fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
507
742
  //exclude network log from the saved report
508
743
  const networkLog = testCase.networkLog;
509
744
  delete testCase.networkLog;
510
- fs_1.default.writeFileSync(path_1.default.join(this.reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
511
- fs_1.default.writeFileSync(path_1.default.join(this.reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
745
+ delete testCase.webLog;
746
+ fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
747
+ fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
512
748
  }
513
749
  catch (error) {
514
750
  console.error('Error writing test case report to disk:', error);
515
751
  }
516
752
  }
517
- onTestRunFinished(testRunFinished) {
753
+ async onTestRunFinished(testRunFinished) {
518
754
  const { timestamp, success, message } = testRunFinished;
519
755
  const prevResult = this.report.result;
520
756
  this.report.result = {
@@ -524,6 +760,7 @@ class ReportGenerator {
524
760
  message,
525
761
  // exception,
526
762
  };
763
+ await this.uploadService.createStatus(success ? 'passed' : 'failed');
527
764
  }
528
765
  }
529
766
  exports.default = ReportGenerator;