@dev-blinq/cucumber-js 1.0.106-dev → 1.0.106
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 +22 -2
- package/lib/configuration/axios_client.js +1 -1
- package/lib/configuration/axios_client.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 +13 -1
- package/lib/formatter/bvt_analysis_formatter.js +159 -55
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.js +4 -1
- package/lib/formatter/feature_data_format.js.map +1 -1
- package/lib/formatter/helpers/constants.d.ts +50 -0
- package/lib/formatter/helpers/constants.js +60 -0
- package/lib/formatter/helpers/constants.js.map +1 -0
- package/lib/formatter/helpers/report_generator.d.ts +31 -13
- package/lib/formatter/helpers/report_generator.js +322 -71
- package/lib/formatter/helpers/report_generator.js.map +1 -1
- package/lib/formatter/helpers/test_case_attempt_formatter.js +1 -1
- package/lib/formatter/helpers/test_case_attempt_formatter.js.map +1 -1
- package/lib/formatter/helpers/upload_serivce.d.ts +15 -3
- package/lib/formatter/helpers/upload_serivce.js +112 -47
- package/lib/formatter/helpers/upload_serivce.js.map +1 -1
- package/lib/formatter/helpers/uploader.d.ts +2 -1
- package/lib/formatter/helpers/uploader.js +16 -1
- 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 +4 -2
|
@@ -1,19 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
var _a, _b;
|
|
6
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const messages = __importStar(require("@cucumber/messages"));
|
|
7
31
|
const fs_1 = __importDefault(require("fs"));
|
|
8
32
|
const path_1 = __importDefault(require("path"));
|
|
9
33
|
const upload_serivce_1 = require("./upload_serivce");
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
34
|
+
const fs_extra_1 = require("fs-extra");
|
|
35
|
+
// type JsonException = messages.Exception
|
|
36
|
+
const object_path_1 = __importDefault(require("object-path"));
|
|
37
|
+
const URL = process.env.NODE_ENV_BLINQ === "dev"
|
|
38
|
+
? "https://dev.api.blinq.io/api/runs"
|
|
39
|
+
: process.env.NODE_ENV_BLINQ === "local"
|
|
40
|
+
? "http://localhost:5001/api/runs"
|
|
41
|
+
: process.env.NODE_ENV_BLINQ === "stage"
|
|
42
|
+
? "https://stage.api.blinq.io/api/runs"
|
|
43
|
+
: process.env.NODE_ENV_BLINQ === "prod"
|
|
44
|
+
? "https://api.blinq.io/api/runs"
|
|
45
|
+
: !process.env.NODE_ENV_BLINQ
|
|
46
|
+
? "https://api.blinq.io/api/runs"
|
|
47
|
+
: `${process.env.NODE_ENV_BLINQ}/api/runs`;
|
|
17
48
|
const REPORT_SERVICE_URL = (_a = process.env.REPORT_SERVICE_URL) !== null && _a !== void 0 ? _a : URL;
|
|
18
49
|
const BATCH_SIZE = 10;
|
|
19
50
|
const MAX_RETRIES = 3;
|
|
@@ -22,12 +53,12 @@ class ReportGenerator {
|
|
|
22
53
|
constructor() {
|
|
23
54
|
this.report = {
|
|
24
55
|
result: {
|
|
25
|
-
status:
|
|
56
|
+
status: "UNKNOWN",
|
|
26
57
|
},
|
|
27
58
|
testCases: [],
|
|
28
59
|
env: {
|
|
29
|
-
name:
|
|
30
|
-
baseUrl:
|
|
60
|
+
name: "",
|
|
61
|
+
baseUrl: "",
|
|
31
62
|
},
|
|
32
63
|
};
|
|
33
64
|
this.gherkinDocumentMap = new Map();
|
|
@@ -40,72 +71,98 @@ class ReportGenerator {
|
|
|
40
71
|
this.scenarioIterationCountMap = new Map();
|
|
41
72
|
this.logs = [];
|
|
42
73
|
this.networkLog = [];
|
|
43
|
-
this.
|
|
74
|
+
this.stepLogs = [];
|
|
75
|
+
this.stepNetworkLogs = [];
|
|
76
|
+
this.runName = "";
|
|
77
|
+
this.ariaSnapshot = "";
|
|
78
|
+
this.initialAriaSnapshot = "";
|
|
79
|
+
this.testCaseLog = [];
|
|
80
|
+
this.loggingOverridden = false; // Flag to track if logging is overridden
|
|
44
81
|
this.reportFolder = null;
|
|
45
82
|
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
46
83
|
}
|
|
47
|
-
async handleMessage(envelope) {
|
|
48
|
-
if (envelope.meta && envelope.meta
|
|
84
|
+
async handleMessage(envelope, reRunId) {
|
|
85
|
+
if (envelope.meta && "runName" in envelope.meta) {
|
|
49
86
|
this.runName = envelope.meta.runName;
|
|
50
87
|
}
|
|
51
88
|
const type = Object.keys(envelope)[0];
|
|
52
89
|
switch (type) {
|
|
53
90
|
// case "meta": { break}
|
|
54
91
|
// case "source": { break}
|
|
55
|
-
case
|
|
92
|
+
case "parseError": {
|
|
56
93
|
const parseError = envelope[type];
|
|
57
94
|
this.handleParseError(parseError);
|
|
58
95
|
break;
|
|
59
96
|
}
|
|
60
|
-
case
|
|
97
|
+
case "gherkinDocument": {
|
|
61
98
|
const doc = envelope[type];
|
|
62
99
|
this.onGherkinDocument(doc);
|
|
63
100
|
break;
|
|
64
101
|
}
|
|
65
|
-
case
|
|
102
|
+
case "pickle": {
|
|
66
103
|
const pickle = envelope[type];
|
|
67
104
|
this.onPickle(pickle);
|
|
68
105
|
break;
|
|
69
106
|
}
|
|
70
107
|
// case "stepDefinition": { break}
|
|
71
108
|
// case "hook": { break} // Before Hook
|
|
72
|
-
case
|
|
109
|
+
case "testRunStarted": {
|
|
73
110
|
const testRunStarted = envelope[type];
|
|
74
111
|
this.onTestRunStarted(testRunStarted);
|
|
75
112
|
break;
|
|
76
113
|
}
|
|
77
|
-
case
|
|
114
|
+
case "testCase": {
|
|
78
115
|
const testCase = envelope[type];
|
|
116
|
+
// Initialize the log storage
|
|
117
|
+
this.testCaseLog = [];
|
|
118
|
+
if (!this.loggingOverridden) {
|
|
119
|
+
this.loggingOverridden = true;
|
|
120
|
+
// Store the original process.stdout.write, and process.stderr.write
|
|
121
|
+
const originalStdoutWrite = process.stdout.write;
|
|
122
|
+
const originalStderrWrite = process.stderr.write;
|
|
123
|
+
// Override process.stdout.write
|
|
124
|
+
process.stdout.write = (chunk, ...args) => {
|
|
125
|
+
this.testCaseLog.push(chunk.toString());
|
|
126
|
+
return originalStdoutWrite.call(process.stdout, chunk, ...args);
|
|
127
|
+
};
|
|
128
|
+
// Override process.stderr.write
|
|
129
|
+
process.stderr.write = (chunk, ...args) => {
|
|
130
|
+
this.testCaseLog.push(chunk.toString());
|
|
131
|
+
return originalStderrWrite.call(process.stderr, chunk, ...args);
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// Call the onTestCase method
|
|
79
135
|
this.onTestCase(testCase);
|
|
80
136
|
break;
|
|
81
137
|
}
|
|
82
|
-
case
|
|
138
|
+
case "testCaseStarted": {
|
|
83
139
|
const testCaseStarted = envelope[type];
|
|
84
140
|
this.onTestCaseStarted(testCaseStarted);
|
|
85
141
|
break;
|
|
86
142
|
}
|
|
87
|
-
case
|
|
143
|
+
case "testStepStarted": {
|
|
88
144
|
const testStepStarted = envelope[type];
|
|
89
145
|
this.onTestStepStarted(testStepStarted);
|
|
90
146
|
break;
|
|
91
147
|
}
|
|
92
|
-
case
|
|
148
|
+
case "attachment": {
|
|
93
149
|
const attachment = envelope[type];
|
|
94
150
|
this.onAttachment(attachment);
|
|
95
151
|
break;
|
|
96
152
|
}
|
|
97
|
-
case
|
|
153
|
+
case "testStepFinished": {
|
|
98
154
|
const testStepFinished = envelope[type];
|
|
99
155
|
this.onTestStepFinished(testStepFinished);
|
|
100
156
|
break;
|
|
101
157
|
}
|
|
102
|
-
case
|
|
158
|
+
case "testCaseFinished": {
|
|
103
159
|
const testCaseFinished = envelope[type];
|
|
104
|
-
|
|
105
|
-
|
|
160
|
+
// Call the onTestCaseFinished method
|
|
161
|
+
const result = await this.onTestCaseFinished(testCaseFinished, reRunId);
|
|
162
|
+
return result;
|
|
106
163
|
}
|
|
107
164
|
// case "hook": { break} // After Hook
|
|
108
|
-
case
|
|
165
|
+
case "testRunFinished": {
|
|
109
166
|
const testRunFinished = envelope[type];
|
|
110
167
|
this.onTestRunFinished(testRunFinished);
|
|
111
168
|
break;
|
|
@@ -121,7 +178,7 @@ class ReportGenerator {
|
|
|
121
178
|
const { message } = parseError;
|
|
122
179
|
const timestamp = new Date().getTime();
|
|
123
180
|
this.report.result = {
|
|
124
|
-
status:
|
|
181
|
+
status: "FAILED",
|
|
125
182
|
startTime: timestamp,
|
|
126
183
|
endTime: timestamp,
|
|
127
184
|
message: message,
|
|
@@ -164,7 +221,7 @@ class ReportGenerator {
|
|
|
164
221
|
}
|
|
165
222
|
onTestRunStarted(testRunStarted) {
|
|
166
223
|
this.report.result = {
|
|
167
|
-
status:
|
|
224
|
+
status: "STARTED",
|
|
168
225
|
startTime: this.getTimeStamp(testRunStarted.timestamp),
|
|
169
226
|
};
|
|
170
227
|
}
|
|
@@ -197,8 +254,7 @@ class ReportGenerator {
|
|
|
197
254
|
for (const tableRow of examples.tableBody) {
|
|
198
255
|
if (tableRow.id === exampleId) {
|
|
199
256
|
for (let i = 0; i < examples.tableHeader.cells.length; i++) {
|
|
200
|
-
parameters[examples.tableHeader.cells[i].value] =
|
|
201
|
-
tableRow.cells[i].value;
|
|
257
|
+
parameters[examples.tableHeader.cells[i].value] = tableRow.cells[i].value;
|
|
202
258
|
}
|
|
203
259
|
}
|
|
204
260
|
}
|
|
@@ -236,8 +292,12 @@ class ReportGenerator {
|
|
|
236
292
|
text: step.text,
|
|
237
293
|
commands: [],
|
|
238
294
|
result: {
|
|
239
|
-
status:
|
|
295
|
+
status: "UNKNOWN",
|
|
240
296
|
},
|
|
297
|
+
networkData: [],
|
|
298
|
+
webLog: [],
|
|
299
|
+
data: {},
|
|
300
|
+
ariaSnapshot: this.ariaSnapshot,
|
|
241
301
|
});
|
|
242
302
|
return this.stepReportMap.get(pickleStep.id);
|
|
243
303
|
});
|
|
@@ -249,11 +309,15 @@ class ReportGenerator {
|
|
|
249
309
|
parameters,
|
|
250
310
|
steps,
|
|
251
311
|
result: {
|
|
252
|
-
status:
|
|
312
|
+
status: "STARTED",
|
|
253
313
|
startTime: this.getTimeStamp(timestamp),
|
|
254
314
|
},
|
|
255
315
|
webLog: [],
|
|
256
316
|
networkLog: [],
|
|
317
|
+
env: {
|
|
318
|
+
name: this.report.env.name,
|
|
319
|
+
baseUrl: this.report.env.baseUrl,
|
|
320
|
+
},
|
|
257
321
|
});
|
|
258
322
|
this.report.testCases.push(this.testCaseReportMap.get(id));
|
|
259
323
|
}
|
|
@@ -266,48 +330,113 @@ class ReportGenerator {
|
|
|
266
330
|
return;
|
|
267
331
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
268
332
|
stepProgess.result = {
|
|
269
|
-
status:
|
|
333
|
+
status: "STARTED",
|
|
270
334
|
startTime: this.getTimeStamp(timestamp),
|
|
271
335
|
};
|
|
272
336
|
}
|
|
273
337
|
onAttachment(attachment) {
|
|
274
338
|
const { testStepId, body, mediaType } = attachment;
|
|
275
|
-
if (mediaType ===
|
|
276
|
-
this.reportFolder = body.replaceAll(
|
|
339
|
+
if (mediaType === "text/plain") {
|
|
340
|
+
this.reportFolder = body.replaceAll("\\", "/");
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
if (mediaType === "application/json+snapshot-before") {
|
|
344
|
+
this.initialAriaSnapshot = body;
|
|
277
345
|
return;
|
|
278
346
|
}
|
|
279
|
-
if (mediaType ===
|
|
347
|
+
if (mediaType === "application/json+snapshot-after") {
|
|
348
|
+
this.ariaSnapshot = body;
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (mediaType === "application/json+env") {
|
|
280
352
|
const data = JSON.parse(body);
|
|
281
353
|
this.report.env = data;
|
|
354
|
+
this.report.testCases.map((testCase) => {
|
|
355
|
+
testCase.env = data;
|
|
356
|
+
return testCase;
|
|
357
|
+
});
|
|
282
358
|
}
|
|
283
|
-
if (mediaType ===
|
|
359
|
+
if (mediaType === "application/json+log") {
|
|
284
360
|
const log = JSON.parse(body);
|
|
285
|
-
if (this.logs.length < 1000)
|
|
361
|
+
if (this.logs.length < 1000) {
|
|
286
362
|
this.logs.push(log);
|
|
363
|
+
this.stepLogs.push(log);
|
|
364
|
+
}
|
|
287
365
|
}
|
|
288
|
-
if (mediaType ===
|
|
366
|
+
if (mediaType === "application/json+network") {
|
|
289
367
|
const networkLog = JSON.parse(body);
|
|
290
368
|
if (this.networkLog.length < 1000)
|
|
291
369
|
this.networkLog.push(networkLog);
|
|
370
|
+
this.stepNetworkLogs.push(networkLog);
|
|
292
371
|
}
|
|
293
372
|
const testStep = this.testStepMap.get(testStepId);
|
|
294
373
|
if (testStep.pickleStepId === undefined)
|
|
295
374
|
return;
|
|
296
375
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
297
|
-
if (mediaType ===
|
|
376
|
+
if (mediaType === "application/json") {
|
|
298
377
|
const command = JSON.parse(body);
|
|
299
378
|
stepProgess.commands.push(command);
|
|
300
379
|
}
|
|
380
|
+
else if (mediaType === "application/json+trace") {
|
|
381
|
+
const data = JSON.parse(body);
|
|
382
|
+
stepProgess.traceFilePath = data.traceFilePath;
|
|
383
|
+
}
|
|
384
|
+
if (mediaType === "application/json+bruno") {
|
|
385
|
+
try {
|
|
386
|
+
const data = JSON.parse(body);
|
|
387
|
+
stepProgess.brunoData = data;
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
console.error("Error parsing bruno data:", error);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
getFailedTestStepResult({ commands, startTime, endTime, result, }) {
|
|
395
|
+
for (const command of commands) {
|
|
396
|
+
if (command.result.status === "FAILED") {
|
|
397
|
+
return {
|
|
398
|
+
status: "FAILED",
|
|
399
|
+
message: command.result.message,
|
|
400
|
+
startTime,
|
|
401
|
+
endTime,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return {
|
|
406
|
+
status: "FAILED",
|
|
407
|
+
startTime,
|
|
408
|
+
endTime,
|
|
409
|
+
message: result.message,
|
|
410
|
+
};
|
|
301
411
|
}
|
|
302
412
|
onTestStepFinished(testStepFinished) {
|
|
303
413
|
const { testStepId, testStepResult, timestamp } = testStepFinished;
|
|
304
414
|
const testStep = this.testStepMap.get(testStepId);
|
|
305
415
|
if (testStep.pickleStepId === undefined) {
|
|
306
|
-
if (testStepResult.status ===
|
|
416
|
+
if (testStepResult.status === "FAILED") {
|
|
307
417
|
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
308
418
|
}
|
|
309
419
|
return;
|
|
310
420
|
}
|
|
421
|
+
if (testStepResult.status === "UNDEFINED") {
|
|
422
|
+
const step = this.stepReportMap.get(testStep.pickleStepId);
|
|
423
|
+
const stepName = step ? step.keyword + " " + step.text : "Undefined step";
|
|
424
|
+
const undefinedCommand = {
|
|
425
|
+
testStepId: testStepId,
|
|
426
|
+
body: JSON.stringify({
|
|
427
|
+
type: "error",
|
|
428
|
+
text: "Undefined step: " + stepName,
|
|
429
|
+
result: {
|
|
430
|
+
status: "FAILED",
|
|
431
|
+
startTime: this.getTimeStamp(timestamp),
|
|
432
|
+
endTime: this.getTimeStamp(timestamp),
|
|
433
|
+
},
|
|
434
|
+
}),
|
|
435
|
+
mediaType: "application/json",
|
|
436
|
+
contentEncoding: messages.AttachmentContentEncoding.IDENTITY,
|
|
437
|
+
};
|
|
438
|
+
this.onAttachment(undefinedCommand);
|
|
439
|
+
}
|
|
311
440
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
312
441
|
const prevStepResult = stepProgess.result;
|
|
313
442
|
let data = {};
|
|
@@ -316,30 +445,85 @@ class ReportGenerator {
|
|
|
316
445
|
if (reportFolder === null) {
|
|
317
446
|
throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
|
|
318
447
|
}
|
|
319
|
-
if (fs_1.default.existsSync(path_1.default.join(reportFolder,
|
|
320
|
-
data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder,
|
|
448
|
+
if (fs_1.default.existsSync(path_1.default.join(reportFolder, "data.json"))) {
|
|
449
|
+
data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder, "data.json"), "utf8"));
|
|
321
450
|
}
|
|
322
451
|
}
|
|
323
452
|
catch (error) {
|
|
324
|
-
console.log(
|
|
453
|
+
console.log("Error reading data.json");
|
|
325
454
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
455
|
+
if (testStepResult.status === "FAILED") {
|
|
456
|
+
stepProgess.result = this.getFailedTestStepResult({
|
|
457
|
+
commands: stepProgess.commands,
|
|
458
|
+
startTime: prevStepResult.startTime,
|
|
459
|
+
endTime: this.getTimeStamp(timestamp),
|
|
460
|
+
result: testStepResult,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
stepProgess.result = {
|
|
465
|
+
status: testStepResult.status,
|
|
466
|
+
startTime: prevStepResult.startTime,
|
|
467
|
+
endTime: this.getTimeStamp(timestamp),
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
stepProgess.webLog = this.stepLogs;
|
|
471
|
+
stepProgess.networkData = this.stepNetworkLogs;
|
|
472
|
+
stepProgess.ariaSnapshot = this.ariaSnapshot;
|
|
473
|
+
this.ariaSnapshot = "";
|
|
474
|
+
this.stepNetworkLogs = [];
|
|
475
|
+
this.stepLogs = [];
|
|
333
476
|
if (Object.keys(data).length > 0) {
|
|
334
477
|
stepProgess.data = data;
|
|
478
|
+
const id = testStepFinished.testCaseStartedId;
|
|
479
|
+
const parameters = this.testCaseReportMap.get(id).parameters;
|
|
480
|
+
const _parameters = {};
|
|
481
|
+
Object.keys(parameters).map((key) => {
|
|
482
|
+
if (parameters[key].startsWith("{{") && parameters[key].endsWith("}}")) {
|
|
483
|
+
const path = parameters[key].slice(2, -2).split(".");
|
|
484
|
+
let value = String(object_path_1.default.get(data, path));
|
|
485
|
+
if (value) {
|
|
486
|
+
if (value.startsWith("secret:")) {
|
|
487
|
+
value = "secret:****";
|
|
488
|
+
}
|
|
489
|
+
else if (value.startsWith("totp:")) {
|
|
490
|
+
value = "totp:****";
|
|
491
|
+
}
|
|
492
|
+
else if (value.startsWith("mask:")) {
|
|
493
|
+
value = "mask:****";
|
|
494
|
+
}
|
|
495
|
+
_parameters[key] = value;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
_parameters[key] = parameters[key];
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
this.report.testCases.find((testCase) => {
|
|
503
|
+
return testCase.id === id;
|
|
504
|
+
}).parameters = _parameters;
|
|
335
505
|
}
|
|
506
|
+
// if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
507
|
+
// this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH
|
|
508
|
+
// if (!fs.existsSync(this.reportFolder)) {
|
|
509
|
+
// fs.mkdirSync(this.reportFolder)
|
|
510
|
+
// }
|
|
511
|
+
// const reportFilePath = path.join(
|
|
512
|
+
// this.reportFolder,
|
|
513
|
+
// `report.json`
|
|
514
|
+
// )
|
|
515
|
+
// writeFileSync(reportFilePath, JSON.stringify(this.report, null, 2))
|
|
516
|
+
// return undefined
|
|
517
|
+
// // } else {
|
|
518
|
+
// // return await this.uploadTestCase(testProgress, reRunId)
|
|
519
|
+
// }
|
|
336
520
|
}
|
|
337
521
|
getLogFileContent() {
|
|
338
522
|
let projectPath = process.cwd();
|
|
339
523
|
if (process.env.PROJECT_PATH) {
|
|
340
524
|
projectPath = process.env.PROJECT_PATH;
|
|
341
525
|
}
|
|
342
|
-
const logFolder = path_1.default.join(projectPath,
|
|
526
|
+
const logFolder = path_1.default.join(projectPath, "logs", "web");
|
|
343
527
|
if (!fs_1.default.existsSync(logFolder)) {
|
|
344
528
|
return [];
|
|
345
529
|
}
|
|
@@ -351,7 +535,7 @@ class ReportGenerator {
|
|
|
351
535
|
return [];
|
|
352
536
|
}
|
|
353
537
|
try {
|
|
354
|
-
const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`),
|
|
538
|
+
const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`), "utf8");
|
|
355
539
|
return JSON.parse(logFileContent);
|
|
356
540
|
}
|
|
357
541
|
catch (error) {
|
|
@@ -361,47 +545,82 @@ class ReportGenerator {
|
|
|
361
545
|
getTestCaseResult(steps) {
|
|
362
546
|
for (const step of steps) {
|
|
363
547
|
switch (step.result.status) {
|
|
364
|
-
case
|
|
548
|
+
case "FAILED":
|
|
365
549
|
return {
|
|
366
550
|
status: step.result.status,
|
|
367
551
|
message: step.result.message,
|
|
368
552
|
// exception: step.result.exception,
|
|
369
553
|
};
|
|
370
|
-
case
|
|
371
|
-
case
|
|
372
|
-
case
|
|
554
|
+
case "AMBIGUOUS":
|
|
555
|
+
case "UNDEFINED":
|
|
556
|
+
case "PENDING":
|
|
373
557
|
return {
|
|
374
|
-
status:
|
|
558
|
+
status: "FAILED",
|
|
375
559
|
message: `step "${step.text}" is ${step.result.status}`,
|
|
376
560
|
};
|
|
377
561
|
}
|
|
378
562
|
}
|
|
379
563
|
return {
|
|
380
|
-
status:
|
|
564
|
+
status: "PASSED",
|
|
381
565
|
};
|
|
382
566
|
}
|
|
383
|
-
async onTestCaseFinished(testCaseFinished) {
|
|
567
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
384
568
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
385
569
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
386
570
|
const prevResult = testProgress.result;
|
|
387
571
|
const steps = Object.values(testProgress.steps);
|
|
388
572
|
const result = this.getTestCaseResult(steps);
|
|
573
|
+
const endTime = this.getTimeStamp(timestamp);
|
|
389
574
|
testProgress.result = {
|
|
390
575
|
...result,
|
|
391
576
|
startTime: prevResult.startTime,
|
|
392
|
-
endTime
|
|
577
|
+
endTime,
|
|
393
578
|
};
|
|
394
579
|
testProgress.webLog = this.logs;
|
|
395
580
|
testProgress.networkLog = this.networkLog;
|
|
581
|
+
testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
|
|
582
|
+
this.initialAriaSnapshot = "";
|
|
396
583
|
this.networkLog = [];
|
|
397
584
|
this.logs = [];
|
|
398
|
-
|
|
585
|
+
if (this.testCaseLog && this.testCaseLog.length > 0) {
|
|
586
|
+
// Create the logs directory
|
|
587
|
+
const logsDir = path_1.default.join(this.reportFolder, 'editorLogs');
|
|
588
|
+
const fileName = `testCaseLog_${testCaseStartedId}.log`;
|
|
589
|
+
const filePath = path_1.default.join(logsDir, fileName);
|
|
590
|
+
// Ensure the logs directory exists
|
|
591
|
+
fs_1.default.mkdirSync(logsDir, { recursive: true });
|
|
592
|
+
// Write the logs to the file
|
|
593
|
+
fs_1.default.writeFileSync(filePath, this.testCaseLog.join('\n'), 'utf8');
|
|
594
|
+
// Store this ID in the testProgress object so it can be accessed later
|
|
595
|
+
testProgress.logFileId = testCaseStartedId;
|
|
596
|
+
}
|
|
597
|
+
this.testCaseLog = [];
|
|
598
|
+
if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
599
|
+
this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
600
|
+
if (!fs_1.default.existsSync(this.reportFolder)) {
|
|
601
|
+
fs_1.default.mkdirSync(this.reportFolder);
|
|
602
|
+
}
|
|
603
|
+
const reportFilePath = path_1.default.join(this.reportFolder, `${endTime}_${testProgress.scenarioName}.json`);
|
|
604
|
+
(0, fs_extra_1.writeFileSync)(reportFilePath, JSON.stringify(testProgress, null, 2));
|
|
605
|
+
return undefined;
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
return await this.uploadTestCase(testProgress, reRunId);
|
|
609
|
+
}
|
|
399
610
|
}
|
|
400
|
-
async uploadTestCase(testCase) {
|
|
401
|
-
let runId =
|
|
402
|
-
let projectId =
|
|
611
|
+
async uploadTestCase(testCase, rerunId) {
|
|
612
|
+
let runId = "";
|
|
613
|
+
let projectId = "";
|
|
614
|
+
if (!process.env.UPLOADING_TEST_CASE) {
|
|
615
|
+
process.env.UPLOADING_TEST_CASE = "[]";
|
|
616
|
+
}
|
|
617
|
+
const anyRemArr = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
618
|
+
const randomID = Math.random().toString(36).substring(7);
|
|
619
|
+
anyRemArr.push(randomID);
|
|
620
|
+
let data;
|
|
621
|
+
process.env.UPLOADING_TEST_CASE = JSON.stringify(anyRemArr);
|
|
403
622
|
try {
|
|
404
|
-
if (process.env.RUN_ID && process.env.PROJECT_ID) {
|
|
623
|
+
if (process.env.RUN_ID && process.env.PROJECT_ID && !process.env.IGNORE_ENV_VARIABLES) {
|
|
405
624
|
runId = process.env.RUN_ID;
|
|
406
625
|
projectId = process.env.PROJECT_ID;
|
|
407
626
|
}
|
|
@@ -409,20 +628,52 @@ class ReportGenerator {
|
|
|
409
628
|
const runDoc = await this.uploadService.createRunDocument(this.runName);
|
|
410
629
|
runId = runDoc._id;
|
|
411
630
|
projectId = runDoc.project_id;
|
|
412
|
-
process.env.
|
|
413
|
-
|
|
631
|
+
if (!process.env.IGNORE_ENV_VARIABLES) {
|
|
632
|
+
process.env.RUN_ID = runId;
|
|
633
|
+
process.env.PROJECT_ID = projectId;
|
|
634
|
+
}
|
|
414
635
|
}
|
|
415
|
-
await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder);
|
|
636
|
+
data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
|
|
637
|
+
this.writeTestCaseReportToDisk(testCase);
|
|
416
638
|
}
|
|
417
639
|
catch (e) {
|
|
418
|
-
console.error(
|
|
640
|
+
console.error("Error uploading test case:", e);
|
|
641
|
+
}
|
|
642
|
+
finally {
|
|
643
|
+
const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
644
|
+
arrRem.splice(arrRem.indexOf(randomID), 1);
|
|
645
|
+
process.env.UPLOADING_TEST_CASE = JSON.stringify(arrRem);
|
|
646
|
+
}
|
|
647
|
+
return data ? data : null;
|
|
648
|
+
}
|
|
649
|
+
writeTestCaseReportToDisk(testCase) {
|
|
650
|
+
var _a;
|
|
651
|
+
const reportFolder = (_a = this.reportFolder) !== null && _a !== void 0 ? _a : process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
652
|
+
if (!reportFolder) {
|
|
653
|
+
console.error("Report folder is not defined");
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
try {
|
|
657
|
+
let i = 0;
|
|
658
|
+
while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
|
|
659
|
+
i++;
|
|
660
|
+
}
|
|
661
|
+
fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
|
|
662
|
+
//exclude network log from the saved report
|
|
663
|
+
const networkLog = testCase.networkLog;
|
|
664
|
+
delete testCase.networkLog;
|
|
665
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
|
|
666
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
|
|
667
|
+
}
|
|
668
|
+
catch (error) {
|
|
669
|
+
console.error("Error writing test case report to disk:", error);
|
|
419
670
|
}
|
|
420
671
|
}
|
|
421
672
|
onTestRunFinished(testRunFinished) {
|
|
422
673
|
const { timestamp, success, message } = testRunFinished;
|
|
423
674
|
const prevResult = this.report.result;
|
|
424
675
|
this.report.result = {
|
|
425
|
-
status: success ?
|
|
676
|
+
status: success ? "PASSED" : "FAILED",
|
|
426
677
|
startTime: prevResult.startTime,
|
|
427
678
|
endTime: this.getTimeStamp(timestamp),
|
|
428
679
|
message,
|