@dev-blinq/cucumber-js 1.0.80-dev → 1.0.80-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 +40 -13
- package/lib/api/gherkin.js +6 -1
- package/lib/api/gherkin.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.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 +14 -1
- package/lib/formatter/bvt_analysis_formatter.js +226 -73
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.d.ts +2 -2
- package/lib/formatter/feature_data_format.js +49 -6
- 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 +47 -12
- package/lib/formatter/helpers/report_generator.js +322 -51
- 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 +172 -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 +59 -5
- package/lib/formatter/helpers/uploader.js.map +1 -1
- package/lib/formatter/summary_formatter.js +2 -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 +5 -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();
|
|
@@ -25,67 +69,77 @@ class ReportGenerator {
|
|
|
25
69
|
this.stepReportMap = new Map();
|
|
26
70
|
this.testCaseReportMap = new Map();
|
|
27
71
|
this.scenarioIterationCountMap = new Map();
|
|
72
|
+
this.logs = [];
|
|
73
|
+
this.networkLog = [];
|
|
74
|
+
this.stepLogs = [];
|
|
75
|
+
this.stepNetworkLogs = [];
|
|
76
|
+
this.runName = "";
|
|
77
|
+
this.ariaSnapshot = "";
|
|
78
|
+
this.initialAriaSnapshot = "";
|
|
28
79
|
this.reportFolder = null;
|
|
80
|
+
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
29
81
|
}
|
|
30
|
-
handleMessage(envelope) {
|
|
82
|
+
async handleMessage(envelope, reRunId) {
|
|
83
|
+
if (envelope.meta && "runName" in envelope.meta) {
|
|
84
|
+
this.runName = envelope.meta.runName;
|
|
85
|
+
}
|
|
31
86
|
const type = Object.keys(envelope)[0];
|
|
32
87
|
switch (type) {
|
|
33
88
|
// case "meta": { break}
|
|
34
89
|
// case "source": { break}
|
|
35
|
-
case
|
|
90
|
+
case "parseError": {
|
|
36
91
|
const parseError = envelope[type];
|
|
37
92
|
this.handleParseError(parseError);
|
|
38
93
|
break;
|
|
39
94
|
}
|
|
40
|
-
case
|
|
95
|
+
case "gherkinDocument": {
|
|
41
96
|
const doc = envelope[type];
|
|
42
97
|
this.onGherkinDocument(doc);
|
|
43
98
|
break;
|
|
44
99
|
}
|
|
45
|
-
case
|
|
100
|
+
case "pickle": {
|
|
46
101
|
const pickle = envelope[type];
|
|
47
102
|
this.onPickle(pickle);
|
|
48
103
|
break;
|
|
49
104
|
}
|
|
50
105
|
// case "stepDefinition": { break}
|
|
51
106
|
// case "hook": { break} // Before Hook
|
|
52
|
-
case
|
|
107
|
+
case "testRunStarted": {
|
|
53
108
|
const testRunStarted = envelope[type];
|
|
54
109
|
this.onTestRunStarted(testRunStarted);
|
|
55
110
|
break;
|
|
56
111
|
}
|
|
57
|
-
case
|
|
112
|
+
case "testCase": {
|
|
58
113
|
const testCase = envelope[type];
|
|
59
114
|
this.onTestCase(testCase);
|
|
60
115
|
break;
|
|
61
116
|
}
|
|
62
|
-
case
|
|
117
|
+
case "testCaseStarted": {
|
|
63
118
|
const testCaseStarted = envelope[type];
|
|
64
119
|
this.onTestCaseStarted(testCaseStarted);
|
|
65
120
|
break;
|
|
66
121
|
}
|
|
67
|
-
case
|
|
122
|
+
case "testStepStarted": {
|
|
68
123
|
const testStepStarted = envelope[type];
|
|
69
124
|
this.onTestStepStarted(testStepStarted);
|
|
70
125
|
break;
|
|
71
126
|
}
|
|
72
|
-
case
|
|
127
|
+
case "attachment": {
|
|
73
128
|
const attachment = envelope[type];
|
|
74
129
|
this.onAttachment(attachment);
|
|
75
130
|
break;
|
|
76
131
|
}
|
|
77
|
-
case
|
|
132
|
+
case "testStepFinished": {
|
|
78
133
|
const testStepFinished = envelope[type];
|
|
79
134
|
this.onTestStepFinished(testStepFinished);
|
|
80
135
|
break;
|
|
81
136
|
}
|
|
82
|
-
case
|
|
137
|
+
case "testCaseFinished": {
|
|
83
138
|
const testCaseFinished = envelope[type];
|
|
84
|
-
this.onTestCaseFinished(testCaseFinished);
|
|
85
|
-
break;
|
|
139
|
+
return await this.onTestCaseFinished(testCaseFinished, reRunId);
|
|
86
140
|
}
|
|
87
141
|
// case "hook": { break} // After Hook
|
|
88
|
-
case
|
|
142
|
+
case "testRunFinished": {
|
|
89
143
|
const testRunFinished = envelope[type];
|
|
90
144
|
this.onTestRunFinished(testRunFinished);
|
|
91
145
|
break;
|
|
@@ -101,7 +155,7 @@ class ReportGenerator {
|
|
|
101
155
|
const { message } = parseError;
|
|
102
156
|
const timestamp = new Date().getTime();
|
|
103
157
|
this.report.result = {
|
|
104
|
-
status:
|
|
158
|
+
status: "FAILED",
|
|
105
159
|
startTime: timestamp,
|
|
106
160
|
endTime: timestamp,
|
|
107
161
|
message: message,
|
|
@@ -144,7 +198,7 @@ class ReportGenerator {
|
|
|
144
198
|
}
|
|
145
199
|
onTestRunStarted(testRunStarted) {
|
|
146
200
|
this.report.result = {
|
|
147
|
-
status:
|
|
201
|
+
status: "STARTED",
|
|
148
202
|
startTime: this.getTimeStamp(testRunStarted.timestamp),
|
|
149
203
|
};
|
|
150
204
|
}
|
|
@@ -177,8 +231,7 @@ class ReportGenerator {
|
|
|
177
231
|
for (const tableRow of examples.tableBody) {
|
|
178
232
|
if (tableRow.id === exampleId) {
|
|
179
233
|
for (let i = 0; i < examples.tableHeader.cells.length; i++) {
|
|
180
|
-
parameters[examples.tableHeader.cells[i].value] =
|
|
181
|
-
tableRow.cells[i].value;
|
|
234
|
+
parameters[examples.tableHeader.cells[i].value] = tableRow.cells[i].value;
|
|
182
235
|
}
|
|
183
236
|
}
|
|
184
237
|
}
|
|
@@ -216,8 +269,12 @@ class ReportGenerator {
|
|
|
216
269
|
text: step.text,
|
|
217
270
|
commands: [],
|
|
218
271
|
result: {
|
|
219
|
-
status:
|
|
272
|
+
status: "UNKNOWN",
|
|
220
273
|
},
|
|
274
|
+
networkData: [],
|
|
275
|
+
webLog: [],
|
|
276
|
+
data: {},
|
|
277
|
+
ariaSnapshot: this.ariaSnapshot,
|
|
221
278
|
});
|
|
222
279
|
return this.stepReportMap.get(pickleStep.id);
|
|
223
280
|
});
|
|
@@ -229,10 +286,15 @@ class ReportGenerator {
|
|
|
229
286
|
parameters,
|
|
230
287
|
steps,
|
|
231
288
|
result: {
|
|
232
|
-
status:
|
|
289
|
+
status: "STARTED",
|
|
233
290
|
startTime: this.getTimeStamp(timestamp),
|
|
234
291
|
},
|
|
235
292
|
webLog: [],
|
|
293
|
+
networkLog: [],
|
|
294
|
+
env: {
|
|
295
|
+
name: this.report.env.name,
|
|
296
|
+
baseUrl: this.report.env.baseUrl,
|
|
297
|
+
},
|
|
236
298
|
});
|
|
237
299
|
this.report.testCases.push(this.testCaseReportMap.get(id));
|
|
238
300
|
}
|
|
@@ -245,38 +307,113 @@ class ReportGenerator {
|
|
|
245
307
|
return;
|
|
246
308
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
247
309
|
stepProgess.result = {
|
|
248
|
-
status:
|
|
310
|
+
status: "STARTED",
|
|
249
311
|
startTime: this.getTimeStamp(timestamp),
|
|
250
312
|
};
|
|
251
313
|
}
|
|
252
314
|
onAttachment(attachment) {
|
|
253
315
|
const { testStepId, body, mediaType } = attachment;
|
|
254
|
-
if (mediaType ===
|
|
255
|
-
this.reportFolder = body.replaceAll(
|
|
316
|
+
if (mediaType === "text/plain") {
|
|
317
|
+
this.reportFolder = body.replaceAll("\\", "/");
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (mediaType === "application/json+snapshot-before") {
|
|
321
|
+
this.initialAriaSnapshot = body;
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (mediaType === "application/json+snapshot-after") {
|
|
325
|
+
this.ariaSnapshot = body;
|
|
256
326
|
return;
|
|
257
327
|
}
|
|
258
|
-
if (mediaType ===
|
|
328
|
+
if (mediaType === "application/json+env") {
|
|
259
329
|
const data = JSON.parse(body);
|
|
260
330
|
this.report.env = data;
|
|
331
|
+
this.report.testCases.map((testCase) => {
|
|
332
|
+
testCase.env = data;
|
|
333
|
+
return testCase;
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
if (mediaType === "application/json+log") {
|
|
337
|
+
const log = JSON.parse(body);
|
|
338
|
+
if (this.logs.length < 1000) {
|
|
339
|
+
this.logs.push(log);
|
|
340
|
+
this.stepLogs.push(log);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (mediaType === "application/json+network") {
|
|
344
|
+
const networkLog = JSON.parse(body);
|
|
345
|
+
if (this.networkLog.length < 1000)
|
|
346
|
+
this.networkLog.push(networkLog);
|
|
347
|
+
this.stepNetworkLogs.push(networkLog);
|
|
261
348
|
}
|
|
262
349
|
const testStep = this.testStepMap.get(testStepId);
|
|
263
350
|
if (testStep.pickleStepId === undefined)
|
|
264
351
|
return;
|
|
265
352
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
266
|
-
if (mediaType ===
|
|
353
|
+
if (mediaType === "application/json") {
|
|
267
354
|
const command = JSON.parse(body);
|
|
268
355
|
stepProgess.commands.push(command);
|
|
269
356
|
}
|
|
357
|
+
else if (mediaType === "application/json+trace") {
|
|
358
|
+
const data = JSON.parse(body);
|
|
359
|
+
stepProgess.traceFilePath = data.traceFilePath;
|
|
360
|
+
}
|
|
361
|
+
if (mediaType === "application/json+bruno") {
|
|
362
|
+
try {
|
|
363
|
+
const data = JSON.parse(body);
|
|
364
|
+
stepProgess.brunoData = data;
|
|
365
|
+
}
|
|
366
|
+
catch (error) {
|
|
367
|
+
console.error("Error parsing bruno data:", error);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
getFailedTestStepResult({ commands, startTime, endTime, result, }) {
|
|
372
|
+
for (const command of commands) {
|
|
373
|
+
if (command.result.status === "FAILED") {
|
|
374
|
+
return {
|
|
375
|
+
status: "FAILED",
|
|
376
|
+
message: command.result.message,
|
|
377
|
+
startTime,
|
|
378
|
+
endTime,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
status: "FAILED",
|
|
384
|
+
startTime,
|
|
385
|
+
endTime,
|
|
386
|
+
message: result.message,
|
|
387
|
+
};
|
|
270
388
|
}
|
|
271
389
|
onTestStepFinished(testStepFinished) {
|
|
272
390
|
const { testStepId, testStepResult, timestamp } = testStepFinished;
|
|
273
391
|
const testStep = this.testStepMap.get(testStepId);
|
|
274
392
|
if (testStep.pickleStepId === undefined) {
|
|
275
|
-
if (testStepResult.status ===
|
|
393
|
+
if (testStepResult.status === "FAILED") {
|
|
276
394
|
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
277
395
|
}
|
|
278
396
|
return;
|
|
279
397
|
}
|
|
398
|
+
if (testStepResult.status === "UNDEFINED") {
|
|
399
|
+
const step = this.stepReportMap.get(testStep.pickleStepId);
|
|
400
|
+
const stepName = step ? step.keyword + " " + step.text : "Undefined step";
|
|
401
|
+
const undefinedCommand = {
|
|
402
|
+
testStepId: testStepId,
|
|
403
|
+
body: JSON.stringify({
|
|
404
|
+
type: "error",
|
|
405
|
+
text: "Undefined step: " + stepName,
|
|
406
|
+
result: {
|
|
407
|
+
status: "FAILED",
|
|
408
|
+
startTime: this.getTimeStamp(timestamp),
|
|
409
|
+
endTime: this.getTimeStamp(timestamp),
|
|
410
|
+
},
|
|
411
|
+
}),
|
|
412
|
+
mediaType: "application/json",
|
|
413
|
+
contentEncoding: messages.AttachmentContentEncoding.IDENTITY,
|
|
414
|
+
};
|
|
415
|
+
this.onAttachment(undefinedCommand);
|
|
416
|
+
}
|
|
280
417
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
281
418
|
const prevStepResult = stepProgess.result;
|
|
282
419
|
let data = {};
|
|
@@ -285,30 +422,85 @@ class ReportGenerator {
|
|
|
285
422
|
if (reportFolder === null) {
|
|
286
423
|
throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
|
|
287
424
|
}
|
|
288
|
-
if (fs_1.default.existsSync(path_1.default.join(reportFolder,
|
|
289
|
-
data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder,
|
|
425
|
+
if (fs_1.default.existsSync(path_1.default.join(reportFolder, "data.json"))) {
|
|
426
|
+
data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder, "data.json"), "utf8"));
|
|
290
427
|
}
|
|
291
428
|
}
|
|
292
429
|
catch (error) {
|
|
293
|
-
console.log(
|
|
430
|
+
console.log("Error reading data.json");
|
|
294
431
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
432
|
+
if (testStepResult.status === "FAILED") {
|
|
433
|
+
stepProgess.result = this.getFailedTestStepResult({
|
|
434
|
+
commands: stepProgess.commands,
|
|
435
|
+
startTime: prevStepResult.startTime,
|
|
436
|
+
endTime: this.getTimeStamp(timestamp),
|
|
437
|
+
result: testStepResult,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
stepProgess.result = {
|
|
442
|
+
status: testStepResult.status,
|
|
443
|
+
startTime: prevStepResult.startTime,
|
|
444
|
+
endTime: this.getTimeStamp(timestamp),
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
stepProgess.webLog = this.stepLogs;
|
|
448
|
+
stepProgess.networkData = this.stepNetworkLogs;
|
|
449
|
+
stepProgess.ariaSnapshot = this.ariaSnapshot;
|
|
450
|
+
this.ariaSnapshot = "";
|
|
451
|
+
this.stepNetworkLogs = [];
|
|
452
|
+
this.stepLogs = [];
|
|
302
453
|
if (Object.keys(data).length > 0) {
|
|
303
454
|
stepProgess.data = data;
|
|
455
|
+
const id = testStepFinished.testCaseStartedId;
|
|
456
|
+
const parameters = this.testCaseReportMap.get(id).parameters;
|
|
457
|
+
const _parameters = {};
|
|
458
|
+
Object.keys(parameters).map((key) => {
|
|
459
|
+
if (parameters[key].startsWith("{{") && parameters[key].endsWith("}}")) {
|
|
460
|
+
const path = parameters[key].slice(2, -2).split(".");
|
|
461
|
+
let value = String(object_path_1.default.get(data, path));
|
|
462
|
+
if (value) {
|
|
463
|
+
if (value.startsWith("secret:")) {
|
|
464
|
+
value = "secret:****";
|
|
465
|
+
}
|
|
466
|
+
else if (value.startsWith("totp:")) {
|
|
467
|
+
value = "totp:****";
|
|
468
|
+
}
|
|
469
|
+
else if (value.startsWith("mask:")) {
|
|
470
|
+
value = "mask:****";
|
|
471
|
+
}
|
|
472
|
+
_parameters[key] = value;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
_parameters[key] = parameters[key];
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
this.report.testCases.find((testCase) => {
|
|
480
|
+
return testCase.id === id;
|
|
481
|
+
}).parameters = _parameters;
|
|
304
482
|
}
|
|
483
|
+
// if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
484
|
+
// this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH
|
|
485
|
+
// if (!fs.existsSync(this.reportFolder)) {
|
|
486
|
+
// fs.mkdirSync(this.reportFolder)
|
|
487
|
+
// }
|
|
488
|
+
// const reportFilePath = path.join(
|
|
489
|
+
// this.reportFolder,
|
|
490
|
+
// `report.json`
|
|
491
|
+
// )
|
|
492
|
+
// writeFileSync(reportFilePath, JSON.stringify(this.report, null, 2))
|
|
493
|
+
// return undefined
|
|
494
|
+
// // } else {
|
|
495
|
+
// // return await this.uploadTestCase(testProgress, reRunId)
|
|
496
|
+
// }
|
|
305
497
|
}
|
|
306
498
|
getLogFileContent() {
|
|
307
499
|
let projectPath = process.cwd();
|
|
308
500
|
if (process.env.PROJECT_PATH) {
|
|
309
501
|
projectPath = process.env.PROJECT_PATH;
|
|
310
502
|
}
|
|
311
|
-
const logFolder = path_1.default.join(projectPath,
|
|
503
|
+
const logFolder = path_1.default.join(projectPath, "logs", "web");
|
|
312
504
|
if (!fs_1.default.existsSync(logFolder)) {
|
|
313
505
|
return [];
|
|
314
506
|
}
|
|
@@ -320,7 +512,7 @@ class ReportGenerator {
|
|
|
320
512
|
return [];
|
|
321
513
|
}
|
|
322
514
|
try {
|
|
323
|
-
const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`),
|
|
515
|
+
const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`), "utf8");
|
|
324
516
|
return JSON.parse(logFileContent);
|
|
325
517
|
}
|
|
326
518
|
catch (error) {
|
|
@@ -330,43 +522,122 @@ class ReportGenerator {
|
|
|
330
522
|
getTestCaseResult(steps) {
|
|
331
523
|
for (const step of steps) {
|
|
332
524
|
switch (step.result.status) {
|
|
333
|
-
case
|
|
525
|
+
case "FAILED":
|
|
334
526
|
return {
|
|
335
527
|
status: step.result.status,
|
|
336
528
|
message: step.result.message,
|
|
337
529
|
// exception: step.result.exception,
|
|
338
530
|
};
|
|
339
|
-
case
|
|
340
|
-
case
|
|
341
|
-
case
|
|
531
|
+
case "AMBIGUOUS":
|
|
532
|
+
case "UNDEFINED":
|
|
533
|
+
case "PENDING":
|
|
342
534
|
return {
|
|
343
|
-
status:
|
|
535
|
+
status: "FAILED",
|
|
344
536
|
message: `step "${step.text}" is ${step.result.status}`,
|
|
345
537
|
};
|
|
346
538
|
}
|
|
347
539
|
}
|
|
348
540
|
return {
|
|
349
|
-
status:
|
|
541
|
+
status: "PASSED",
|
|
350
542
|
};
|
|
351
543
|
}
|
|
352
|
-
onTestCaseFinished(testCaseFinished) {
|
|
544
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
353
545
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
354
546
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
355
547
|
const prevResult = testProgress.result;
|
|
356
548
|
const steps = Object.values(testProgress.steps);
|
|
357
549
|
const result = this.getTestCaseResult(steps);
|
|
550
|
+
const endTime = this.getTimeStamp(timestamp);
|
|
358
551
|
testProgress.result = {
|
|
359
552
|
...result,
|
|
360
553
|
startTime: prevResult.startTime,
|
|
361
|
-
endTime
|
|
554
|
+
endTime,
|
|
362
555
|
};
|
|
363
|
-
testProgress.webLog = this.
|
|
556
|
+
testProgress.webLog = this.logs;
|
|
557
|
+
testProgress.networkLog = this.networkLog;
|
|
558
|
+
testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
|
|
559
|
+
this.initialAriaSnapshot = "";
|
|
560
|
+
this.networkLog = [];
|
|
561
|
+
this.logs = [];
|
|
562
|
+
if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
563
|
+
this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
564
|
+
if (!fs_1.default.existsSync(this.reportFolder)) {
|
|
565
|
+
fs_1.default.mkdirSync(this.reportFolder);
|
|
566
|
+
}
|
|
567
|
+
const reportFilePath = path_1.default.join(this.reportFolder, `${endTime}_${testProgress.scenarioName}.json`);
|
|
568
|
+
(0, fs_extra_1.writeFileSync)(reportFilePath, JSON.stringify(testProgress, null, 2));
|
|
569
|
+
return undefined;
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
return await this.uploadTestCase(testProgress, reRunId);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
async uploadTestCase(testCase, rerunId) {
|
|
576
|
+
let runId = "";
|
|
577
|
+
let projectId = "";
|
|
578
|
+
if (!process.env.UPLOADING_TEST_CASE) {
|
|
579
|
+
process.env.UPLOADING_TEST_CASE = "[]";
|
|
580
|
+
}
|
|
581
|
+
const anyRemArr = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
582
|
+
const randomID = Math.random().toString(36).substring(7);
|
|
583
|
+
anyRemArr.push(randomID);
|
|
584
|
+
let data;
|
|
585
|
+
process.env.UPLOADING_TEST_CASE = JSON.stringify(anyRemArr);
|
|
586
|
+
try {
|
|
587
|
+
if (process.env.RUN_ID && process.env.PROJECT_ID && !process.env.IGNORE_ENV_VARIABLES) {
|
|
588
|
+
runId = process.env.RUN_ID;
|
|
589
|
+
projectId = process.env.PROJECT_ID;
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
const runDoc = await this.uploadService.createRunDocument(this.runName);
|
|
593
|
+
runId = runDoc._id;
|
|
594
|
+
projectId = runDoc.project_id;
|
|
595
|
+
if (!process.env.IGNORE_ENV_VARIABLES) {
|
|
596
|
+
process.env.RUN_ID = runId;
|
|
597
|
+
process.env.PROJECT_ID = projectId;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
|
|
601
|
+
this.writeTestCaseReportToDisk(testCase);
|
|
602
|
+
}
|
|
603
|
+
catch (e) {
|
|
604
|
+
console.error("Error uploading test case:", e);
|
|
605
|
+
}
|
|
606
|
+
finally {
|
|
607
|
+
const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
608
|
+
arrRem.splice(arrRem.indexOf(randomID), 1);
|
|
609
|
+
process.env.UPLOADING_TEST_CASE = JSON.stringify(arrRem);
|
|
610
|
+
}
|
|
611
|
+
return data ? data : null;
|
|
612
|
+
}
|
|
613
|
+
writeTestCaseReportToDisk(testCase) {
|
|
614
|
+
var _a;
|
|
615
|
+
const reportFolder = (_a = this.reportFolder) !== null && _a !== void 0 ? _a : process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
616
|
+
if (!reportFolder) {
|
|
617
|
+
console.error("Report folder is not defined");
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
try {
|
|
621
|
+
let i = 0;
|
|
622
|
+
while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
|
|
623
|
+
i++;
|
|
624
|
+
}
|
|
625
|
+
fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
|
|
626
|
+
//exclude network log from the saved report
|
|
627
|
+
const networkLog = testCase.networkLog;
|
|
628
|
+
delete testCase.networkLog;
|
|
629
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
|
|
630
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
console.error("Error writing test case report to disk:", error);
|
|
634
|
+
}
|
|
364
635
|
}
|
|
365
636
|
onTestRunFinished(testRunFinished) {
|
|
366
637
|
const { timestamp, success, message } = testRunFinished;
|
|
367
638
|
const prevResult = this.report.result;
|
|
368
639
|
this.report.result = {
|
|
369
|
-
status: success ?
|
|
640
|
+
status: success ? "PASSED" : "FAILED",
|
|
370
641
|
startTime: prevResult.startTime,
|
|
371
642
|
endTime: this.getTimeStamp(timestamp),
|
|
372
643
|
message,
|