@dev-blinq/cucumber-js 1.0.22 → 1.0.23-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 +167 -0
- package/lib/api/gherkin.js +47 -1
- package/lib/api/gherkin.js.map +1 -1
- package/lib/cli/index.js +3 -0
- package/lib/cli/index.js.map +1 -1
- package/lib/configuration/argv_parser.js +2 -1
- package/lib/configuration/argv_parser.js.map +1 -1
- package/lib/configuration/axios_client.d.ts +1 -0
- package/lib/configuration/axios_client.js +40 -0
- package/lib/configuration/axios_client.js.map +1 -0
- package/lib/configuration/default_configuration.js +1 -0
- package/lib/configuration/default_configuration.js.map +1 -1
- package/lib/configuration/types.d.ts +1 -0
- package/lib/configuration/types.js.map +1 -1
- package/lib/formatter/bvt_analysis_formatter.d.ts +1 -0
- package/lib/formatter/bvt_analysis_formatter.js +48 -160
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.d.ts +11 -2
- package/lib/formatter/feature_data_format.js +78 -5
- package/lib/formatter/feature_data_format.js.map +1 -1
- package/lib/formatter/helpers/report_generator.d.ts +26 -3
- package/lib/formatter/helpers/report_generator.js +163 -21
- package/lib/formatter/helpers/report_generator.js.map +1 -1
- package/lib/formatter/helpers/upload_serivce.d.ts +4 -0
- package/lib/formatter/helpers/upload_serivce.js +64 -3
- package/lib/formatter/helpers/upload_serivce.js.map +1 -1
- package/lib/formatter/helpers/uploader.d.ts +4 -1
- package/lib/formatter/helpers/uploader.js +59 -6
- package/lib/formatter/helpers/uploader.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 +7 -4
|
@@ -1,39 +1,16 @@
|
|
|
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
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
6
|
const child_process_1 = require("child_process");
|
|
7
|
+
const fs_1 = require("fs");
|
|
30
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const tmp_promise_1 = require("tmp-promise");
|
|
31
10
|
const _1 = __importDefault(require("."));
|
|
32
11
|
const value_checker_1 = require("../value_checker");
|
|
33
12
|
const report_generator_1 = __importDefault(require("./helpers/report_generator"));
|
|
34
13
|
const uploader_1 = __importDefault(require("./helpers/uploader"));
|
|
35
|
-
// import { temporaryFileTask } from 'tempy'
|
|
36
|
-
const fs_1 = require("fs");
|
|
37
14
|
//User token
|
|
38
15
|
const TOKEN = process.env.TOKEN;
|
|
39
16
|
class BVTAnalysisFormatter extends _1.default {
|
|
@@ -83,7 +60,7 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
83
60
|
}
|
|
84
61
|
async analyzeReport(report) {
|
|
85
62
|
if (report.result.status === 'PASSED') {
|
|
86
|
-
this.log('
|
|
63
|
+
this.log('No test failed. No need to retrain\n');
|
|
87
64
|
const uploadSuccessful = await this.uploadFinalReport(report);
|
|
88
65
|
if (uploadSuccessful) {
|
|
89
66
|
process.exit(0);
|
|
@@ -94,7 +71,7 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
94
71
|
this.log('Some tests failed, starting the retraining...\n');
|
|
95
72
|
if (!('startTime' in report.result) || !('endTime' in report.result)) {
|
|
96
73
|
this.log('Unknown error occured,not retraining\n');
|
|
97
|
-
await this.
|
|
74
|
+
await this.uploadFinalReport(report);
|
|
98
75
|
return;
|
|
99
76
|
}
|
|
100
77
|
const finalReport = await this.processTestCases(report);
|
|
@@ -107,18 +84,9 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
107
84
|
}
|
|
108
85
|
}
|
|
109
86
|
async processTestCases(report) {
|
|
110
|
-
// const finalResults: JsonTestResult[] = []
|
|
111
|
-
// const finalStepResults: JsonTestResult[][] = []
|
|
112
|
-
// let isFailing = true
|
|
113
87
|
const finalTestCases = [];
|
|
114
88
|
for (const testCase of report.testCases) {
|
|
115
89
|
const modifiedTestCase = await this.processTestCase(testCase, report);
|
|
116
|
-
// finalResults.push(result)
|
|
117
|
-
// finalStepResults.push(steps)
|
|
118
|
-
// //If any of the test case fails, the whole run is considered failed
|
|
119
|
-
// if (result.status === 'FAILED') {
|
|
120
|
-
// isFailing = false
|
|
121
|
-
// }
|
|
122
90
|
finalTestCases.push(modifiedTestCase);
|
|
123
91
|
}
|
|
124
92
|
const finalResult = finalTestCases.some((tc) => tc.result.status !== 'PASSED')
|
|
@@ -130,121 +98,30 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
130
98
|
return {
|
|
131
99
|
result: finalResult,
|
|
132
100
|
testCases: finalTestCases,
|
|
101
|
+
env: report.env,
|
|
133
102
|
};
|
|
134
|
-
// return {
|
|
135
|
-
// result: isFailing
|
|
136
|
-
// ? {
|
|
137
|
-
// status: 'FIXED_BY_AI',
|
|
138
|
-
// startTime:
|
|
139
|
-
// 'startTime' in report.result
|
|
140
|
-
// ? report.result.startTime
|
|
141
|
-
// : this.START,
|
|
142
|
-
// endTime: Date.now(),
|
|
143
|
-
// }
|
|
144
|
-
// : {
|
|
145
|
-
// status: 'FAILED',
|
|
146
|
-
// startTime:
|
|
147
|
-
// 'startTime' in report.result
|
|
148
|
-
// ? report.result.startTime
|
|
149
|
-
// : Date.now(),
|
|
150
|
-
// endTime: Date.now(),
|
|
151
|
-
// },
|
|
152
|
-
// testCases: report.testCases.map((testCase, i) => {
|
|
153
|
-
// return {
|
|
154
|
-
// ...testCase,
|
|
155
|
-
// result: finalResults[i],
|
|
156
|
-
// steps: testCase.steps.map((step, j) => {
|
|
157
|
-
// return {
|
|
158
|
-
// ...step,
|
|
159
|
-
// result: finalStepResults[i][j],
|
|
160
|
-
// }
|
|
161
|
-
// }),
|
|
162
|
-
// }
|
|
163
|
-
// }),
|
|
164
|
-
// }
|
|
165
103
|
}
|
|
166
104
|
async processTestCase(testCase, report) {
|
|
167
105
|
if (testCase.result.status === 'PASSED') {
|
|
168
106
|
return testCase;
|
|
169
107
|
}
|
|
170
108
|
const failedTestSteps = testCase.steps
|
|
171
|
-
.map((step, i) => (step.result.status
|
|
109
|
+
.map((step, i) => (step.result.status === 'FAILED' ? i : null))
|
|
172
110
|
.filter((i) => i !== null);
|
|
173
111
|
const retrainStats = await this.retrain(failedTestSteps, testCase);
|
|
174
|
-
// if(newTestCase.result.status === "PASSED") {
|
|
175
|
-
// newTestCase.result.status = "FIXED"
|
|
176
|
-
// }
|
|
177
112
|
if (!retrainStats) {
|
|
178
113
|
return testCase;
|
|
179
114
|
}
|
|
180
|
-
// const newResult: JsonTestResult =
|
|
181
|
-
// retrainStats.result.status === 'PASSED'
|
|
182
|
-
// ? {
|
|
183
|
-
// ...retrainStats.result,
|
|
184
|
-
// status: 'FIXED_BY_AI',
|
|
185
|
-
// }
|
|
186
|
-
// : retrainStats.result
|
|
187
|
-
// const finalResult = this.createFinalResult(success, testCase, report)
|
|
188
115
|
return {
|
|
189
116
|
...testCase,
|
|
190
117
|
retrainStats,
|
|
191
118
|
};
|
|
192
|
-
// return {
|
|
193
|
-
// result: finalResult,
|
|
194
|
-
// steps: testCase.steps.map((step) =>
|
|
195
|
-
// step.result.status === 'PASSED'
|
|
196
|
-
// ? { ...step.result }
|
|
197
|
-
// : this.createStepResult(success, step, report)
|
|
198
|
-
// ),
|
|
199
|
-
// }
|
|
200
119
|
}
|
|
201
|
-
// private createFinalResult(
|
|
202
|
-
// success: boolean,
|
|
203
|
-
// testCase: JsonTestProgress,
|
|
204
|
-
// report: JsonReport
|
|
205
|
-
// ): JsonFixedByAi | JsonResultFailed {
|
|
206
|
-
// const status = success ? 'FIXED_BY_AI' : 'FAILED'
|
|
207
|
-
// return {
|
|
208
|
-
// status,
|
|
209
|
-
// startTime: this.createStartTime(testCase, report),
|
|
210
|
-
// endTime: Date.now(),
|
|
211
|
-
// }
|
|
212
|
-
// }
|
|
213
|
-
// private createStartTime(
|
|
214
|
-
// testCase: JsonTestProgress,
|
|
215
|
-
// report: JsonReport
|
|
216
|
-
// ): number {
|
|
217
|
-
// let startTime
|
|
218
|
-
// if ('startTime' in testCase.result) {
|
|
219
|
-
// startTime = testCase.result.startTime
|
|
220
|
-
// } else if ('startTime' in report.result) {
|
|
221
|
-
// startTime = report.result.startTime
|
|
222
|
-
// } else {
|
|
223
|
-
// startTime = Date.now()
|
|
224
|
-
// }
|
|
225
|
-
// return startTime
|
|
226
|
-
// }
|
|
227
|
-
// private createStepResult(
|
|
228
|
-
// success: boolean,
|
|
229
|
-
// step: JsonStep,
|
|
230
|
-
// report: JsonReport
|
|
231
|
-
// ): JsonFixedByAi | JsonResultFailed {
|
|
232
|
-
// const status = success ? 'FIXED_BY_AI' : 'FAILED'
|
|
233
|
-
// return {
|
|
234
|
-
// status,
|
|
235
|
-
// startTime:
|
|
236
|
-
// 'startTime' in step.result
|
|
237
|
-
// ? step.result.startTime
|
|
238
|
-
// : 'startTime' in report.result
|
|
239
|
-
// ? report.result.startTime
|
|
240
|
-
// : Date.now(),
|
|
241
|
-
// endTime: Date.now(),
|
|
242
|
-
// }
|
|
243
|
-
// }
|
|
244
120
|
async uploadFinalReport(finalReport) {
|
|
245
121
|
let success = true;
|
|
246
122
|
try {
|
|
247
|
-
await this.uploader.uploadRun(finalReport, this.runName);
|
|
123
|
+
const { projectId, runId } = await this.uploader.uploadRun(finalReport, this.runName);
|
|
124
|
+
this.logReportLink(runId, projectId);
|
|
248
125
|
}
|
|
249
126
|
catch (err) {
|
|
250
127
|
this.log('Error uploading report\n');
|
|
@@ -257,10 +134,7 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
257
134
|
return success;
|
|
258
135
|
}
|
|
259
136
|
async retrain(failedTestCases, testCase) {
|
|
260
|
-
|
|
261
|
-
return await this.call_cucumber_client(stepsToRetrain, testCase);
|
|
262
|
-
// const success = await this.call_cucumber_client(stepsToRetrain, testCase)
|
|
263
|
-
// return success
|
|
137
|
+
return await this.call_cucumber_client(failedTestCases, testCase);
|
|
264
138
|
}
|
|
265
139
|
async call_cucumber_client(stepsToRetrain, testCase) {
|
|
266
140
|
return new Promise((resolve, reject) => {
|
|
@@ -269,41 +143,55 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
269
143
|
process.cwd(),
|
|
270
144
|
path_1.default.join(process.cwd(), testCase.uri),
|
|
271
145
|
`${testCase.scenarioName}`,
|
|
146
|
+
'undefined',
|
|
272
147
|
`${stepsToRetrain.join(',')}`,
|
|
273
148
|
];
|
|
274
149
|
if (process.env.BLINQ_ENV) {
|
|
275
150
|
args.push(`--env=${process.env.BLINQ_ENV}`);
|
|
276
151
|
}
|
|
277
152
|
// const temporaryFileTask = await import('tempy')
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
});
|
|
153
|
+
(0, tmp_promise_1.withFile)(async ({ path: tempFile, fd }) => {
|
|
154
|
+
// when this function returns or throws - release the file
|
|
155
|
+
args.push(`--temp-file=${tempFile}`);
|
|
156
|
+
const cucumberClient = (0, child_process_1.spawn)('node', [cucumber_client_path, ...args], {
|
|
157
|
+
env: {
|
|
158
|
+
...process.env,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
cucumberClient.stdout.on('data', (data) => {
|
|
162
|
+
console.log(data.toString());
|
|
163
|
+
});
|
|
164
|
+
cucumberClient.stderr.on('data', (data) => {
|
|
165
|
+
console.error(data.toString());
|
|
166
|
+
});
|
|
167
|
+
cucumberClient.on('close', (code) => {
|
|
168
|
+
if (code === 0) {
|
|
169
|
+
const reportData = (0, fs_1.readFileSync)(tempFile, 'utf-8');
|
|
170
|
+
const retrainStats = JSON.parse(reportData);
|
|
171
|
+
resolve(retrainStats);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
this.log('Error retraining\n');
|
|
175
|
+
resolve(null);
|
|
176
|
+
}
|
|
303
177
|
});
|
|
304
178
|
});
|
|
305
179
|
});
|
|
306
180
|
}
|
|
181
|
+
logReportLink(runId, projectId) {
|
|
182
|
+
let reportLinkBaseUrl = 'https://www.app.blinq.io';
|
|
183
|
+
if (process.env.NODE_ENV_BLINQ === 'local') {
|
|
184
|
+
reportLinkBaseUrl = 'http://localhost:3000';
|
|
185
|
+
}
|
|
186
|
+
else if (process.env.NODE_ENV_BLINQ === 'dev') {
|
|
187
|
+
reportLinkBaseUrl = 'https://dev.app.blinq.io';
|
|
188
|
+
}
|
|
189
|
+
else if (process.env.NODE_ENV_BLINQ === 'stage') {
|
|
190
|
+
reportLinkBaseUrl = 'https://stage.app.blinq.io';
|
|
191
|
+
}
|
|
192
|
+
const reportLink = `${reportLinkBaseUrl}/${projectId}/run-report/${runId}`;
|
|
193
|
+
this.log(`Report link: ${reportLink}\n`);
|
|
194
|
+
}
|
|
307
195
|
}
|
|
308
196
|
exports.default = BVTAnalysisFormatter;
|
|
309
197
|
//# sourceMappingURL=bvt_analysis_formatter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bvt_analysis_formatter.js","sourceRoot":"","sources":["../../src/formatter/bvt_analysis_formatter.ts"],"names":[],"mappings":"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","sourcesContent":["import { Envelope, Meta } from '@cucumber/messages'\nimport { spawn } from 'child_process'\nimport path from 'path'\nimport Formatter, { IFormatterOptions } from '.'\nimport { doesHaveValue } from '../value_checker'\nimport ReportGenerator, {\n JsonFixedByAi,\n JsonReport,\n JsonResultFailed,\n JsonResultPassed,\n JsonStep,\n JsonTestProgress,\n JsonTestResult,\n RetrainStats,\n} from './helpers/report_generator'\nimport ReportUploader from './helpers/uploader'\n// import { temporaryFileTask } from 'tempy'\nimport { readFileSync } from 'fs'\n//User token\nconst TOKEN = process.env.TOKEN\ninterface MetaMessage extends Meta {\n runName: string\n}\n\ninterface EnvelopeWithMetaMessage extends Envelope {\n meta: MetaMessage\n}\nexport default class BVTAnalysisFormatter extends Formatter {\n private reportGenerator = new ReportGenerator()\n private uploader = new ReportUploader(this.reportGenerator)\n private exit = false\n private START: number\n private runName: string\n constructor(options: IFormatterOptions) {\n super(options)\n if (!TOKEN && process.env.BVT_FORMATTER === 'ANALYSIS') {\n throw new Error('TOKEN must be set')\n }\n options.eventBroadcaster.on(\n 'envelope',\n async (envelope: EnvelopeWithMetaMessage) => {\n this.reportGenerator.handleMessage(envelope)\n if (\n doesHaveValue(envelope.meta) &&\n doesHaveValue(envelope.meta.runName)\n ) {\n this.runName = envelope.meta.runName\n }\n if (doesHaveValue(envelope.testRunFinished)) {\n const report = this.reportGenerator.getReport()\n this.START = Date.now()\n if (process.env.BVT_FORMATTER === 'ANALYSIS') {\n await this.analyzeReport(report)\n } else {\n await this.uploadReport(report)\n }\n this.exit = true\n }\n }\n )\n }\n\n private async uploadReport(report: JsonReport) {\n const uploadSuccessful = await this.uploadFinalReport(report)\n if (uploadSuccessful && report.result.status !== 'FAILED') {\n process.exit(0)\n }\n process.exit(1)\n }\n\n async finished(): Promise<any> {\n await new Promise((resolve) => {\n const checkInterval = setInterval(() => {\n if (this.exit) {\n clearInterval(checkInterval)\n resolve(null)\n }\n }, 100) // check every 100ms\n })\n }\n private async analyzeReport(report: JsonReport) {\n if (report.result.status === 'PASSED') {\n this.log('All tests passed. No need to retrain\\n')\n const uploadSuccessful = await this.uploadFinalReport(report)\n if (uploadSuccessful) {\n process.exit(0)\n }\n\n process.exit(1)\n }\n //checking if the type of report.result is JsonResultFailed or not\n this.log('Some tests failed, starting the retraining...\\n')\n if (!('startTime' in report.result) || !('endTime' in report.result)) {\n this.log('Unknown error occured,not retraining\\n')\n await this.uploader.uploadRun(report, this.runName)\n return\n }\n const finalReport = await this.processTestCases(report)\n const uploadSuccessful = await this.uploadFinalReport(finalReport)\n if (finalReport.result.status !== 'FAILED' && uploadSuccessful) {\n process.exit(0)\n } else {\n process.exit(1)\n }\n }\n private async processTestCases(report: JsonReport): Promise<JsonReport> {\n // const finalResults: JsonTestResult[] = []\n // const finalStepResults: JsonTestResult[][] = []\n // let isFailing = true\n const finalTestCases = []\n for (const testCase of report.testCases) {\n const modifiedTestCase = await this.processTestCase(testCase, report)\n // finalResults.push(result)\n // finalStepResults.push(steps)\n // //If any of the test case fails, the whole run is considered failed\n // if (result.status === 'FAILED') {\n // isFailing = false\n // }\n finalTestCases.push(modifiedTestCase)\n }\n const finalResult = finalTestCases.some(\n (tc) => tc.result.status !== 'PASSED'\n )\n ? report.result\n : ({\n ...report.result,\n status: 'PASSED',\n } as JsonTestResult)\n return {\n result: finalResult,\n testCases: finalTestCases,\n }\n // return {\n // result: isFailing\n // ? {\n // status: 'FIXED_BY_AI',\n // startTime:\n // 'startTime' in report.result\n // ? report.result.startTime\n // : this.START,\n // endTime: Date.now(),\n // }\n // : {\n // status: 'FAILED',\n // startTime:\n // 'startTime' in report.result\n // ? report.result.startTime\n // : Date.now(),\n // endTime: Date.now(),\n // },\n // testCases: report.testCases.map((testCase, i) => {\n // return {\n // ...testCase,\n // result: finalResults[i],\n // steps: testCase.steps.map((step, j) => {\n // return {\n // ...step,\n // result: finalStepResults[i][j],\n // }\n // }),\n // }\n // }),\n // }\n }\n private async processTestCase(\n testCase: JsonTestProgress,\n report: JsonReport\n ): Promise<JsonTestProgress> {\n if (testCase.result.status === 'PASSED') {\n return testCase\n }\n const failedTestSteps = testCase.steps\n .map((step, i) => (step.result.status !== 'PASSED' ? i : null))\n .filter((i) => i !== null)\n const retrainStats = await this.retrain(failedTestSteps, testCase)\n // if(newTestCase.result.status === \"PASSED\") {\n // newTestCase.result.status = \"FIXED\"\n // }\n if (!retrainStats) {\n return testCase\n }\n // const newResult: JsonTestResult =\n // retrainStats.result.status === 'PASSED'\n // ? {\n // ...retrainStats.result,\n // status: 'FIXED_BY_AI',\n // }\n // : retrainStats.result\n // const finalResult = this.createFinalResult(success, testCase, report)\n return {\n ...testCase,\n retrainStats,\n }\n // return {\n // result: finalResult,\n // steps: testCase.steps.map((step) =>\n // step.result.status === 'PASSED'\n // ? { ...step.result }\n // : this.createStepResult(success, step, report)\n // ),\n // }\n }\n\n // private createFinalResult(\n // success: boolean,\n // testCase: JsonTestProgress,\n // report: JsonReport\n // ): JsonFixedByAi | JsonResultFailed {\n // const status = success ? 'FIXED_BY_AI' : 'FAILED'\n // return {\n // status,\n // startTime: this.createStartTime(testCase, report),\n // endTime: Date.now(),\n // }\n // }\n // private createStartTime(\n // testCase: JsonTestProgress,\n // report: JsonReport\n // ): number {\n // let startTime\n\n // if ('startTime' in testCase.result) {\n // startTime = testCase.result.startTime\n // } else if ('startTime' in report.result) {\n // startTime = report.result.startTime\n // } else {\n // startTime = Date.now()\n // }\n\n // return startTime\n // }\n // private createStepResult(\n // success: boolean,\n // step: JsonStep,\n // report: JsonReport\n // ): JsonFixedByAi | JsonResultFailed {\n // const status = success ? 'FIXED_BY_AI' : 'FAILED'\n // return {\n // status,\n // startTime:\n // 'startTime' in step.result\n // ? step.result.startTime\n // : 'startTime' in report.result\n // ? report.result.startTime\n // : Date.now(),\n // endTime: Date.now(),\n // }\n // }\n private async uploadFinalReport(finalReport: JsonReport) {\n let success = true\n try {\n await this.uploader.uploadRun(finalReport, this.runName)\n } catch (err) {\n this.log('Error uploading report\\n')\n if ('stack' in err) {\n this.log(err.stack)\n }\n success = false\n }\n\n //this.log(JSON.stringify(finalReport, null, 2))\n return success\n }\n private async retrain(\n failedTestCases: number[],\n testCase: JsonTestProgress\n ): Promise<RetrainStats | null> {\n const stepsToRetrain = testCase.steps.map((_, i) => i)\n return await this.call_cucumber_client(stepsToRetrain, testCase)\n // const success = await this.call_cucumber_client(stepsToRetrain, testCase)\n // return success\n }\n\n private async call_cucumber_client(\n stepsToRetrain: number[],\n testCase: JsonTestProgress\n ): Promise<RetrainStats | null> {\n return new Promise((resolve, reject) => {\n const cucumber_client_path = path.resolve(\n process.cwd(),\n 'node_modules',\n '@dev-blinq',\n 'cucumber_client',\n 'bin',\n 'client',\n 'cucumber.js'\n )\n\n const args: string[] = [\n process.cwd(),\n path.join(process.cwd(), testCase.uri),\n `${testCase.scenarioName}`,\n `${stepsToRetrain.join(',')}`,\n ]\n\n if (process.env.BLINQ_ENV) {\n args.push(`--env=${process.env.BLINQ_ENV}`)\n }\n // const temporaryFileTask = await import('tempy')\n import('tempy').then(({ temporaryFileTask }) => {\n temporaryFileTask((tempFile) => {\n args.push(`--temp-file=${tempFile}`)\n const cucumberClient = spawn(\n 'node',\n [cucumber_client_path, ...args],\n {\n env: {\n ...process.env,\n },\n }\n )\n\n cucumberClient.stdout.on('data', (data) => {\n console.log(data.toString())\n })\n\n cucumberClient.stderr.on('data', (data) => {\n console.error(data.toString())\n })\n\n cucumberClient.on('close', (code) => {\n if (code === 0) {\n const reportData = readFileSync(tempFile, 'utf-8')\n const retrainStats = JSON.parse(reportData) as RetrainStats\n resolve(retrainStats)\n } else {\n this.log('Error retraining\\n')\n resolve(null)\n }\n })\n })\n })\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bvt_analysis_formatter.js","sourceRoot":"","sources":["../../src/formatter/bvt_analysis_formatter.ts"],"names":[],"mappings":";;;;;AACA,iDAAqC;AACrC,2BAAiC;AACjC,gDAAuB;AACvB,6CAAsC;AACtC,yCAAgD;AAChD,oDAAgD;AAChD,kFAKmC;AACnC,kEAA+C;AAC/C,YAAY;AACZ,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAA;AAQ/B,MAAqB,oBAAqB,SAAQ,UAAS;IAMzD,YAAY,OAA0B;QACpC,KAAK,CAAC,OAAO,CAAC,CAAA;QANR,oBAAe,GAAG,IAAI,0BAAe,EAAE,CAAA;QACvC,aAAQ,GAAG,IAAI,kBAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QACnD,SAAI,GAAG,KAAK,CAAA;QAKlB,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,UAAU,EAAE;YACtD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;SACrC;QACD,OAAO,CAAC,gBAAgB,CAAC,EAAE,CACzB,UAAU,EACV,KAAK,EAAE,QAAiC,EAAE,EAAE;YAC1C,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YAC5C,IACE,IAAA,6BAAa,EAAC,QAAQ,CAAC,IAAI,CAAC;gBAC5B,IAAA,6BAAa,EAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EACpC;gBACA,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAA;aACrC;YACD,IAAI,IAAA,6BAAa,EAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;gBAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAA;gBAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBACvB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,UAAU,EAAE;oBAC5C,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;iBACjC;qBAAM;oBACL,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;iBAChC;gBACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;aACjB;QACH,CAAC,CACF,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,MAAkB;QAC3C,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAC7D,IAAI,gBAAgB,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;YACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAChB;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC5B,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;gBACrC,IAAI,IAAI,CAAC,IAAI,EAAE;oBACb,aAAa,CAAC,aAAa,CAAC,CAAA;oBAC5B,OAAO,CAAC,IAAI,CAAC,CAAA;iBACd;YACH,CAAC,EAAE,GAAG,CAAC,CAAA,CAAC,oBAAoB;QAC9B,CAAC,CAAC,CAAA;IACJ,CAAC;IACO,KAAK,CAAC,aAAa,CAAC,MAAkB;QAC5C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;YACrC,IAAI,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAA;YAChD,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;YAC7D,IAAI,gBAAgB,EAAE;gBACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;aAChB;YAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAChB;QACD,kEAAkE;QAClE,IAAI,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;QAC3D,IAAI,CAAC,CAAC,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE;YACpE,IAAI,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;YAClD,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;YACpC,OAAM;SACP;QACD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAA;QACvD,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;QAClE,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,gBAAgB,EAAE;YAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAChB;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAChB;IACH,CAAC;IACO,KAAK,CAAC,gBAAgB,CAAC,MAAkB;QAC/C,MAAM,cAAc,GAAG,EAAE,CAAA;QACzB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;YACvC,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAErE,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;SACtC;QACD,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CACrC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CACtC;YACC,CAAC,CAAC,MAAM,CAAC,MAAM;YACf,CAAC,CAAE;gBACC,GAAG,MAAM,CAAC,MAAM;gBAChB,MAAM,EAAE,QAAQ;aACE,CAAA;QACxB,OAAO;YACL,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,cAAc;YACzB,GAAG,EAAE,MAAM,CAAC,GAAG;SAChB,CAAA;IACH,CAAC;IACO,KAAK,CAAC,eAAe,CAC3B,QAA0B,EAC1B,MAAkB;QAElB,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;YACvC,OAAO,QAAQ,CAAA;SAChB;QACD,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK;aACnC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aAC9D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;QAC5B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAA;QAElE,IAAI,CAAC,YAAY,EAAE;YACjB,OAAO,QAAQ,CAAA;SAChB;QAED,OAAO;YACL,GAAG,QAAQ;YACX,YAAY;SACb,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,WAAuB;QACrD,IAAI,OAAO,GAAG,IAAI,CAAA;QAClB,IAAI;YACF,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CACxD,WAAW,EACX,IAAI,CAAC,OAAO,CACb,CAAA;YACD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;SACrC;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;YACpC,IAAI,OAAO,IAAI,GAAG,EAAE;gBAClB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;aACpB;YACD,OAAO,GAAG,KAAK,CAAA;SAChB;QAED,gDAAgD;QAChD,OAAO,OAAO,CAAA;IAChB,CAAC;IACO,KAAK,CAAC,OAAO,CACnB,eAAyB,EACzB,QAA0B;QAE1B,OAAO,MAAM,IAAI,CAAC,oBAAoB,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAA;IACnE,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,cAAwB,EACxB,QAA0B;QAE1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,oBAAoB,GAAG,cAAI,CAAC,OAAO,CACvC,OAAO,CAAC,GAAG,EAAE,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,QAAQ,EACR,aAAa,CACd,CAAA;YAED,MAAM,IAAI,GAAa;gBACrB,OAAO,CAAC,GAAG,EAAE;gBACb,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,GAAG,CAAC;gBACtC,GAAG,QAAQ,CAAC,YAAY,EAAE;gBAC1B,WAAW;gBACX,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;aAC9B,CAAA;YAED,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE;gBACzB,IAAI,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAA;aAC5C;YACD,kDAAkD;YAClD,IAAA,sBAAQ,EAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE;gBACxC,0DAA0D;gBAC1D,IAAI,CAAC,IAAI,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAA;gBACpC,MAAM,cAAc,GAAG,IAAA,qBAAK,EAAC,MAAM,EAAE,CAAC,oBAAoB,EAAE,GAAG,IAAI,CAAC,EAAE;oBACpE,GAAG,EAAE;wBACH,GAAG,OAAO,CAAC,GAAG;qBACf;iBACF,CAAC,CAAA;gBAEF,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oBACxC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;gBAC9B,CAAC,CAAC,CAAA;gBAEF,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oBACxC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;gBAChC,CAAC,CAAC,CAAA;gBAEF,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;oBAClC,IAAI,IAAI,KAAK,CAAC,EAAE;wBACd,MAAM,UAAU,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;wBAClD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAiB,CAAA;wBAC3D,OAAO,CAAC,YAAY,CAAC,CAAA;qBACtB;yBAAM;wBACL,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;wBAC9B,OAAO,CAAC,IAAI,CAAC,CAAA;qBACd;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IACO,aAAa,CAAC,KAAa,EAAE,SAAiB;QACpD,IAAI,iBAAiB,GAAG,0BAA0B,CAAA;QAClD,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,OAAO,EAAE;YAC1C,iBAAiB,GAAG,uBAAuB,CAAA;SAC5C;aAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,KAAK,EAAE;YAC/C,iBAAiB,GAAG,0BAA0B,CAAA;SAC/C;aAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,OAAO,EAAE;YACjD,iBAAiB,GAAG,4BAA4B,CAAA;SAEjD;QACD,MAAM,UAAU,GAAG,GAAG,iBAAiB,IAAI,SAAS,eAAe,KAAK,EAAE,CAAA;QAC1E,IAAI,CAAC,GAAG,CAAC,gBAAgB,UAAU,IAAI,CAAC,CAAA;IAC1C,CAAC;CACF;AAzND,uCAyNC","sourcesContent":["import { Envelope, Meta } from '@cucumber/messages'\nimport { spawn } from 'child_process'\nimport { readFileSync } from 'fs'\nimport path from 'path'\nimport { withFile } from 'tmp-promise'\nimport Formatter, { IFormatterOptions } from '.'\nimport { doesHaveValue } from '../value_checker'\nimport ReportGenerator, {\n JsonReport,\n JsonTestProgress,\n JsonTestResult,\n RetrainStats,\n} from './helpers/report_generator'\nimport ReportUploader from './helpers/uploader'\n//User token\nconst TOKEN = process.env.TOKEN\ninterface MetaMessage extends Meta {\n runName: string\n}\n\ninterface EnvelopeWithMetaMessage extends Envelope {\n meta: MetaMessage\n}\nexport default class BVTAnalysisFormatter extends Formatter {\n private reportGenerator = new ReportGenerator()\n private uploader = new ReportUploader(this.reportGenerator)\n private exit = false\n private START: number\n private runName: string\n constructor(options: IFormatterOptions) {\n super(options)\n if (!TOKEN && process.env.BVT_FORMATTER === 'ANALYSIS') {\n throw new Error('TOKEN must be set')\n }\n options.eventBroadcaster.on(\n 'envelope',\n async (envelope: EnvelopeWithMetaMessage) => {\n this.reportGenerator.handleMessage(envelope)\n if (\n doesHaveValue(envelope.meta) &&\n doesHaveValue(envelope.meta.runName)\n ) {\n this.runName = envelope.meta.runName\n }\n if (doesHaveValue(envelope.testRunFinished)) {\n const report = this.reportGenerator.getReport()\n this.START = Date.now()\n if (process.env.BVT_FORMATTER === 'ANALYSIS') {\n await this.analyzeReport(report)\n } else {\n await this.uploadReport(report)\n }\n this.exit = true\n }\n }\n )\n }\n\n private async uploadReport(report: JsonReport) {\n const uploadSuccessful = await this.uploadFinalReport(report)\n if (uploadSuccessful && report.result.status !== 'FAILED') {\n process.exit(0)\n }\n process.exit(1)\n }\n\n async finished(): Promise<any> {\n await new Promise((resolve) => {\n const checkInterval = setInterval(() => {\n if (this.exit) {\n clearInterval(checkInterval)\n resolve(null)\n }\n }, 100) // check every 100ms\n })\n }\n private async analyzeReport(report: JsonReport) {\n if (report.result.status === 'PASSED') {\n this.log('No test failed. No need to retrain\\n')\n const uploadSuccessful = await this.uploadFinalReport(report)\n if (uploadSuccessful) {\n process.exit(0)\n }\n\n process.exit(1)\n }\n //checking if the type of report.result is JsonResultFailed or not\n this.log('Some tests failed, starting the retraining...\\n')\n if (!('startTime' in report.result) || !('endTime' in report.result)) {\n this.log('Unknown error occured,not retraining\\n')\n await this.uploadFinalReport(report)\n return\n }\n const finalReport = await this.processTestCases(report)\n const uploadSuccessful = await this.uploadFinalReport(finalReport)\n if (finalReport.result.status !== 'FAILED' && uploadSuccessful) {\n process.exit(0)\n } else {\n process.exit(1)\n }\n }\n private async processTestCases(report: JsonReport): Promise<JsonReport> {\n const finalTestCases = []\n for (const testCase of report.testCases) {\n const modifiedTestCase = await this.processTestCase(testCase, report)\n\n finalTestCases.push(modifiedTestCase)\n }\n const finalResult = finalTestCases.some(\n (tc) => tc.result.status !== 'PASSED'\n )\n ? report.result\n : ({\n ...report.result,\n status: 'PASSED',\n } as JsonTestResult)\n return {\n result: finalResult,\n testCases: finalTestCases,\n env: report.env,\n }\n }\n private async processTestCase(\n testCase: JsonTestProgress,\n report: JsonReport\n ): Promise<JsonTestProgress> {\n if (testCase.result.status === 'PASSED') {\n return testCase\n }\n const failedTestSteps = testCase.steps\n .map((step, i) => (step.result.status === 'FAILED' ? i : null))\n .filter((i) => i !== null)\n const retrainStats = await this.retrain(failedTestSteps, testCase)\n\n if (!retrainStats) {\n return testCase\n }\n\n return {\n ...testCase,\n retrainStats,\n }\n }\n\n private async uploadFinalReport(finalReport: JsonReport) {\n let success = true\n try {\n const { projectId, runId } = await this.uploader.uploadRun(\n finalReport,\n this.runName\n )\n this.logReportLink(runId, projectId)\n } catch (err) {\n this.log('Error uploading report\\n')\n if ('stack' in err) {\n this.log(err.stack)\n }\n success = false\n }\n\n //this.log(JSON.stringify(finalReport, null, 2))\n return success\n }\n private async retrain(\n failedTestCases: number[],\n testCase: JsonTestProgress\n ): Promise<RetrainStats | null> {\n return await this.call_cucumber_client(failedTestCases, testCase)\n }\n\n private async call_cucumber_client(\n stepsToRetrain: number[],\n testCase: JsonTestProgress\n ): Promise<RetrainStats | null> {\n return new Promise((resolve, reject) => {\n const cucumber_client_path = path.resolve(\n process.cwd(),\n 'node_modules',\n '@dev-blinq',\n 'cucumber_client',\n 'bin',\n 'client',\n 'cucumber.js'\n )\n\n const args: string[] = [\n process.cwd(),\n path.join(process.cwd(), testCase.uri),\n `${testCase.scenarioName}`,\n 'undefined',\n `${stepsToRetrain.join(',')}`,\n ]\n\n if (process.env.BLINQ_ENV) {\n args.push(`--env=${process.env.BLINQ_ENV}`)\n }\n // const temporaryFileTask = await import('tempy')\n withFile(async ({ path: tempFile, fd }) => {\n // when this function returns or throws - release the file\n args.push(`--temp-file=${tempFile}`)\n const cucumberClient = spawn('node', [cucumber_client_path, ...args], {\n env: {\n ...process.env,\n },\n })\n\n cucumberClient.stdout.on('data', (data) => {\n console.log(data.toString())\n })\n\n cucumberClient.stderr.on('data', (data) => {\n console.error(data.toString())\n })\n\n cucumberClient.on('close', (code) => {\n if (code === 0) {\n const reportData = readFileSync(tempFile, 'utf-8')\n const retrainStats = JSON.parse(reportData) as RetrainStats\n resolve(retrainStats)\n } else {\n this.log('Error retraining\\n')\n resolve(null)\n }\n })\n })\n })\n }\n private logReportLink(runId: string, projectId: string) {\n let reportLinkBaseUrl = 'https://www.app.blinq.io'\n if (process.env.NODE_ENV_BLINQ === 'local') {\n reportLinkBaseUrl = 'http://localhost:3000'\n } else if (process.env.NODE_ENV_BLINQ === 'dev') {\n reportLinkBaseUrl = 'https://dev.app.blinq.io'\n } else if (process.env.NODE_ENV_BLINQ === 'stage') {\n reportLinkBaseUrl = 'https://stage.app.blinq.io'\n\n }\n const reportLink = `${reportLinkBaseUrl}/${projectId}/run-report/${runId}`\n this.log(`Report link: ${reportLink}\\n`)\n }\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { TableCell } from '@cucumber/messages';
|
|
1
2
|
declare const generateTestData: (featureFileContent: string, vars?: any, fakeData?: {
|
|
2
3
|
var: string;
|
|
3
4
|
fake: string;
|
|
4
|
-
}[]) => {
|
|
5
|
+
}[], projectDir?: string) => {
|
|
5
6
|
newContent: string;
|
|
6
7
|
variables: any;
|
|
7
8
|
otherFakeData: {
|
|
@@ -11,4 +12,12 @@ declare const generateTestData: (featureFileContent: string, vars?: any, fakeDat
|
|
|
11
12
|
changed: boolean;
|
|
12
13
|
fakeIndex: number;
|
|
13
14
|
};
|
|
14
|
-
|
|
15
|
+
declare const generateExamplesFromFunction: (data: string, feature_path: string, functionName: string, functionFile: string) => {
|
|
16
|
+
newData: string;
|
|
17
|
+
mjsData: any;
|
|
18
|
+
};
|
|
19
|
+
declare const generateExamplesFromFunctionGherkin: (headers: readonly TableCell[], values: readonly TableCell[], mjsData: any) => {
|
|
20
|
+
header: string;
|
|
21
|
+
value: any;
|
|
22
|
+
}[];
|
|
23
|
+
export { generateTestData, generateExamplesFromFunction, generateExamplesFromFunctionGherkin, };
|
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateTestData = void 0;
|
|
6
|
+
exports.generateExamplesFromFunctionGherkin = exports.generateExamplesFromFunction = exports.generateTestData = void 0;
|
|
4
7
|
const faker_1 = require("@faker-js/faker");
|
|
5
|
-
const
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const generateTestData = (featureFileContent, vars, fakeData, projectDir) => {
|
|
6
11
|
const regexp = /\{\{([^}]+)\}\}/g;
|
|
7
12
|
const variableRegex = /^([a-zA-Z0-9_]*)=(.*)/g;
|
|
8
13
|
let newContent = featureFileContent;
|
|
9
14
|
let match;
|
|
15
|
+
if (!projectDir) {
|
|
16
|
+
projectDir = process.cwd();
|
|
17
|
+
}
|
|
18
|
+
const namespacePath = path_1.default.join(projectDir, 'features', 'step_definitions', 'namespaces.json');
|
|
19
|
+
let namespaces = fs_1.default.existsSync(namespacePath)
|
|
20
|
+
? JSON.parse(fs_1.default.readFileSync(namespacePath, 'utf-8'))
|
|
21
|
+
: [];
|
|
22
|
+
if (!Array.isArray(namespaces)) {
|
|
23
|
+
namespaces = [];
|
|
24
|
+
}
|
|
10
25
|
const matches = [];
|
|
11
26
|
// collect all matches
|
|
12
27
|
while ((match = regexp.exec(featureFileContent)) !== null) {
|
|
13
|
-
|
|
28
|
+
// match[0] is the full match, match[1] is the first capturing group
|
|
29
|
+
// Eg:- match[0] = {{name}}, match[1] = name
|
|
30
|
+
if (!namespaces.includes(match[1].split('.')[0]))
|
|
31
|
+
matches.push(match);
|
|
14
32
|
}
|
|
15
33
|
// find all variables in the matches
|
|
16
34
|
const variables = { ...vars };
|
|
@@ -53,8 +71,12 @@ const generateTestData = (featureFileContent, vars, fakeData) => {
|
|
|
53
71
|
const duplicateFakeData = fakeData ? [...fakeData] : [];
|
|
54
72
|
let fakeIndex = 0;
|
|
55
73
|
while ((match = regexp.exec(featureFileContent)) !== null) {
|
|
74
|
+
if (namespaces.includes(match[1].split('.')[0]))
|
|
75
|
+
continue;
|
|
56
76
|
try {
|
|
57
|
-
const fake = duplicateFakeData &&
|
|
77
|
+
const fake = duplicateFakeData &&
|
|
78
|
+
duplicateFakeData.length > 0 &&
|
|
79
|
+
duplicateFakeData[0].var === match[0]
|
|
58
80
|
? duplicateFakeData.shift().fake
|
|
59
81
|
: faker_1.faker.helpers.fake(match[0]);
|
|
60
82
|
otherFakeData.push({
|
|
@@ -66,7 +88,7 @@ const generateTestData = (featureFileContent, vars, fakeData) => {
|
|
|
66
88
|
}
|
|
67
89
|
catch (err) {
|
|
68
90
|
// eslint-disable-next-line no-console
|
|
69
|
-
console.log('unknown faker variable:' + match[0])
|
|
91
|
+
//console.log('unknown faker variable:' + match[0])
|
|
70
92
|
}
|
|
71
93
|
}
|
|
72
94
|
return {
|
|
@@ -78,4 +100,55 @@ const generateTestData = (featureFileContent, vars, fakeData) => {
|
|
|
78
100
|
};
|
|
79
101
|
};
|
|
80
102
|
exports.generateTestData = generateTestData;
|
|
103
|
+
const getDefinitionFunction = (feature_path, functionName, functionFile) => {
|
|
104
|
+
const mjsFiles = fs_1.default
|
|
105
|
+
.readdirSync(path_1.default.join(feature_path, '../step_definitions'))
|
|
106
|
+
.filter((file) => file === `${functionFile}.js`);
|
|
107
|
+
if (mjsFiles.length === 0) {
|
|
108
|
+
throw new Error(`File ${functionFile} not found in step_definitions folder`);
|
|
109
|
+
}
|
|
110
|
+
const [mjsData] = mjsFiles.map((file) => {
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
112
|
+
const { [functionName]: func } = require(path_1.default.join(feature_path, '../step_definitions', file));
|
|
113
|
+
if (!func)
|
|
114
|
+
throw new Error(`Function ${functionName} not found in file ${file}`);
|
|
115
|
+
return func();
|
|
116
|
+
});
|
|
117
|
+
return mjsData;
|
|
118
|
+
};
|
|
119
|
+
const generateExamplesFromFunction = (data, feature_path, functionName, functionFile) => {
|
|
120
|
+
const examples = data.split('Examples:')[1].split('\n').slice(1);
|
|
121
|
+
const headers = examples[0]
|
|
122
|
+
.split('|')
|
|
123
|
+
.map((header) => header.trim())
|
|
124
|
+
.filter((header) => header !== '');
|
|
125
|
+
const values = examples[1]
|
|
126
|
+
.split('|')
|
|
127
|
+
.map((value) => value.trim())
|
|
128
|
+
.filter((header) => header !== '');
|
|
129
|
+
const mjsData = getDefinitionFunction(feature_path, functionName, functionFile);
|
|
130
|
+
const newExamples = headers.map((header) => {
|
|
131
|
+
if (mjsData[header]) {
|
|
132
|
+
return mjsData[header];
|
|
133
|
+
}
|
|
134
|
+
return values[headers.indexOf(header)];
|
|
135
|
+
});
|
|
136
|
+
let newExamplesString = data.split('Examples:')[1];
|
|
137
|
+
newExamples.forEach((example, index) => {
|
|
138
|
+
newExamplesString = newExamplesString.replace(values[index], example);
|
|
139
|
+
});
|
|
140
|
+
const newData = data.replace(data.split('Examples:')[1], newExamplesString);
|
|
141
|
+
return { newData, mjsData };
|
|
142
|
+
};
|
|
143
|
+
exports.generateExamplesFromFunction = generateExamplesFromFunction;
|
|
144
|
+
const generateExamplesFromFunctionGherkin = (headers, values, mjsData) => {
|
|
145
|
+
const newExamples = headers.map(({ value: header }, index) => {
|
|
146
|
+
if (mjsData[header]) {
|
|
147
|
+
return { header, value: mjsData[header] };
|
|
148
|
+
}
|
|
149
|
+
return { header, value: values[index].value };
|
|
150
|
+
});
|
|
151
|
+
return newExamples;
|
|
152
|
+
};
|
|
153
|
+
exports.generateExamplesFromFunctionGherkin = generateExamplesFromFunctionGherkin;
|
|
81
154
|
//# sourceMappingURL=feature_data_format.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature_data_format.js","sourceRoot":"","sources":["../../src/formatter/feature_data_format.ts"],"names":[],"mappings":"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","sourcesContent":["import { faker } from '@faker-js/faker'\n\nconst generateTestData = (\n featureFileContent: string,\n vars?: any,\n fakeData?: {\n var: string\n fake: string\n }[]\n) => {\n const regexp = /\\{\\{([^}]+)\\}\\}/g\n const variableRegex = /^([a-zA-Z0-9_]*)=(.*)/g\n let newContent = featureFileContent\n let match: RegExpExecArray\n const matches = []\n // collect all matches\n while ((match = regexp.exec(featureFileContent)) !== null) {\n matches.push(match)\n }\n // find all variables in the matches\n const variables: any = { ...vars }\n\n if (Object.keys(variables).length > 0) {\n for (let i = 0; i < matches.length; i++) {\n const _match = matches[i]\n const value = _match[1]\n const variableMatch = variableRegex.exec(value)\n if (variableMatch !== null) {\n newContent = newContent.replaceAll(_match[0], `{{${variableMatch[1]}}}`)\n }\n }\n\n for (const key in variables) {\n const variable = variables[key]\n newContent = newContent.replaceAll(`{{${variable.var}}}`, variable.fake)\n }\n } else {\n for (let i = 0; i < matches.length; i++) {\n const _match = matches[i]\n const value = _match[1]\n const variableMatch = variableRegex.exec(value)\n if (variableMatch !== null) {\n variables[variableMatch[1]] = {\n var: variableMatch[1],\n toFake: variableMatch[2],\n }\n newContent = newContent.replaceAll(_match[0], `{{${variableMatch[1]}}}`)\n }\n }\n\n for (const key in variables) {\n const variable = variables[key]\n const fake = faker.helpers.fake(`{{${variable.toFake}}}`)\n newContent = newContent.replaceAll(`{{${variable.var}}}`, fake)\n variables[key].fake = fake\n }\n }\n\n regexp.lastIndex = 0\n const otherFakeData = []\n const duplicateFakeData = fakeData ? [...fakeData] : []\n let fakeIndex = 0\n\n while ((match = regexp.exec(featureFileContent)) !== null) {\n try {\n const fake =\n duplicateFakeData && duplicateFakeData.length > 0\n ? duplicateFakeData.shift().fake\n : faker.helpers.fake(match[0])\n otherFakeData.push({\n var: match[0],\n fake,\n })\n newContent = newContent.replace(match[0], fake)\n fakeIndex++\n } catch (err) {\n // eslint-disable-next-line no-console\n console.log('unknown faker variable:' + match[0])\n }\n }\n\n return {\n newContent,\n variables,\n otherFakeData,\n changed: newContent !== featureFileContent,\n fakeIndex,\n }\n}\n\n//let result = generateTestData(\"/Users/guyarieli/Documents/GitHub/ai-qa/cucumber_demo/features/create_issues.feature\");\n//console.log(result.newContent);\nexport { generateTestData }\n"]}
|
|
1
|
+
{"version":3,"file":"feature_data_format.js","sourceRoot":"","sources":["../../src/formatter/feature_data_format.ts"],"names":[],"mappings":"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","sourcesContent":["import { faker } from '@faker-js/faker'\nimport fs from 'fs'\nimport path from 'path'\nimport { TableCell } from '@cucumber/messages'\n\nconst generateTestData = (\n featureFileContent: string,\n vars?: any,\n fakeData?: {\n var: string\n fake: string\n }[],\n projectDir?: string\n) => {\n const regexp = /\\{\\{([^}]+)\\}\\}/g\n const variableRegex = /^([a-zA-Z0-9_]*)=(.*)/g\n let newContent = featureFileContent\n let match: RegExpExecArray\n if (!projectDir) {\n projectDir = process.cwd()\n }\n const namespacePath = path.join(\n projectDir,\n 'features',\n 'step_definitions',\n 'namespaces.json'\n )\n let namespaces: string[] = fs.existsSync(namespacePath)\n ? JSON.parse(fs.readFileSync(namespacePath, 'utf-8'))\n : []\n if (!Array.isArray(namespaces)) {\n namespaces = []\n }\n const matches = []\n // collect all matches\n while ((match = regexp.exec(featureFileContent)) !== null) {\n // match[0] is the full match, match[1] is the first capturing group\n // Eg:- match[0] = {{name}}, match[1] = name\n if (!namespaces.includes(match[1].split('.')[0])) matches.push(match)\n }\n // find all variables in the matches\n const variables: any = { ...vars }\n\n if (Object.keys(variables).length > 0) {\n for (let i = 0; i < matches.length; i++) {\n const _match = matches[i]\n const value = _match[1]\n const variableMatch = variableRegex.exec(value)\n if (variableMatch !== null) {\n newContent = newContent.replaceAll(_match[0], `{{${variableMatch[1]}}}`)\n }\n }\n\n for (const key in variables) {\n const variable = variables[key]\n newContent = newContent.replaceAll(`{{${variable.var}}}`, variable.fake)\n }\n } else {\n for (let i = 0; i < matches.length; i++) {\n const _match = matches[i]\n const value = _match[1]\n const variableMatch = variableRegex.exec(value)\n if (variableMatch !== null) {\n variables[variableMatch[1]] = {\n var: variableMatch[1],\n toFake: variableMatch[2],\n }\n newContent = newContent.replaceAll(_match[0], `{{${variableMatch[1]}}}`)\n }\n }\n\n for (const key in variables) {\n const variable = variables[key]\n const fake = faker.helpers.fake(`{{${variable.toFake}}}`)\n newContent = newContent.replaceAll(`{{${variable.var}}}`, fake)\n variables[key].fake = fake\n }\n }\n\n regexp.lastIndex = 0\n const otherFakeData = []\n const duplicateFakeData = fakeData ? [...fakeData] : []\n let fakeIndex = 0\n while ((match = regexp.exec(featureFileContent)) !== null) {\n if (namespaces.includes(match[1].split('.')[0])) continue\n try {\n const fake =\n duplicateFakeData &&\n duplicateFakeData.length > 0 &&\n duplicateFakeData[0].var === match[0]\n ? duplicateFakeData.shift().fake\n : faker.helpers.fake(match[0])\n otherFakeData.push({\n var: match[0],\n fake,\n })\n newContent = newContent.replace(match[0], fake)\n fakeIndex++\n } catch (err) {\n // eslint-disable-next-line no-console\n //console.log('unknown faker variable:' + match[0])\n }\n }\n\n return {\n newContent,\n variables,\n otherFakeData,\n changed: newContent !== featureFileContent,\n fakeIndex,\n }\n}\n\nconst getDefinitionFunction = (\n feature_path: string,\n functionName: string,\n functionFile: string\n) => {\n const mjsFiles = fs\n .readdirSync(path.join(feature_path, '../step_definitions'))\n .filter((file) => file === `${functionFile}.js`)\n\n if (mjsFiles.length === 0) {\n throw new Error(`File ${functionFile} not found in step_definitions folder`)\n }\n\n const [mjsData] = mjsFiles.map((file) => {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { [functionName]: func } = require(path.join(\n feature_path,\n '../step_definitions',\n file\n ))\n if (!func)\n throw new Error(`Function ${functionName} not found in file ${file}`)\n\n return func()\n })\n\n return mjsData\n}\n\nconst generateExamplesFromFunction = (\n data: string,\n feature_path: string,\n functionName: string,\n functionFile: string\n) => {\n const examples = data.split('Examples:')[1].split('\\n').slice(1)\n const headers = examples[0]\n .split('|')\n .map((header) => header.trim())\n .filter((header) => header !== '')\n const values = examples[1]\n .split('|')\n .map((value) => value.trim())\n .filter((header) => header !== '')\n\n const mjsData = getDefinitionFunction(\n feature_path,\n functionName,\n functionFile\n )\n\n const newExamples = headers.map((header) => {\n if (mjsData[header]) {\n return mjsData[header]\n }\n return values[headers.indexOf(header)]\n })\n\n let newExamplesString = data.split('Examples:')[1]\n newExamples.forEach((example, index) => {\n newExamplesString = newExamplesString.replace(values[index], example)\n })\n\n const newData = data.replace(data.split('Examples:')[1], newExamplesString)\n\n return { newData, mjsData }\n}\n\nconst generateExamplesFromFunctionGherkin = (\n headers: readonly TableCell[],\n values: readonly TableCell[],\n mjsData: any\n) => {\n const newExamples = headers.map(({ value: header }, index) => {\n if (mjsData[header]) {\n return { header, value: mjsData[header] }\n }\n return { header, value: values[index].value }\n })\n\n return newExamples\n}\n\nexport {\n generateTestData,\n generateExamplesFromFunction,\n generateExamplesFromFunctionGherkin,\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as messages from '@cucumber/messages';
|
|
2
2
|
type JsonTimestamp = number;
|
|
3
|
-
type JsonStepType = 'Unknown' | 'Context' | 'Action' | 'Outcome';
|
|
3
|
+
type JsonStepType = 'Unknown' | 'Context' | 'Action' | 'Outcome' | 'Conjunction';
|
|
4
4
|
export type JsonResultUnknown = {
|
|
5
5
|
status: 'UNKNOWN';
|
|
6
6
|
};
|
|
@@ -48,12 +48,22 @@ type JsonCommand = {
|
|
|
48
48
|
text: string;
|
|
49
49
|
screenshotId?: string;
|
|
50
50
|
result: JsonCommandResult;
|
|
51
|
+
webLog?: webLog[];
|
|
52
|
+
netWorkLog?: any[];
|
|
53
|
+
};
|
|
54
|
+
type webLog = {
|
|
55
|
+
type: string;
|
|
56
|
+
text: string;
|
|
57
|
+
location: string;
|
|
58
|
+
time: string;
|
|
51
59
|
};
|
|
52
60
|
export type JsonStep = {
|
|
61
|
+
keyword: string;
|
|
53
62
|
type: JsonStepType;
|
|
54
63
|
text: string;
|
|
55
64
|
commands: JsonCommand[];
|
|
56
65
|
result: JsonStepResult;
|
|
66
|
+
data?: any;
|
|
57
67
|
};
|
|
58
68
|
export type RetrainStats = {
|
|
59
69
|
result: JsonTestResult;
|
|
@@ -70,19 +80,29 @@ export type JsonTestProgress = {
|
|
|
70
80
|
steps: JsonStep[];
|
|
71
81
|
result: JsonTestResult;
|
|
72
82
|
retrainStats?: RetrainStats;
|
|
83
|
+
webLog: any;
|
|
84
|
+
networkLog: any;
|
|
73
85
|
};
|
|
74
86
|
export type JsonReport = {
|
|
75
87
|
testCases: JsonTestProgress[];
|
|
76
88
|
result: JsonReportResult;
|
|
89
|
+
env: {
|
|
90
|
+
name: string;
|
|
91
|
+
baseUrl: string;
|
|
92
|
+
};
|
|
77
93
|
};
|
|
78
94
|
export default class ReportGenerator {
|
|
79
95
|
private report;
|
|
80
96
|
private gherkinDocumentMap;
|
|
97
|
+
private stepMap;
|
|
81
98
|
private pickleMap;
|
|
82
99
|
private testCaseMap;
|
|
83
100
|
private testStepMap;
|
|
84
|
-
private
|
|
85
|
-
private
|
|
101
|
+
private stepReportMap;
|
|
102
|
+
private testCaseReportMap;
|
|
103
|
+
private scenarioIterationCountMap;
|
|
104
|
+
private logs;
|
|
105
|
+
private networkLog;
|
|
86
106
|
reportFolder: null | string;
|
|
87
107
|
handleMessage(envelope: messages.Envelope): void;
|
|
88
108
|
getReport(): JsonReport;
|
|
@@ -92,10 +112,13 @@ export default class ReportGenerator {
|
|
|
92
112
|
private getTimeStamp;
|
|
93
113
|
private onTestRunStarted;
|
|
94
114
|
private onTestCase;
|
|
115
|
+
private _findScenario;
|
|
116
|
+
private _getParameters;
|
|
95
117
|
private onTestCaseStarted;
|
|
96
118
|
private onTestStepStarted;
|
|
97
119
|
private onAttachment;
|
|
98
120
|
private onTestStepFinished;
|
|
121
|
+
getLogFileContent(): any;
|
|
99
122
|
private getTestCaseResult;
|
|
100
123
|
private onTestCaseFinished;
|
|
101
124
|
private onTestRunFinished;
|