@dev-blinq/cucumber-js 1.0.95 → 1.0.96-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.
- package/bin/download-install.js +14 -2
- package/lib/cli/validate_node_engine_version.js +3 -1
- package/lib/cli/validate_node_engine_version.js.map +1 -1
- package/lib/formatter/api.js +7 -1
- package/lib/formatter/api.js.map +1 -1
- package/lib/formatter/bvt_analysis_formatter.d.ts +11 -1
- package/lib/formatter/bvt_analysis_formatter.js +144 -56
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.js +0 -1
- package/lib/formatter/feature_data_format.js.map +1 -1
- package/lib/formatter/helpers/constants.d.ts +6 -0
- package/lib/formatter/helpers/constants.js +13 -3
- package/lib/formatter/helpers/constants.js.map +1 -1
- package/lib/formatter/helpers/report_generator.d.ts +17 -1
- package/lib/formatter/helpers/report_generator.js +236 -22
- package/lib/formatter/helpers/report_generator.js.map +1 -1
- package/lib/formatter/helpers/upload_serivce.d.ts +14 -1
- package/lib/formatter/helpers/upload_serivce.js +57 -4
- package/lib/formatter/helpers/upload_serivce.js.map +1 -1
- package/lib/formatter/helpers/uploader.js +11 -14
- package/lib/formatter/helpers/uploader.js.map +1 -1
- package/lib/formatter/summary_formatter.js +4 -0
- package/lib/formatter/summary_formatter.js.map +1 -1
- package/lib/runtime/test_case_runner.d.ts +1 -0
- package/lib/runtime/test_case_runner.js +10 -1
- package/lib/runtime/test_case_runner.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 +3 -1
|
@@ -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;
|
|
@@ -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";
|
|
@@ -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;
|
|
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<
|
|
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 {};
|
|
@@ -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;
|
|
@@ -65,12 +72,18 @@ class ReportGenerator {
|
|
|
65
72
|
this.logs = [];
|
|
66
73
|
this.networkLog = [];
|
|
67
74
|
this.stepLogs = [];
|
|
75
|
+
this.stepNetworkLogs = [];
|
|
68
76
|
this.runName = '';
|
|
77
|
+
this.ariaSnapshot = '';
|
|
78
|
+
this.initialAriaSnapshot = '';
|
|
79
|
+
this.testCaseLog = [];
|
|
80
|
+
this.loggingOverridden = false; // Flag to track if logging is overridden
|
|
69
81
|
this.reportFolder = null;
|
|
70
82
|
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
83
|
+
this.retryCount = 3;
|
|
71
84
|
}
|
|
72
|
-
async handleMessage(envelope) {
|
|
73
|
-
if (envelope.meta && envelope.meta
|
|
85
|
+
async handleMessage(envelope, reRunId) {
|
|
86
|
+
if (envelope.meta && 'runName' in envelope.meta) {
|
|
74
87
|
this.runName = envelope.meta.runName;
|
|
75
88
|
}
|
|
76
89
|
const type = Object.keys(envelope)[0];
|
|
@@ -97,10 +110,30 @@ class ReportGenerator {
|
|
|
97
110
|
case 'testRunStarted': {
|
|
98
111
|
const testRunStarted = envelope[type];
|
|
99
112
|
this.onTestRunStarted(testRunStarted);
|
|
113
|
+
await this.uploadService.createStatus('running');
|
|
100
114
|
break;
|
|
101
115
|
}
|
|
102
116
|
case 'testCase': {
|
|
103
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
|
|
104
137
|
this.onTestCase(testCase);
|
|
105
138
|
break;
|
|
106
139
|
}
|
|
@@ -126,13 +159,14 @@ class ReportGenerator {
|
|
|
126
159
|
}
|
|
127
160
|
case 'testCaseFinished': {
|
|
128
161
|
const testCaseFinished = envelope[type];
|
|
129
|
-
|
|
130
|
-
|
|
162
|
+
// Call the onTestCaseFinished method
|
|
163
|
+
const result = await this.onTestCaseFinished(testCaseFinished, reRunId);
|
|
164
|
+
return result;
|
|
131
165
|
}
|
|
132
166
|
// case "hook": { break} // After Hook
|
|
133
167
|
case 'testRunFinished': {
|
|
134
168
|
const testRunFinished = envelope[type];
|
|
135
|
-
this.onTestRunFinished(testRunFinished);
|
|
169
|
+
await this.onTestRunFinished(testRunFinished);
|
|
136
170
|
break;
|
|
137
171
|
}
|
|
138
172
|
// case "parameterType" : { break}
|
|
@@ -263,7 +297,10 @@ class ReportGenerator {
|
|
|
263
297
|
result: {
|
|
264
298
|
status: 'UNKNOWN',
|
|
265
299
|
},
|
|
300
|
+
networkData: [],
|
|
266
301
|
webLog: [],
|
|
302
|
+
data: {},
|
|
303
|
+
ariaSnapshot: this.ariaSnapshot,
|
|
267
304
|
});
|
|
268
305
|
return this.stepReportMap.get(pickleStep.id);
|
|
269
306
|
});
|
|
@@ -306,6 +343,14 @@ class ReportGenerator {
|
|
|
306
343
|
this.reportFolder = body.replaceAll('\\', '/');
|
|
307
344
|
return;
|
|
308
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
|
+
}
|
|
309
354
|
if (mediaType === 'application/json+env') {
|
|
310
355
|
const data = JSON.parse(body);
|
|
311
356
|
this.report.env = data;
|
|
@@ -325,6 +370,7 @@ class ReportGenerator {
|
|
|
325
370
|
const networkLog = JSON.parse(body);
|
|
326
371
|
if (this.networkLog.length < 1000)
|
|
327
372
|
this.networkLog.push(networkLog);
|
|
373
|
+
this.stepNetworkLogs.push(networkLog);
|
|
328
374
|
}
|
|
329
375
|
const testStep = this.testStepMap.get(testStepId);
|
|
330
376
|
if (testStep.pickleStepId === undefined)
|
|
@@ -334,6 +380,46 @@ class ReportGenerator {
|
|
|
334
380
|
const command = JSON.parse(body);
|
|
335
381
|
stepProgess.commands.push(command);
|
|
336
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
|
+
};
|
|
337
423
|
}
|
|
338
424
|
onTestStepFinished(testStepFinished) {
|
|
339
425
|
const { testStepId, testStepResult, timestamp } = testStepFinished;
|
|
@@ -378,18 +464,73 @@ class ReportGenerator {
|
|
|
378
464
|
catch (error) {
|
|
379
465
|
console.log('Error reading data.json');
|
|
380
466
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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
|
+
}
|
|
388
482
|
stepProgess.webLog = this.stepLogs;
|
|
483
|
+
stepProgess.networkData = this.stepNetworkLogs;
|
|
484
|
+
stepProgess.ariaSnapshot = this.ariaSnapshot;
|
|
485
|
+
this.ariaSnapshot = '';
|
|
486
|
+
this.stepNetworkLogs = [];
|
|
389
487
|
this.stepLogs = [];
|
|
390
488
|
if (Object.keys(data).length > 0) {
|
|
391
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;
|
|
392
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
|
+
// }
|
|
393
534
|
}
|
|
394
535
|
getLogFileContent() {
|
|
395
536
|
let projectPath = process.cwd();
|
|
@@ -437,24 +578,74 @@ class ReportGenerator {
|
|
|
437
578
|
status: 'PASSED',
|
|
438
579
|
};
|
|
439
580
|
}
|
|
440
|
-
async onTestCaseFinished(testCaseFinished) {
|
|
581
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
441
582
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
442
583
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
443
584
|
const prevResult = testProgress.result;
|
|
444
585
|
const steps = Object.values(testProgress.steps);
|
|
445
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);
|
|
446
591
|
testProgress.result = {
|
|
447
592
|
...result,
|
|
448
593
|
startTime: prevResult.startTime,
|
|
449
|
-
endTime
|
|
594
|
+
endTime,
|
|
450
595
|
};
|
|
451
596
|
testProgress.webLog = this.logs;
|
|
452
597
|
testProgress.networkLog = this.networkLog;
|
|
598
|
+
testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
|
|
599
|
+
this.initialAriaSnapshot = '';
|
|
453
600
|
this.networkLog = [];
|
|
454
601
|
this.logs = [];
|
|
455
|
-
|
|
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
|
+
}
|
|
456
627
|
}
|
|
457
|
-
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) {
|
|
458
649
|
let runId = '';
|
|
459
650
|
let projectId = '';
|
|
460
651
|
if (!process.env.UPLOADING_TEST_CASE) {
|
|
@@ -480,10 +671,9 @@ class ReportGenerator {
|
|
|
480
671
|
process.env.PROJECT_ID = projectId;
|
|
481
672
|
}
|
|
482
673
|
}
|
|
483
|
-
await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder);
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
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;
|
|
487
677
|
}
|
|
488
678
|
finally {
|
|
489
679
|
const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
@@ -491,7 +681,30 @@ class ReportGenerator {
|
|
|
491
681
|
process.env.UPLOADING_TEST_CASE = JSON.stringify(arrRem);
|
|
492
682
|
}
|
|
493
683
|
}
|
|
494
|
-
|
|
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) {
|
|
495
708
|
const { timestamp, success, message } = testRunFinished;
|
|
496
709
|
const prevResult = this.report.result;
|
|
497
710
|
this.report.result = {
|
|
@@ -501,6 +714,7 @@ class ReportGenerator {
|
|
|
501
714
|
message,
|
|
502
715
|
// exception,
|
|
503
716
|
};
|
|
717
|
+
await this.uploadService.createStatus(success ? 'passed' : 'failed');
|
|
504
718
|
}
|
|
505
719
|
}
|
|
506
720
|
exports.default = ReportGenerator;
|