@dev-blinq/cucumber-js 1.0.141-dev → 1.0.141
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cucumber.ts +1 -0
- package/bin/download-install.js +22 -2
- package/lib/api/console_logger.js.map +1 -1
- package/lib/cli/run.js +1 -0
- package/lib/cli/run.js.map +1 -1
- package/lib/cli/validate_node_engine_version.js +3 -1
- package/lib/cli/validate_node_engine_version.js.map +1 -1
- package/lib/configuration/axios_client.js +1 -1
- package/lib/configuration/axios_client.js.map +1 -1
- package/lib/formatter/api.js +16 -5
- package/lib/formatter/api.js.map +1 -1
- package/lib/formatter/builder.js +1 -3
- package/lib/formatter/builder.js.map +1 -1
- package/lib/formatter/bvt_analysis_formatter.d.ts +13 -1
- package/lib/formatter/bvt_analysis_formatter.js +204 -68
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.js +22 -8
- package/lib/formatter/feature_data_format.js.map +1 -1
- package/lib/formatter/helpers/constants.d.ts +20 -1
- package/lib/formatter/helpers/constants.js +26 -3
- package/lib/formatter/helpers/constants.js.map +1 -1
- package/lib/formatter/helpers/report_generator.d.ts +13 -2
- package/lib/formatter/helpers/report_generator.js +220 -23
- package/lib/formatter/helpers/report_generator.js.map +1 -1
- package/lib/formatter/helpers/test_case_attempt_parser.js.map +1 -1
- package/lib/formatter/helpers/upload_serivce.d.ts +22 -2
- package/lib/formatter/helpers/upload_serivce.js +198 -49
- package/lib/formatter/helpers/upload_serivce.js.map +1 -1
- package/lib/formatter/helpers/uploader.js +6 -2
- package/lib/formatter/helpers/uploader.js.map +1 -1
- package/lib/formatter/progress_formatter.d.ts +2 -1
- package/lib/formatter/progress_formatter.js.map +1 -1
- package/lib/formatter/snippets_formatter.js.map +1 -1
- package/lib/formatter/summary_formatter.js +4 -0
- package/lib/formatter/summary_formatter.js.map +1 -1
- package/lib/formatter/usage_formatter.js.map +1 -1
- package/lib/formatter/usage_json_formatter.js.map +1 -1
- package/lib/models/definition.js.map +1 -1
- package/lib/pickle_filter.d.ts +3 -2
- package/lib/pickle_filter.js.map +1 -1
- package/lib/runtime/test_case_runner.d.ts +2 -0
- package/lib/runtime/test_case_runner.js +17 -1
- package/lib/runtime/test_case_runner.js.map +1 -1
- package/lib/support_code_library_builder/world.js.map +1 -1
- package/lib/uncaught_exception_manager.d.ts +1 -1
- package/lib/uncaught_exception_manager.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +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
|
-
:
|
|
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;
|
|
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';
|
|
@@ -66,6 +67,9 @@ export type JsonStep = {
|
|
|
66
67
|
networkData: any[];
|
|
67
68
|
data?: any;
|
|
68
69
|
ariaSnapshot: string;
|
|
70
|
+
traceFilePath?: string;
|
|
71
|
+
brunoData?: any;
|
|
72
|
+
interceptResults?: any;
|
|
69
73
|
};
|
|
70
74
|
export type RetrainStats = {
|
|
71
75
|
result: JsonTestResult;
|
|
@@ -85,10 +89,12 @@ export type JsonTestProgress = {
|
|
|
85
89
|
initialAriaSnapshot?: string;
|
|
86
90
|
webLog: any;
|
|
87
91
|
networkLog: any;
|
|
92
|
+
logFileId?: string;
|
|
88
93
|
env: {
|
|
89
94
|
name: string;
|
|
90
95
|
baseUrl: string;
|
|
91
96
|
};
|
|
97
|
+
traceFileId?: string;
|
|
92
98
|
};
|
|
93
99
|
export type JsonReport = {
|
|
94
100
|
testCases: JsonTestProgress[];
|
|
@@ -121,9 +127,12 @@ export default class ReportGenerator {
|
|
|
121
127
|
private runName;
|
|
122
128
|
private ariaSnapshot;
|
|
123
129
|
private initialAriaSnapshot;
|
|
130
|
+
private testCaseLog;
|
|
131
|
+
private loggingOverridden;
|
|
124
132
|
reportFolder: null | string;
|
|
125
133
|
private uploadService;
|
|
126
|
-
|
|
134
|
+
private retryTestCaseId;
|
|
135
|
+
handleMessage(envelope: EnvelopeWithMetaMessage | messages.Envelope, reRunId?: string): Promise<any>;
|
|
127
136
|
getReport(): JsonReport;
|
|
128
137
|
private handleParseError;
|
|
129
138
|
private onGherkinDocument;
|
|
@@ -141,7 +150,9 @@ export default class ReportGenerator {
|
|
|
141
150
|
getLogFileContent(): any;
|
|
142
151
|
private getTestCaseResult;
|
|
143
152
|
private onTestCaseFinished;
|
|
153
|
+
private readonly retryCount;
|
|
144
154
|
private uploadTestCase;
|
|
155
|
+
private tryUpload;
|
|
145
156
|
private writeTestCaseReportToDisk;
|
|
146
157
|
private onTestRunFinished;
|
|
147
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
|
-
:
|
|
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;
|
|
@@ -69,11 +76,15 @@ class ReportGenerator {
|
|
|
69
76
|
this.runName = '';
|
|
70
77
|
this.ariaSnapshot = '';
|
|
71
78
|
this.initialAriaSnapshot = '';
|
|
79
|
+
this.testCaseLog = [];
|
|
80
|
+
this.loggingOverridden = false; // Flag to track if logging is overridden
|
|
72
81
|
this.reportFolder = null;
|
|
73
82
|
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
83
|
+
this.retryTestCaseId = null;
|
|
84
|
+
this.retryCount = 3;
|
|
74
85
|
}
|
|
75
|
-
async handleMessage(envelope) {
|
|
76
|
-
if (envelope.meta && envelope.meta
|
|
86
|
+
async handleMessage(envelope, reRunId) {
|
|
87
|
+
if (envelope.meta && 'runName' in envelope.meta) {
|
|
77
88
|
this.runName = envelope.meta.runName;
|
|
78
89
|
}
|
|
79
90
|
const type = Object.keys(envelope)[0];
|
|
@@ -100,14 +111,35 @@ class ReportGenerator {
|
|
|
100
111
|
case 'testRunStarted': {
|
|
101
112
|
const testRunStarted = envelope[type];
|
|
102
113
|
this.onTestRunStarted(testRunStarted);
|
|
114
|
+
await this.uploadService.createStatus('running');
|
|
103
115
|
break;
|
|
104
116
|
}
|
|
105
117
|
case 'testCase': {
|
|
106
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
|
|
107
138
|
this.onTestCase(testCase);
|
|
108
139
|
break;
|
|
109
140
|
}
|
|
110
141
|
case 'testCaseStarted': {
|
|
142
|
+
this.retryTestCaseId = envelope[type].retryTestCaseId;
|
|
111
143
|
const testCaseStarted = envelope[type];
|
|
112
144
|
this.onTestCaseStarted(testCaseStarted);
|
|
113
145
|
break;
|
|
@@ -129,13 +161,18 @@ class ReportGenerator {
|
|
|
129
161
|
}
|
|
130
162
|
case 'testCaseFinished': {
|
|
131
163
|
const testCaseFinished = envelope[type];
|
|
132
|
-
|
|
133
|
-
|
|
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;
|
|
134
171
|
}
|
|
135
172
|
// case "hook": { break} // After Hook
|
|
136
173
|
case 'testRunFinished': {
|
|
137
174
|
const testRunFinished = envelope[type];
|
|
138
|
-
this.onTestRunFinished(testRunFinished);
|
|
175
|
+
await this.onTestRunFinished(testRunFinished);
|
|
139
176
|
break;
|
|
140
177
|
}
|
|
141
178
|
// case "parameterType" : { break}
|
|
@@ -349,13 +386,36 @@ class ReportGenerator {
|
|
|
349
386
|
const command = JSON.parse(body);
|
|
350
387
|
stepProgess.commands.push(command);
|
|
351
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
|
+
}
|
|
352
411
|
}
|
|
353
|
-
getFailedTestStepResult({ commands, startTime, endTime, result, }) {
|
|
412
|
+
getFailedTestStepResult({ commands, startTime, endTime, result, stepName, }) {
|
|
354
413
|
for (const command of commands) {
|
|
355
414
|
if (command.result.status === 'FAILED') {
|
|
356
415
|
return {
|
|
357
416
|
status: 'FAILED',
|
|
358
417
|
message: command.result.message,
|
|
418
|
+
name: stepName,
|
|
359
419
|
startTime,
|
|
360
420
|
endTime,
|
|
361
421
|
};
|
|
@@ -366,6 +426,7 @@ class ReportGenerator {
|
|
|
366
426
|
startTime,
|
|
367
427
|
endTime,
|
|
368
428
|
message: result.message,
|
|
429
|
+
name: stepName,
|
|
369
430
|
};
|
|
370
431
|
}
|
|
371
432
|
onTestStepFinished(testStepFinished) {
|
|
@@ -373,6 +434,31 @@ class ReportGenerator {
|
|
|
373
434
|
const testStep = this.testStepMap.get(testStepId);
|
|
374
435
|
if (testStep.pickleStepId === undefined) {
|
|
375
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);
|
|
376
462
|
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
377
463
|
}
|
|
378
464
|
return;
|
|
@@ -417,6 +503,7 @@ class ReportGenerator {
|
|
|
417
503
|
startTime: prevStepResult.startTime,
|
|
418
504
|
endTime: this.getTimeStamp(timestamp),
|
|
419
505
|
result: testStepResult,
|
|
506
|
+
stepName: stepProgess.text,
|
|
420
507
|
});
|
|
421
508
|
}
|
|
422
509
|
else {
|
|
@@ -434,7 +521,50 @@ class ReportGenerator {
|
|
|
434
521
|
this.stepLogs = [];
|
|
435
522
|
if (Object.keys(data).length > 0) {
|
|
436
523
|
stepProgess.data = data;
|
|
437
|
-
|
|
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;
|
|
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
|
+
// }
|
|
438
568
|
}
|
|
439
569
|
getLogFileContent() {
|
|
440
570
|
let projectPath = process.cwd();
|
|
@@ -461,6 +591,12 @@ class ReportGenerator {
|
|
|
461
591
|
}
|
|
462
592
|
}
|
|
463
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
|
+
}
|
|
464
600
|
for (const step of steps) {
|
|
465
601
|
switch (step.result.status) {
|
|
466
602
|
case 'FAILED':
|
|
@@ -482,26 +618,79 @@ class ReportGenerator {
|
|
|
482
618
|
status: 'PASSED',
|
|
483
619
|
};
|
|
484
620
|
}
|
|
485
|
-
async onTestCaseFinished(testCaseFinished) {
|
|
621
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
486
622
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
487
623
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
488
624
|
const prevResult = testProgress.result;
|
|
489
625
|
const steps = Object.values(testProgress.steps);
|
|
490
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);
|
|
491
631
|
testProgress.result = {
|
|
492
632
|
...result,
|
|
493
633
|
startTime: prevResult.startTime,
|
|
494
|
-
endTime
|
|
634
|
+
endTime,
|
|
495
635
|
};
|
|
496
636
|
testProgress.webLog = this.logs;
|
|
497
637
|
testProgress.networkLog = this.networkLog;
|
|
498
638
|
testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
|
|
639
|
+
if (process.env.TRACE) {
|
|
640
|
+
testProgress.traceFileId = path_1.default.join(`trace-${testCaseStartedId}.zip`);
|
|
641
|
+
}
|
|
499
642
|
this.initialAriaSnapshot = '';
|
|
500
643
|
this.networkLog = [];
|
|
501
644
|
this.logs = [];
|
|
502
|
-
|
|
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
|
+
}
|
|
503
672
|
}
|
|
504
|
-
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) {
|
|
505
694
|
let runId = '';
|
|
506
695
|
let projectId = '';
|
|
507
696
|
if (!process.env.UPLOADING_TEST_CASE) {
|
|
@@ -519,7 +708,7 @@ class ReportGenerator {
|
|
|
519
708
|
projectId = process.env.PROJECT_ID;
|
|
520
709
|
}
|
|
521
710
|
else {
|
|
522
|
-
const runDoc = await this.uploadService.createRunDocument(this.runName);
|
|
711
|
+
const runDoc = await this.uploadService.createRunDocument(this.runName, testCase.env);
|
|
523
712
|
runId = runDoc._id;
|
|
524
713
|
projectId = runDoc.project_id;
|
|
525
714
|
if (!process.env.IGNORE_ENV_VARIABLES) {
|
|
@@ -527,11 +716,9 @@ class ReportGenerator {
|
|
|
527
716
|
process.env.PROJECT_ID = projectId;
|
|
528
717
|
}
|
|
529
718
|
}
|
|
530
|
-
|
|
531
|
-
this.
|
|
532
|
-
|
|
533
|
-
catch (e) {
|
|
534
|
-
console.error('Error uploading test case:', e);
|
|
719
|
+
const reportIndex = this.writeTestCaseReportToDisk(testCase);
|
|
720
|
+
const data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, reportIndex, rerunId);
|
|
721
|
+
return data;
|
|
535
722
|
}
|
|
536
723
|
finally {
|
|
537
724
|
const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
@@ -540,23 +727,32 @@ class ReportGenerator {
|
|
|
540
727
|
}
|
|
541
728
|
}
|
|
542
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 -1;
|
|
735
|
+
}
|
|
543
736
|
try {
|
|
544
737
|
let i = 0;
|
|
545
|
-
while (fs_1.default.existsSync(path_1.default.join(
|
|
738
|
+
while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
|
|
546
739
|
i++;
|
|
547
740
|
}
|
|
548
|
-
fs_1.default.mkdirSync(path_1.default.join(
|
|
741
|
+
fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
|
|
549
742
|
//exclude network log from the saved report
|
|
550
743
|
const networkLog = testCase.networkLog;
|
|
551
744
|
delete testCase.networkLog;
|
|
552
|
-
|
|
553
|
-
fs_1.default.writeFileSync(path_1.default.join(
|
|
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));
|
|
748
|
+
return i;
|
|
554
749
|
}
|
|
555
750
|
catch (error) {
|
|
556
751
|
console.error('Error writing test case report to disk:', error);
|
|
752
|
+
return -1;
|
|
557
753
|
}
|
|
558
754
|
}
|
|
559
|
-
onTestRunFinished(testRunFinished) {
|
|
755
|
+
async onTestRunFinished(testRunFinished) {
|
|
560
756
|
const { timestamp, success, message } = testRunFinished;
|
|
561
757
|
const prevResult = this.report.result;
|
|
562
758
|
this.report.result = {
|
|
@@ -566,6 +762,7 @@ class ReportGenerator {
|
|
|
566
762
|
message,
|
|
567
763
|
// exception,
|
|
568
764
|
};
|
|
765
|
+
await this.uploadService.createStatus(success ? 'passed' : 'failed');
|
|
569
766
|
}
|
|
570
767
|
}
|
|
571
768
|
exports.default = ReportGenerator;
|