@dev-blinq/cucumber-js 1.0.76-main → 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 +31 -19
- package/lib/api/gherkin.js +6 -1
- package/lib/api/gherkin.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 +220 -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 +51 -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 +46 -12
- package/lib/formatter/helpers/report_generator.js +317 -55
- 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 +63 -18
- 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,70 +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;
|
|
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
|
+
}
|
|
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
383
|
if (testStep.pickleStepId === undefined) {
|
|
275
|
-
if (testStepResult.status ===
|
|
384
|
+
if (testStepResult.status === "FAILED") {
|
|
276
385
|
console.error(`Before/After hook failed with message: ${testStepResult.message}`);
|
|
277
386
|
}
|
|
278
387
|
return;
|
|
279
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
|
+
}
|
|
280
408
|
const stepProgess = this.stepReportMap.get(testStep.pickleStepId);
|
|
281
409
|
const prevStepResult = stepProgess.result;
|
|
282
410
|
let data = {};
|
|
283
|
-
const reportFolder = this.reportFolder;
|
|
284
|
-
if (reportFolder === null) {
|
|
285
|
-
throw new Error('"reportFolder" is "null". Failed to run BVT hooks. Please retry after running "Generate All" or "Record Scenario" ');
|
|
286
|
-
}
|
|
287
411
|
try {
|
|
288
|
-
|
|
289
|
-
|
|
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" ');
|
|
415
|
+
}
|
|
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"));
|
|
290
418
|
}
|
|
291
419
|
}
|
|
292
420
|
catch (error) {
|
|
293
|
-
console.log(
|
|
421
|
+
console.log("Error reading data.json");
|
|
294
422
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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 = [];
|
|
302
444
|
if (Object.keys(data).length > 0) {
|
|
303
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;
|
|
304
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
|
+
// }
|
|
305
488
|
}
|
|
306
489
|
getLogFileContent() {
|
|
307
490
|
let projectPath = process.cwd();
|
|
308
491
|
if (process.env.PROJECT_PATH) {
|
|
309
492
|
projectPath = process.env.PROJECT_PATH;
|
|
310
493
|
}
|
|
311
|
-
const logFolder = path_1.default.join(projectPath,
|
|
494
|
+
const logFolder = path_1.default.join(projectPath, "logs", "web");
|
|
312
495
|
if (!fs_1.default.existsSync(logFolder)) {
|
|
313
496
|
return [];
|
|
314
497
|
}
|
|
@@ -320,7 +503,7 @@ class ReportGenerator {
|
|
|
320
503
|
return [];
|
|
321
504
|
}
|
|
322
505
|
try {
|
|
323
|
-
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");
|
|
324
507
|
return JSON.parse(logFileContent);
|
|
325
508
|
}
|
|
326
509
|
catch (error) {
|
|
@@ -330,43 +513,122 @@ class ReportGenerator {
|
|
|
330
513
|
getTestCaseResult(steps) {
|
|
331
514
|
for (const step of steps) {
|
|
332
515
|
switch (step.result.status) {
|
|
333
|
-
case
|
|
516
|
+
case "FAILED":
|
|
334
517
|
return {
|
|
335
518
|
status: step.result.status,
|
|
336
519
|
message: step.result.message,
|
|
337
520
|
// exception: step.result.exception,
|
|
338
521
|
};
|
|
339
|
-
case
|
|
340
|
-
case
|
|
341
|
-
case
|
|
522
|
+
case "AMBIGUOUS":
|
|
523
|
+
case "UNDEFINED":
|
|
524
|
+
case "PENDING":
|
|
342
525
|
return {
|
|
343
|
-
status:
|
|
526
|
+
status: "FAILED",
|
|
344
527
|
message: `step "${step.text}" is ${step.result.status}`,
|
|
345
528
|
};
|
|
346
529
|
}
|
|
347
530
|
}
|
|
348
531
|
return {
|
|
349
|
-
status:
|
|
532
|
+
status: "PASSED",
|
|
350
533
|
};
|
|
351
534
|
}
|
|
352
|
-
onTestCaseFinished(testCaseFinished) {
|
|
535
|
+
async onTestCaseFinished(testCaseFinished, reRunId) {
|
|
353
536
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
354
537
|
const testProgress = this.testCaseReportMap.get(testCaseStartedId);
|
|
355
538
|
const prevResult = testProgress.result;
|
|
356
539
|
const steps = Object.values(testProgress.steps);
|
|
357
540
|
const result = this.getTestCaseResult(steps);
|
|
541
|
+
const endTime = this.getTimeStamp(timestamp);
|
|
358
542
|
testProgress.result = {
|
|
359
543
|
...result,
|
|
360
544
|
startTime: prevResult.startTime,
|
|
361
|
-
endTime
|
|
545
|
+
endTime,
|
|
362
546
|
};
|
|
363
|
-
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
|
+
}
|
|
364
626
|
}
|
|
365
627
|
onTestRunFinished(testRunFinished) {
|
|
366
628
|
const { timestamp, success, message } = testRunFinished;
|
|
367
629
|
const prevResult = this.report.result;
|
|
368
630
|
this.report.result = {
|
|
369
|
-
status: success ?
|
|
631
|
+
status: success ? "PASSED" : "FAILED",
|
|
370
632
|
startTime: prevResult.startTime,
|
|
371
633
|
endTime: this.getTimeStamp(timestamp),
|
|
372
634
|
message,
|