@dev-blinq/cucumber-js 1.0.80-main → 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 +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 +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.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 +37 -13
- package/lib/formatter/helpers/report_generator.js +317 -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 +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 +63 -18
- 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 +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,75 @@ 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 = "";
|
|
30
79
|
this.reportFolder = null;
|
|
80
|
+
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
31
81
|
}
|
|
32
|
-
handleMessage(envelope) {
|
|
82
|
+
async handleMessage(envelope, reRunId) {
|
|
83
|
+
if (envelope.meta && "runName" in envelope.meta) {
|
|
84
|
+
this.runName = envelope.meta.runName;
|
|
85
|
+
}
|
|
33
86
|
const type = Object.keys(envelope)[0];
|
|
34
87
|
switch (type) {
|
|
35
88
|
// case "meta": { break}
|
|
36
89
|
// case "source": { break}
|
|
37
|
-
case
|
|
90
|
+
case "parseError": {
|
|
38
91
|
const parseError = envelope[type];
|
|
39
92
|
this.handleParseError(parseError);
|
|
40
93
|
break;
|
|
41
94
|
}
|
|
42
|
-
case
|
|
95
|
+
case "gherkinDocument": {
|
|
43
96
|
const doc = envelope[type];
|
|
44
97
|
this.onGherkinDocument(doc);
|
|
45
98
|
break;
|
|
46
99
|
}
|
|
47
|
-
case
|
|
100
|
+
case "pickle": {
|
|
48
101
|
const pickle = envelope[type];
|
|
49
102
|
this.onPickle(pickle);
|
|
50
103
|
break;
|
|
51
104
|
}
|
|
52
105
|
// case "stepDefinition": { break}
|
|
53
106
|
// case "hook": { break} // Before Hook
|
|
54
|
-
case
|
|
107
|
+
case "testRunStarted": {
|
|
55
108
|
const testRunStarted = envelope[type];
|
|
56
109
|
this.onTestRunStarted(testRunStarted);
|
|
57
110
|
break;
|
|
58
111
|
}
|
|
59
|
-
case
|
|
112
|
+
case "testCase": {
|
|
60
113
|
const testCase = envelope[type];
|
|
61
114
|
this.onTestCase(testCase);
|
|
62
115
|
break;
|
|
63
116
|
}
|
|
64
|
-
case
|
|
117
|
+
case "testCaseStarted": {
|
|
65
118
|
const testCaseStarted = envelope[type];
|
|
66
119
|
this.onTestCaseStarted(testCaseStarted);
|
|
67
120
|
break;
|
|
68
121
|
}
|
|
69
|
-
case
|
|
122
|
+
case "testStepStarted": {
|
|
70
123
|
const testStepStarted = envelope[type];
|
|
71
124
|
this.onTestStepStarted(testStepStarted);
|
|
72
125
|
break;
|
|
73
126
|
}
|
|
74
|
-
case
|
|
127
|
+
case "attachment": {
|
|
75
128
|
const attachment = envelope[type];
|
|
76
129
|
this.onAttachment(attachment);
|
|
77
130
|
break;
|
|
78
131
|
}
|
|
79
|
-
case
|
|
132
|
+
case "testStepFinished": {
|
|
80
133
|
const testStepFinished = envelope[type];
|
|
81
134
|
this.onTestStepFinished(testStepFinished);
|
|
82
135
|
break;
|
|
83
136
|
}
|
|
84
|
-
case
|
|
137
|
+
case "testCaseFinished": {
|
|
85
138
|
const testCaseFinished = envelope[type];
|
|
86
|
-
this.onTestCaseFinished(testCaseFinished);
|
|
87
|
-
break;
|
|
139
|
+
return await this.onTestCaseFinished(testCaseFinished, reRunId);
|
|
88
140
|
}
|
|
89
141
|
// case "hook": { break} // After Hook
|
|
90
|
-
case
|
|
142
|
+
case "testRunFinished": {
|
|
91
143
|
const testRunFinished = envelope[type];
|
|
92
144
|
this.onTestRunFinished(testRunFinished);
|
|
93
145
|
break;
|
|
@@ -103,7 +155,7 @@ class ReportGenerator {
|
|
|
103
155
|
const { message } = parseError;
|
|
104
156
|
const timestamp = new Date().getTime();
|
|
105
157
|
this.report.result = {
|
|
106
|
-
status:
|
|
158
|
+
status: "FAILED",
|
|
107
159
|
startTime: timestamp,
|
|
108
160
|
endTime: timestamp,
|
|
109
161
|
message: message,
|
|
@@ -146,7 +198,7 @@ class ReportGenerator {
|
|
|
146
198
|
}
|
|
147
199
|
onTestRunStarted(testRunStarted) {
|
|
148
200
|
this.report.result = {
|
|
149
|
-
status:
|
|
201
|
+
status: "STARTED",
|
|
150
202
|
startTime: this.getTimeStamp(testRunStarted.timestamp),
|
|
151
203
|
};
|
|
152
204
|
}
|
|
@@ -179,8 +231,7 @@ class ReportGenerator {
|
|
|
179
231
|
for (const tableRow of examples.tableBody) {
|
|
180
232
|
if (tableRow.id === exampleId) {
|
|
181
233
|
for (let i = 0; i < examples.tableHeader.cells.length; i++) {
|
|
182
|
-
parameters[examples.tableHeader.cells[i].value] =
|
|
183
|
-
tableRow.cells[i].value;
|
|
234
|
+
parameters[examples.tableHeader.cells[i].value] = tableRow.cells[i].value;
|
|
184
235
|
}
|
|
185
236
|
}
|
|
186
237
|
}
|
|
@@ -218,8 +269,12 @@ class ReportGenerator {
|
|
|
218
269
|
text: step.text,
|
|
219
270
|
commands: [],
|
|
220
271
|
result: {
|
|
221
|
-
status:
|
|
272
|
+
status: "UNKNOWN",
|
|
222
273
|
},
|
|
274
|
+
networkData: [],
|
|
275
|
+
webLog: [],
|
|
276
|
+
data: {},
|
|
277
|
+
ariaSnapshot: this.ariaSnapshot,
|
|
223
278
|
});
|
|
224
279
|
return this.stepReportMap.get(pickleStep.id);
|
|
225
280
|
});
|
|
@@ -231,11 +286,15 @@ class ReportGenerator {
|
|
|
231
286
|
parameters,
|
|
232
287
|
steps,
|
|
233
288
|
result: {
|
|
234
|
-
status:
|
|
289
|
+
status: "STARTED",
|
|
235
290
|
startTime: this.getTimeStamp(timestamp),
|
|
236
291
|
},
|
|
237
292
|
webLog: [],
|
|
238
293
|
networkLog: [],
|
|
294
|
+
env: {
|
|
295
|
+
name: this.report.env.name,
|
|
296
|
+
baseUrl: this.report.env.baseUrl,
|
|
297
|
+
},
|
|
239
298
|
});
|
|
240
299
|
this.report.testCases.push(this.testCaseReportMap.get(id));
|
|
241
300
|
}
|
|
@@ -248,78 +307,200 @@ class ReportGenerator {
|
|
|
248
307
|
return;
|
|
249
308
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
250
309
|
stepProgess.result = {
|
|
251
|
-
status:
|
|
310
|
+
status: "STARTED",
|
|
252
311
|
startTime: this.getTimeStamp(timestamp),
|
|
253
312
|
};
|
|
254
313
|
}
|
|
255
314
|
onAttachment(attachment) {
|
|
256
315
|
const { testStepId, body, mediaType } = attachment;
|
|
257
|
-
if (mediaType ===
|
|
258
|
-
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;
|
|
259
322
|
return;
|
|
260
323
|
}
|
|
261
|
-
if (mediaType ===
|
|
324
|
+
if (mediaType === "application/json+snapshot-after") {
|
|
325
|
+
this.ariaSnapshot = body;
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (mediaType === "application/json+env") {
|
|
262
329
|
const data = JSON.parse(body);
|
|
263
330
|
this.report.env = data;
|
|
331
|
+
this.report.testCases.map((testCase) => {
|
|
332
|
+
testCase.env = data;
|
|
333
|
+
return testCase;
|
|
334
|
+
});
|
|
264
335
|
}
|
|
265
|
-
if (mediaType ===
|
|
336
|
+
if (mediaType === "application/json+log") {
|
|
266
337
|
const log = JSON.parse(body);
|
|
267
|
-
this.logs.
|
|
338
|
+
if (this.logs.length < 1000) {
|
|
339
|
+
this.logs.push(log);
|
|
340
|
+
this.stepLogs.push(log);
|
|
341
|
+
}
|
|
268
342
|
}
|
|
269
|
-
if (mediaType ===
|
|
343
|
+
if (mediaType === "application/json+network") {
|
|
270
344
|
const networkLog = JSON.parse(body);
|
|
271
|
-
this.networkLog.
|
|
345
|
+
if (this.networkLog.length < 1000)
|
|
346
|
+
this.networkLog.push(networkLog);
|
|
347
|
+
this.stepNetworkLogs.push(networkLog);
|
|
272
348
|
}
|
|
273
349
|
const testStep = this.testStepMap.get(testStepId);
|
|
274
350
|
if (testStep.pickleStepId === undefined)
|
|
275
351
|
return;
|
|
276
352
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
277
|
-
if (mediaType ===
|
|
353
|
+
if (mediaType === "application/json") {
|
|
278
354
|
const command = JSON.parse(body);
|
|
279
355
|
stepProgess.commands.push(command);
|
|
280
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
|
+
};
|
|
281
388
|
}
|
|
282
389
|
onTestStepFinished(testStepFinished) {
|
|
283
390
|
const { testStepId, testStepResult, timestamp } = testStepFinished;
|
|
284
391
|
const testStep = this.testStepMap.get(testStepId);
|
|
285
392
|
if (testStep.pickleStepId === undefined) {
|
|
286
|
-
if (testStepResult.status ===
|
|
393
|
+
if (testStepResult.status === "FAILED") {
|
|
287
394
|
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
288
395
|
}
|
|
289
396
|
return;
|
|
290
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
|
+
}
|
|
291
417
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
292
418
|
const prevStepResult = stepProgess.result;
|
|
293
419
|
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
420
|
try {
|
|
299
|
-
|
|
300
|
-
|
|
421
|
+
const reportFolder = this.reportFolder;
|
|
422
|
+
if (reportFolder === null) {
|
|
423
|
+
throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
|
|
424
|
+
}
|
|
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"));
|
|
301
427
|
}
|
|
302
428
|
}
|
|
303
429
|
catch (error) {
|
|
304
|
-
console.log(
|
|
430
|
+
console.log("Error reading data.json");
|
|
305
431
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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 = [];
|
|
313
453
|
if (Object.keys(data).length > 0) {
|
|
314
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;
|
|
315
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
|
+
// }
|
|
316
497
|
}
|
|
317
498
|
getLogFileContent() {
|
|
318
499
|
let projectPath = process.cwd();
|
|
319
500
|
if (process.env.PROJECT_PATH) {
|
|
320
501
|
projectPath = process.env.PROJECT_PATH;
|
|
321
502
|
}
|
|
322
|
-
const logFolder = path_1.default.join(projectPath,
|
|
503
|
+
const logFolder = path_1.default.join(projectPath, "logs", "web");
|
|
323
504
|
if (!fs_1.default.existsSync(logFolder)) {
|
|
324
505
|
return [];
|
|
325
506
|
}
|
|
@@ -331,7 +512,7 @@ class ReportGenerator {
|
|
|
331
512
|
return [];
|
|
332
513
|
}
|
|
333
514
|
try {
|
|
334
|
-
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");
|
|
335
516
|
return JSON.parse(logFileContent);
|
|
336
517
|
}
|
|
337
518
|
catch (error) {
|
|
@@ -341,44 +522,122 @@ class ReportGenerator {
|
|
|
341
522
|
getTestCaseResult(steps) {
|
|
342
523
|
for (const step of steps) {
|
|
343
524
|
switch (step.result.status) {
|
|
344
|
-
case
|
|
525
|
+
case "FAILED":
|
|
345
526
|
return {
|
|
346
527
|
status: step.result.status,
|
|
347
528
|
message: step.result.message,
|
|
348
529
|
// exception: step.result.exception,
|
|
349
530
|
};
|
|
350
|
-
case
|
|
351
|
-
case
|
|
352
|
-
case
|
|
531
|
+
case "AMBIGUOUS":
|
|
532
|
+
case "UNDEFINED":
|
|
533
|
+
case "PENDING":
|
|
353
534
|
return {
|
|
354
|
-
status:
|
|
535
|
+
status: "FAILED",
|
|
355
536
|
message: `step "${step.text}" is ${step.result.status}`,
|
|
356
537
|
};
|
|
357
538
|
}
|
|
358
539
|
}
|
|
359
540
|
return {
|
|
360
|
-
status:
|
|
541
|
+
status: "PASSED",
|
|
361
542
|
};
|
|
362
543
|
}
|
|
363
|
-
onTestCaseFinished(testCaseFinished) {
|
|
544
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
364
545
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
365
546
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
366
547
|
const prevResult = testProgress.result;
|
|
367
548
|
const steps = Object.values(testProgress.steps);
|
|
368
549
|
const result = this.getTestCaseResult(steps);
|
|
550
|
+
const endTime = this.getTimeStamp(timestamp);
|
|
369
551
|
testProgress.result = {
|
|
370
552
|
...result,
|
|
371
553
|
startTime: prevResult.startTime,
|
|
372
|
-
endTime
|
|
554
|
+
endTime,
|
|
373
555
|
};
|
|
374
556
|
testProgress.webLog = this.logs;
|
|
375
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
|
+
}
|
|
376
635
|
}
|
|
377
636
|
onTestRunFinished(testRunFinished) {
|
|
378
637
|
const { timestamp, success, message } = testRunFinished;
|
|
379
638
|
const prevResult = this.report.result;
|
|
380
639
|
this.report.result = {
|
|
381
|
-
status: success ?
|
|
640
|
+
status: success ? "PASSED" : "FAILED",
|
|
382
641
|
startTime: prevResult.startTime,
|
|
383
642
|
endTime: this.getTimeStamp(timestamp),
|
|
384
643
|
message,
|