@dev-blinq/cucumber-js 1.0.83-main → 1.0.83-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 +31 -19
- package/lib/formatter/api.d.ts +2 -0
- package/lib/formatter/api.js +59 -0
- package/lib/formatter/api.js.map +1 -0
- package/lib/formatter/bvt_analysis_formatter.d.ts +13 -1
- package/lib/formatter/bvt_analysis_formatter.js +197 -71
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.js +14 -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 +40 -13
- package/lib/formatter/helpers/report_generator.js +353 -58
- 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 +16 -3
- package/lib/formatter/helpers/upload_serivce.js +176 -34
- 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 +63 -18
- 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,20 +1,64 @@
|
|
|
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
|
};
|
|
28
|
+
var _a, _b;
|
|
5
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const messages = __importStar(require("@cucumber/messages"));
|
|
6
31
|
const fs_1 = __importDefault(require("fs"));
|
|
7
32
|
const path_1 = __importDefault(require("path"));
|
|
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"));
|
|
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`;
|
|
48
|
+
const REPORT_SERVICE_URL = (_a = process.env.REPORT_SERVICE_URL) !== null && _a !== void 0 ? _a : URL;
|
|
49
|
+
const BATCH_SIZE = 10;
|
|
50
|
+
const MAX_RETRIES = 3;
|
|
51
|
+
const REPORT_SERVICE_TOKEN = (_b = process.env.TOKEN) !== null && _b !== void 0 ? _b : process.env.REPORT_SERVICE_TOKEN;
|
|
8
52
|
class ReportGenerator {
|
|
9
53
|
constructor() {
|
|
10
54
|
this.report = {
|
|
11
55
|
result: {
|
|
12
|
-
status:
|
|
56
|
+
status: "UNKNOWN",
|
|
13
57
|
},
|
|
14
58
|
testCases: [],
|
|
15
59
|
env: {
|
|
16
|
-
name:
|
|
17
|
-
baseUrl:
|
|
60
|
+
name: "",
|
|
61
|
+
baseUrl: "",
|
|
18
62
|
},
|
|
19
63
|
};
|
|
20
64
|
this.gherkinDocumentMap = new Map();
|
|
@@ -27,67 +71,98 @@ class ReportGenerator {
|
|
|
27
71
|
this.scenarioIterationCountMap = new Map();
|
|
28
72
|
this.logs = [];
|
|
29
73
|
this.networkLog = [];
|
|
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
|
|
30
81
|
this.reportFolder = null;
|
|
82
|
+
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
31
83
|
}
|
|
32
|
-
handleMessage(envelope) {
|
|
84
|
+
async handleMessage(envelope, reRunId) {
|
|
85
|
+
if (envelope.meta && "runName" in envelope.meta) {
|
|
86
|
+
this.runName = envelope.meta.runName;
|
|
87
|
+
}
|
|
33
88
|
const type = Object.keys(envelope)[0];
|
|
34
89
|
switch (type) {
|
|
35
90
|
// case "meta": { break}
|
|
36
91
|
// case "source": { break}
|
|
37
|
-
case
|
|
92
|
+
case "parseError": {
|
|
38
93
|
const parseError = envelope[type];
|
|
39
94
|
this.handleParseError(parseError);
|
|
40
95
|
break;
|
|
41
96
|
}
|
|
42
|
-
case
|
|
97
|
+
case "gherkinDocument": {
|
|
43
98
|
const doc = envelope[type];
|
|
44
99
|
this.onGherkinDocument(doc);
|
|
45
100
|
break;
|
|
46
101
|
}
|
|
47
|
-
case
|
|
102
|
+
case "pickle": {
|
|
48
103
|
const pickle = envelope[type];
|
|
49
104
|
this.onPickle(pickle);
|
|
50
105
|
break;
|
|
51
106
|
}
|
|
52
107
|
// case "stepDefinition": { break}
|
|
53
108
|
// case "hook": { break} // Before Hook
|
|
54
|
-
case
|
|
109
|
+
case "testRunStarted": {
|
|
55
110
|
const testRunStarted = envelope[type];
|
|
56
111
|
this.onTestRunStarted(testRunStarted);
|
|
57
112
|
break;
|
|
58
113
|
}
|
|
59
|
-
case
|
|
114
|
+
case "testCase": {
|
|
60
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
|
|
61
135
|
this.onTestCase(testCase);
|
|
62
136
|
break;
|
|
63
137
|
}
|
|
64
|
-
case
|
|
138
|
+
case "testCaseStarted": {
|
|
65
139
|
const testCaseStarted = envelope[type];
|
|
66
140
|
this.onTestCaseStarted(testCaseStarted);
|
|
67
141
|
break;
|
|
68
142
|
}
|
|
69
|
-
case
|
|
143
|
+
case "testStepStarted": {
|
|
70
144
|
const testStepStarted = envelope[type];
|
|
71
145
|
this.onTestStepStarted(testStepStarted);
|
|
72
146
|
break;
|
|
73
147
|
}
|
|
74
|
-
case
|
|
148
|
+
case "attachment": {
|
|
75
149
|
const attachment = envelope[type];
|
|
76
150
|
this.onAttachment(attachment);
|
|
77
151
|
break;
|
|
78
152
|
}
|
|
79
|
-
case
|
|
153
|
+
case "testStepFinished": {
|
|
80
154
|
const testStepFinished = envelope[type];
|
|
81
155
|
this.onTestStepFinished(testStepFinished);
|
|
82
156
|
break;
|
|
83
157
|
}
|
|
84
|
-
case
|
|
158
|
+
case "testCaseFinished": {
|
|
85
159
|
const testCaseFinished = envelope[type];
|
|
86
|
-
|
|
87
|
-
|
|
160
|
+
// Call the onTestCaseFinished method
|
|
161
|
+
const result = await this.onTestCaseFinished(testCaseFinished, reRunId);
|
|
162
|
+
return result;
|
|
88
163
|
}
|
|
89
164
|
// case "hook": { break} // After Hook
|
|
90
|
-
case
|
|
165
|
+
case "testRunFinished": {
|
|
91
166
|
const testRunFinished = envelope[type];
|
|
92
167
|
this.onTestRunFinished(testRunFinished);
|
|
93
168
|
break;
|
|
@@ -103,7 +178,7 @@ class ReportGenerator {
|
|
|
103
178
|
const { message } = parseError;
|
|
104
179
|
const timestamp = new Date().getTime();
|
|
105
180
|
this.report.result = {
|
|
106
|
-
status:
|
|
181
|
+
status: "FAILED",
|
|
107
182
|
startTime: timestamp,
|
|
108
183
|
endTime: timestamp,
|
|
109
184
|
message: message,
|
|
@@ -146,7 +221,7 @@ class ReportGenerator {
|
|
|
146
221
|
}
|
|
147
222
|
onTestRunStarted(testRunStarted) {
|
|
148
223
|
this.report.result = {
|
|
149
|
-
status:
|
|
224
|
+
status: "STARTED",
|
|
150
225
|
startTime: this.getTimeStamp(testRunStarted.timestamp),
|
|
151
226
|
};
|
|
152
227
|
}
|
|
@@ -179,8 +254,7 @@ class ReportGenerator {
|
|
|
179
254
|
for (const tableRow of examples.tableBody) {
|
|
180
255
|
if (tableRow.id === exampleId) {
|
|
181
256
|
for (let i = 0; i < examples.tableHeader.cells.length; i++) {
|
|
182
|
-
parameters[examples.tableHeader.cells[i].value] =
|
|
183
|
-
tableRow.cells[i].value;
|
|
257
|
+
parameters[examples.tableHeader.cells[i].value] = tableRow.cells[i].value;
|
|
184
258
|
}
|
|
185
259
|
}
|
|
186
260
|
}
|
|
@@ -218,8 +292,12 @@ class ReportGenerator {
|
|
|
218
292
|
text: step.text,
|
|
219
293
|
commands: [],
|
|
220
294
|
result: {
|
|
221
|
-
status:
|
|
295
|
+
status: "UNKNOWN",
|
|
222
296
|
},
|
|
297
|
+
networkData: [],
|
|
298
|
+
webLog: [],
|
|
299
|
+
data: {},
|
|
300
|
+
ariaSnapshot: this.ariaSnapshot,
|
|
223
301
|
});
|
|
224
302
|
return this.stepReportMap.get(pickleStep.id);
|
|
225
303
|
});
|
|
@@ -231,11 +309,15 @@ class ReportGenerator {
|
|
|
231
309
|
parameters,
|
|
232
310
|
steps,
|
|
233
311
|
result: {
|
|
234
|
-
status:
|
|
312
|
+
status: "STARTED",
|
|
235
313
|
startTime: this.getTimeStamp(timestamp),
|
|
236
314
|
},
|
|
237
315
|
webLog: [],
|
|
238
316
|
networkLog: [],
|
|
317
|
+
env: {
|
|
318
|
+
name: this.report.env.name,
|
|
319
|
+
baseUrl: this.report.env.baseUrl,
|
|
320
|
+
},
|
|
239
321
|
});
|
|
240
322
|
this.report.testCases.push(this.testCaseReportMap.get(id));
|
|
241
323
|
}
|
|
@@ -248,78 +330,200 @@ class ReportGenerator {
|
|
|
248
330
|
return;
|
|
249
331
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
250
332
|
stepProgess.result = {
|
|
251
|
-
status:
|
|
333
|
+
status: "STARTED",
|
|
252
334
|
startTime: this.getTimeStamp(timestamp),
|
|
253
335
|
};
|
|
254
336
|
}
|
|
255
337
|
onAttachment(attachment) {
|
|
256
338
|
const { testStepId, body, mediaType } = attachment;
|
|
257
|
-
if (mediaType ===
|
|
258
|
-
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;
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (mediaType === "application/json+snapshot-after") {
|
|
348
|
+
this.ariaSnapshot = body;
|
|
259
349
|
return;
|
|
260
350
|
}
|
|
261
|
-
if (mediaType ===
|
|
351
|
+
if (mediaType === "application/json+env") {
|
|
262
352
|
const data = JSON.parse(body);
|
|
263
353
|
this.report.env = data;
|
|
354
|
+
this.report.testCases.map((testCase) => {
|
|
355
|
+
testCase.env = data;
|
|
356
|
+
return testCase;
|
|
357
|
+
});
|
|
264
358
|
}
|
|
265
|
-
if (mediaType ===
|
|
359
|
+
if (mediaType === "application/json+log") {
|
|
266
360
|
const log = JSON.parse(body);
|
|
267
|
-
this.logs.
|
|
361
|
+
if (this.logs.length < 1000) {
|
|
362
|
+
this.logs.push(log);
|
|
363
|
+
this.stepLogs.push(log);
|
|
364
|
+
}
|
|
268
365
|
}
|
|
269
|
-
if (mediaType ===
|
|
366
|
+
if (mediaType === "application/json+network") {
|
|
270
367
|
const networkLog = JSON.parse(body);
|
|
271
|
-
this.networkLog.
|
|
368
|
+
if (this.networkLog.length < 1000)
|
|
369
|
+
this.networkLog.push(networkLog);
|
|
370
|
+
this.stepNetworkLogs.push(networkLog);
|
|
272
371
|
}
|
|
273
372
|
const testStep = this.testStepMap.get(testStepId);
|
|
274
373
|
if (testStep.pickleStepId === undefined)
|
|
275
374
|
return;
|
|
276
375
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
277
|
-
if (mediaType ===
|
|
376
|
+
if (mediaType === "application/json") {
|
|
278
377
|
const command = JSON.parse(body);
|
|
279
378
|
stepProgess.commands.push(command);
|
|
280
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
|
+
};
|
|
281
411
|
}
|
|
282
412
|
onTestStepFinished(testStepFinished) {
|
|
283
413
|
const { testStepId, testStepResult, timestamp } = testStepFinished;
|
|
284
414
|
const testStep = this.testStepMap.get(testStepId);
|
|
285
415
|
if (testStep.pickleStepId === undefined) {
|
|
286
|
-
if (testStepResult.status ===
|
|
416
|
+
if (testStepResult.status === "FAILED") {
|
|
287
417
|
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
288
418
|
}
|
|
289
419
|
return;
|
|
290
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
|
+
}
|
|
291
440
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
292
441
|
const prevStepResult = stepProgess.result;
|
|
293
442
|
let data = {};
|
|
294
|
-
const reportFolder = this.reportFolder;
|
|
295
|
-
if (reportFolder === null) {
|
|
296
|
-
throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
|
|
297
|
-
}
|
|
298
443
|
try {
|
|
299
|
-
|
|
300
|
-
|
|
444
|
+
const reportFolder = this.reportFolder;
|
|
445
|
+
if (reportFolder === null) {
|
|
446
|
+
throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
|
|
447
|
+
}
|
|
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"));
|
|
301
450
|
}
|
|
302
451
|
}
|
|
303
452
|
catch (error) {
|
|
304
|
-
console.log(
|
|
453
|
+
console.log("Error reading data.json");
|
|
305
454
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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 = [];
|
|
313
476
|
if (Object.keys(data).length > 0) {
|
|
314
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;
|
|
315
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
|
+
// }
|
|
316
520
|
}
|
|
317
521
|
getLogFileContent() {
|
|
318
522
|
let projectPath = process.cwd();
|
|
319
523
|
if (process.env.PROJECT_PATH) {
|
|
320
524
|
projectPath = process.env.PROJECT_PATH;
|
|
321
525
|
}
|
|
322
|
-
const logFolder = path_1.default.join(projectPath,
|
|
526
|
+
const logFolder = path_1.default.join(projectPath, "logs", "web");
|
|
323
527
|
if (!fs_1.default.existsSync(logFolder)) {
|
|
324
528
|
return [];
|
|
325
529
|
}
|
|
@@ -331,7 +535,7 @@ class ReportGenerator {
|
|
|
331
535
|
return [];
|
|
332
536
|
}
|
|
333
537
|
try {
|
|
334
|
-
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");
|
|
335
539
|
return JSON.parse(logFileContent);
|
|
336
540
|
}
|
|
337
541
|
catch (error) {
|
|
@@ -341,44 +545,135 @@ class ReportGenerator {
|
|
|
341
545
|
getTestCaseResult(steps) {
|
|
342
546
|
for (const step of steps) {
|
|
343
547
|
switch (step.result.status) {
|
|
344
|
-
case
|
|
548
|
+
case "FAILED":
|
|
345
549
|
return {
|
|
346
550
|
status: step.result.status,
|
|
347
551
|
message: step.result.message,
|
|
348
552
|
// exception: step.result.exception,
|
|
349
553
|
};
|
|
350
|
-
case
|
|
351
|
-
case
|
|
352
|
-
case
|
|
554
|
+
case "AMBIGUOUS":
|
|
555
|
+
case "UNDEFINED":
|
|
556
|
+
case "PENDING":
|
|
353
557
|
return {
|
|
354
|
-
status:
|
|
558
|
+
status: "FAILED",
|
|
355
559
|
message: `step "${step.text}" is ${step.result.status}`,
|
|
356
560
|
};
|
|
357
561
|
}
|
|
358
562
|
}
|
|
359
563
|
return {
|
|
360
|
-
status:
|
|
564
|
+
status: "PASSED",
|
|
361
565
|
};
|
|
362
566
|
}
|
|
363
|
-
onTestCaseFinished(testCaseFinished) {
|
|
567
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
364
568
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
365
569
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
366
570
|
const prevResult = testProgress.result;
|
|
367
571
|
const steps = Object.values(testProgress.steps);
|
|
368
572
|
const result = this.getTestCaseResult(steps);
|
|
573
|
+
const endTime = this.getTimeStamp(timestamp);
|
|
369
574
|
testProgress.result = {
|
|
370
575
|
...result,
|
|
371
576
|
startTime: prevResult.startTime,
|
|
372
|
-
endTime
|
|
577
|
+
endTime,
|
|
373
578
|
};
|
|
374
579
|
testProgress.webLog = this.logs;
|
|
375
580
|
testProgress.networkLog = this.networkLog;
|
|
581
|
+
testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
|
|
582
|
+
this.initialAriaSnapshot = "";
|
|
583
|
+
this.networkLog = [];
|
|
584
|
+
this.logs = [];
|
|
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
|
+
}
|
|
610
|
+
}
|
|
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);
|
|
622
|
+
try {
|
|
623
|
+
if (process.env.RUN_ID && process.env.PROJECT_ID && !process.env.IGNORE_ENV_VARIABLES) {
|
|
624
|
+
runId = process.env.RUN_ID;
|
|
625
|
+
projectId = process.env.PROJECT_ID;
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
const runDoc = await this.uploadService.createRunDocument(this.runName);
|
|
629
|
+
runId = runDoc._id;
|
|
630
|
+
projectId = runDoc.project_id;
|
|
631
|
+
if (!process.env.IGNORE_ENV_VARIABLES) {
|
|
632
|
+
process.env.RUN_ID = runId;
|
|
633
|
+
process.env.PROJECT_ID = projectId;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
|
|
637
|
+
this.writeTestCaseReportToDisk(testCase);
|
|
638
|
+
}
|
|
639
|
+
catch (e) {
|
|
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);
|
|
670
|
+
}
|
|
376
671
|
}
|
|
377
672
|
onTestRunFinished(testRunFinished) {
|
|
378
673
|
const { timestamp, success, message } = testRunFinished;
|
|
379
674
|
const prevResult = this.report.result;
|
|
380
675
|
this.report.result = {
|
|
381
|
-
status: success ?
|
|
676
|
+
status: success ? "PASSED" : "FAILED",
|
|
382
677
|
startTime: prevResult.startTime,
|
|
383
678
|
endTime: this.getTimeStamp(timestamp),
|
|
384
679
|
message,
|