@dev-blinq/cucumber-js 1.0.76-dev → 1.0.76-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 +13 -1
- package/lib/formatter/bvt_analysis_formatter.js +221 -76
- 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 +52 -7
- 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 +46 -12
- package/lib/formatter/helpers/report_generator.js +323 -53
- 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 -2
- package/lib/formatter/helpers/upload_serivce.js +150 -16
- 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/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,62 +307,191 @@ 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;
|
|
256
322
|
return;
|
|
257
323
|
}
|
|
258
|
-
if (mediaType ===
|
|
324
|
+
if (mediaType === "application/json+snapshot-after") {
|
|
325
|
+
this.ariaSnapshot = body;
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
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
|
+
}
|
|
362
|
+
getFailedTestStepResult({ commands, startTime, endTime, result, }) {
|
|
363
|
+
for (const command of commands) {
|
|
364
|
+
if (command.result.status === "FAILED") {
|
|
365
|
+
return {
|
|
366
|
+
status: "FAILED",
|
|
367
|
+
message: command.result.message,
|
|
368
|
+
startTime,
|
|
369
|
+
endTime,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
status: "FAILED",
|
|
375
|
+
startTime,
|
|
376
|
+
endTime,
|
|
377
|
+
message: result.message,
|
|
378
|
+
};
|
|
270
379
|
}
|
|
271
380
|
onTestStepFinished(testStepFinished) {
|
|
272
381
|
const { testStepId, testStepResult, timestamp } = testStepFinished;
|
|
273
382
|
const testStep = this.testStepMap.get(testStepId);
|
|
274
|
-
if (testStep.pickleStepId === undefined)
|
|
383
|
+
if (testStep.pickleStepId === undefined) {
|
|
384
|
+
if (testStepResult.status === "FAILED") {
|
|
385
|
+
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
386
|
+
}
|
|
275
387
|
return;
|
|
388
|
+
}
|
|
389
|
+
if (testStepResult.status === "UNDEFINED") {
|
|
390
|
+
const step = this.stepReportMap.get(testStep.pickleStepId);
|
|
391
|
+
const stepName = step ? step.keyword + " " + step.text : "Undefined step";
|
|
392
|
+
const undefinedCommand = {
|
|
393
|
+
testStepId: testStepId,
|
|
394
|
+
body: JSON.stringify({
|
|
395
|
+
type: "error",
|
|
396
|
+
text: "Undefined step: " + stepName,
|
|
397
|
+
result: {
|
|
398
|
+
status: "FAILED",
|
|
399
|
+
startTime: this.getTimeStamp(timestamp),
|
|
400
|
+
endTime: this.getTimeStamp(timestamp),
|
|
401
|
+
},
|
|
402
|
+
}),
|
|
403
|
+
mediaType: "application/json",
|
|
404
|
+
contentEncoding: messages.AttachmentContentEncoding.IDENTITY,
|
|
405
|
+
};
|
|
406
|
+
this.onAttachment(undefinedCommand);
|
|
407
|
+
}
|
|
276
408
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
277
409
|
const prevStepResult = stepProgess.result;
|
|
278
410
|
let data = {};
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
411
|
+
try {
|
|
412
|
+
const reportFolder = this.reportFolder;
|
|
413
|
+
if (reportFolder === null) {
|
|
414
|
+
throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
|
|
282
415
|
}
|
|
283
|
-
|
|
284
|
-
|
|
416
|
+
if (fs_1.default.existsSync(path_1.default.join(reportFolder, "data.json"))) {
|
|
417
|
+
data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(reportFolder, "data.json"), "utf8"));
|
|
285
418
|
}
|
|
286
419
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
420
|
+
catch (error) {
|
|
421
|
+
console.log("Error reading data.json");
|
|
422
|
+
}
|
|
423
|
+
if (testStepResult.status === "FAILED") {
|
|
424
|
+
stepProgess.result = this.getFailedTestStepResult({
|
|
425
|
+
commands: stepProgess.commands,
|
|
426
|
+
startTime: prevStepResult.startTime,
|
|
427
|
+
endTime: this.getTimeStamp(timestamp),
|
|
428
|
+
result: testStepResult,
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
stepProgess.result = {
|
|
433
|
+
status: testStepResult.status,
|
|
434
|
+
startTime: prevStepResult.startTime,
|
|
435
|
+
endTime: this.getTimeStamp(timestamp),
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
stepProgess.webLog = this.stepLogs;
|
|
439
|
+
stepProgess.networkData = this.stepNetworkLogs;
|
|
440
|
+
stepProgess.ariaSnapshot = this.ariaSnapshot;
|
|
441
|
+
this.ariaSnapshot = "";
|
|
442
|
+
this.stepNetworkLogs = [];
|
|
443
|
+
this.stepLogs = [];
|
|
294
444
|
if (Object.keys(data).length > 0) {
|
|
295
445
|
stepProgess.data = data;
|
|
446
|
+
const id = testStepFinished.testCaseStartedId;
|
|
447
|
+
const parameters = this.testCaseReportMap.get(id).parameters;
|
|
448
|
+
const _parameters = {};
|
|
449
|
+
Object.keys(parameters).map((key) => {
|
|
450
|
+
if (parameters[key].startsWith("{{") && parameters[key].endsWith("}}")) {
|
|
451
|
+
const path = parameters[key].slice(2, -2).split(".");
|
|
452
|
+
let value = String(object_path_1.default.get(data, path));
|
|
453
|
+
if (value) {
|
|
454
|
+
if (value.startsWith("secret:")) {
|
|
455
|
+
value = "secret:****";
|
|
456
|
+
}
|
|
457
|
+
else if (value.startsWith("totp:")) {
|
|
458
|
+
value = "totp:****";
|
|
459
|
+
}
|
|
460
|
+
else if (value.startsWith("mask:")) {
|
|
461
|
+
value = "mask:****";
|
|
462
|
+
}
|
|
463
|
+
_parameters[key] = value;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
_parameters[key] = parameters[key];
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
this.report.testCases.find((testCase) => {
|
|
471
|
+
return testCase.id === id;
|
|
472
|
+
}).parameters = _parameters;
|
|
296
473
|
}
|
|
474
|
+
// if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
475
|
+
// this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH
|
|
476
|
+
// if (!fs.existsSync(this.reportFolder)) {
|
|
477
|
+
// fs.mkdirSync(this.reportFolder)
|
|
478
|
+
// }
|
|
479
|
+
// const reportFilePath = path.join(
|
|
480
|
+
// this.reportFolder,
|
|
481
|
+
// `report.json`
|
|
482
|
+
// )
|
|
483
|
+
// writeFileSync(reportFilePath, JSON.stringify(this.report, null, 2))
|
|
484
|
+
// return undefined
|
|
485
|
+
// // } else {
|
|
486
|
+
// // return await this.uploadTestCase(testProgress, reRunId)
|
|
487
|
+
// }
|
|
297
488
|
}
|
|
298
489
|
getLogFileContent() {
|
|
299
490
|
let projectPath = process.cwd();
|
|
300
491
|
if (process.env.PROJECT_PATH) {
|
|
301
492
|
projectPath = process.env.PROJECT_PATH;
|
|
302
493
|
}
|
|
303
|
-
const logFolder = path_1.default.join(projectPath,
|
|
494
|
+
const logFolder = path_1.default.join(projectPath, "logs", "web");
|
|
304
495
|
if (!fs_1.default.existsSync(logFolder)) {
|
|
305
496
|
return [];
|
|
306
497
|
}
|
|
@@ -312,7 +503,7 @@ class ReportGenerator {
|
|
|
312
503
|
return [];
|
|
313
504
|
}
|
|
314
505
|
try {
|
|
315
|
-
const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`),
|
|
506
|
+
const logFileContent = fs_1.default.readFileSync(path_1.default.join(logFolder, `${nextId - 1}.json`), "utf8");
|
|
316
507
|
return JSON.parse(logFileContent);
|
|
317
508
|
}
|
|
318
509
|
catch (error) {
|
|
@@ -322,43 +513,122 @@ class ReportGenerator {
|
|
|
322
513
|
getTestCaseResult(steps) {
|
|
323
514
|
for (const step of steps) {
|
|
324
515
|
switch (step.result.status) {
|
|
325
|
-
case
|
|
516
|
+
case "FAILED":
|
|
326
517
|
return {
|
|
327
518
|
status: step.result.status,
|
|
328
519
|
message: step.result.message,
|
|
329
520
|
// exception: step.result.exception,
|
|
330
521
|
};
|
|
331
|
-
case
|
|
332
|
-
case
|
|
333
|
-
case
|
|
522
|
+
case "AMBIGUOUS":
|
|
523
|
+
case "UNDEFINED":
|
|
524
|
+
case "PENDING":
|
|
334
525
|
return {
|
|
335
|
-
status:
|
|
526
|
+
status: "FAILED",
|
|
336
527
|
message: `step "${step.text}" is ${step.result.status}`,
|
|
337
528
|
};
|
|
338
529
|
}
|
|
339
530
|
}
|
|
340
531
|
return {
|
|
341
|
-
status:
|
|
532
|
+
status: "PASSED",
|
|
342
533
|
};
|
|
343
534
|
}
|
|
344
|
-
onTestCaseFinished(testCaseFinished) {
|
|
535
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
345
536
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
346
537
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
347
538
|
const prevResult = testProgress.result;
|
|
348
539
|
const steps = Object.values(testProgress.steps);
|
|
349
540
|
const result = this.getTestCaseResult(steps);
|
|
541
|
+
const endTime = this.getTimeStamp(timestamp);
|
|
350
542
|
testProgress.result = {
|
|
351
543
|
...result,
|
|
352
544
|
startTime: prevResult.startTime,
|
|
353
|
-
endTime
|
|
545
|
+
endTime,
|
|
354
546
|
};
|
|
355
|
-
testProgress.webLog = this.
|
|
547
|
+
testProgress.webLog = this.logs;
|
|
548
|
+
testProgress.networkLog = this.networkLog;
|
|
549
|
+
testProgress.initialAriaSnapshot = this.initialAriaSnapshot;
|
|
550
|
+
this.initialAriaSnapshot = "";
|
|
551
|
+
this.networkLog = [];
|
|
552
|
+
this.logs = [];
|
|
553
|
+
if (process.env.TESTCASE_REPORT_FOLDER_PATH) {
|
|
554
|
+
this.reportFolder = process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
555
|
+
if (!fs_1.default.existsSync(this.reportFolder)) {
|
|
556
|
+
fs_1.default.mkdirSync(this.reportFolder);
|
|
557
|
+
}
|
|
558
|
+
const reportFilePath = path_1.default.join(this.reportFolder, `${endTime}_${testProgress.scenarioName}.json`);
|
|
559
|
+
(0, fs_extra_1.writeFileSync)(reportFilePath, JSON.stringify(testProgress, null, 2));
|
|
560
|
+
return undefined;
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
return await this.uploadTestCase(testProgress, reRunId);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
async uploadTestCase(testCase, rerunId) {
|
|
567
|
+
let runId = "";
|
|
568
|
+
let projectId = "";
|
|
569
|
+
if (!process.env.UPLOADING_TEST_CASE) {
|
|
570
|
+
process.env.UPLOADING_TEST_CASE = "[]";
|
|
571
|
+
}
|
|
572
|
+
const anyRemArr = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
573
|
+
const randomID = Math.random().toString(36).substring(7);
|
|
574
|
+
anyRemArr.push(randomID);
|
|
575
|
+
let data;
|
|
576
|
+
process.env.UPLOADING_TEST_CASE = JSON.stringify(anyRemArr);
|
|
577
|
+
try {
|
|
578
|
+
if (process.env.RUN_ID && process.env.PROJECT_ID && !process.env.IGNORE_ENV_VARIABLES) {
|
|
579
|
+
runId = process.env.RUN_ID;
|
|
580
|
+
projectId = process.env.PROJECT_ID;
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
const runDoc = await this.uploadService.createRunDocument(this.runName);
|
|
584
|
+
runId = runDoc._id;
|
|
585
|
+
projectId = runDoc.project_id;
|
|
586
|
+
if (!process.env.IGNORE_ENV_VARIABLES) {
|
|
587
|
+
process.env.RUN_ID = runId;
|
|
588
|
+
process.env.PROJECT_ID = projectId;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
data = await this.uploadService.uploadTestCase(testCase, runId, projectId, this.reportFolder, rerunId);
|
|
592
|
+
this.writeTestCaseReportToDisk(testCase);
|
|
593
|
+
}
|
|
594
|
+
catch (e) {
|
|
595
|
+
console.error("Error uploading test case:", e);
|
|
596
|
+
}
|
|
597
|
+
finally {
|
|
598
|
+
const arrRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
599
|
+
arrRem.splice(arrRem.indexOf(randomID), 1);
|
|
600
|
+
process.env.UPLOADING_TEST_CASE = JSON.stringify(arrRem);
|
|
601
|
+
}
|
|
602
|
+
return data ? data : null;
|
|
603
|
+
}
|
|
604
|
+
writeTestCaseReportToDisk(testCase) {
|
|
605
|
+
var _a;
|
|
606
|
+
const reportFolder = (_a = this.reportFolder) !== null && _a !== void 0 ? _a : process.env.TESTCASE_REPORT_FOLDER_PATH;
|
|
607
|
+
if (!reportFolder) {
|
|
608
|
+
console.error("Report folder is not defined");
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
try {
|
|
612
|
+
let i = 0;
|
|
613
|
+
while (fs_1.default.existsSync(path_1.default.join(reportFolder, `${i}`))) {
|
|
614
|
+
i++;
|
|
615
|
+
}
|
|
616
|
+
fs_1.default.mkdirSync(path_1.default.join(reportFolder, `${i}`));
|
|
617
|
+
//exclude network log from the saved report
|
|
618
|
+
const networkLog = testCase.networkLog;
|
|
619
|
+
delete testCase.networkLog;
|
|
620
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `report.json`), JSON.stringify(testCase, null, 2));
|
|
621
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, `${i}`, `network.json`), JSON.stringify(networkLog, null, 2));
|
|
622
|
+
}
|
|
623
|
+
catch (error) {
|
|
624
|
+
console.error("Error writing test case report to disk:", error);
|
|
625
|
+
}
|
|
356
626
|
}
|
|
357
627
|
onTestRunFinished(testRunFinished) {
|
|
358
628
|
const { timestamp, success, message } = testRunFinished;
|
|
359
629
|
const prevResult = this.report.result;
|
|
360
630
|
this.report.result = {
|
|
361
|
-
status: success ?
|
|
631
|
+
status: success ? "PASSED" : "FAILED",
|
|
362
632
|
startTime: prevResult.startTime,
|
|
363
633
|
endTime: this.getTimeStamp(timestamp),
|
|
364
634
|
message,
|