@dev-blinq/cucumber-js 1.0.102-dev → 1.0.102
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 +22 -2
- package/lib/configuration/axios_client.js +1 -1
- package/lib/configuration/axios_client.js.map +1 -1
- package/lib/formatter/api.js +7 -1
- package/lib/formatter/api.js.map +1 -1
- package/lib/formatter/bvt_analysis_formatter.d.ts +12 -1
- package/lib/formatter/bvt_analysis_formatter.js +170 -74
- package/lib/formatter/bvt_analysis_formatter.js.map +1 -1
- package/lib/formatter/feature_data_format.js +4 -1
- package/lib/formatter/feature_data_format.js.map +1 -1
- package/lib/formatter/helpers/constants.d.ts +50 -0
- package/lib/formatter/helpers/constants.js +60 -0
- package/lib/formatter/helpers/constants.js.map +1 -0
- package/lib/formatter/helpers/report_generator.d.ts +25 -2
- package/lib/formatter/helpers/report_generator.js +233 -13
- 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 +14 -0
- package/lib/formatter/helpers/upload_serivce.js +117 -0
- 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 +17 -2
- 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 +2 -2
package/bin/download-install.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
/* eslint-disable no-undef */
|
|
1
4
|
const { argv } = require('node:process')
|
|
2
5
|
const fs = require('fs')
|
|
3
6
|
const path = require('path')
|
|
@@ -16,8 +19,14 @@ const getSSoUrl = () => {
|
|
|
16
19
|
return 'https://dev.api.blinq.io/api/auth'
|
|
17
20
|
case 'stage':
|
|
18
21
|
return 'https://stage.api.blinq.io/api/auth'
|
|
19
|
-
|
|
22
|
+
case 'prod':
|
|
23
|
+
return 'https://api.blinq.io/api/auth'
|
|
24
|
+
case null:
|
|
25
|
+
return 'https://api.blinq.io/api/auth'
|
|
26
|
+
case undefined:
|
|
20
27
|
return 'https://api.blinq.io/api/auth'
|
|
28
|
+
default:
|
|
29
|
+
return `${process.env.NODE_ENV_BLINQ}/api/auth`
|
|
21
30
|
}
|
|
22
31
|
}
|
|
23
32
|
|
|
@@ -48,8 +57,14 @@ const getWorkSpaceUrl = () => {
|
|
|
48
57
|
return 'https://dev.api.blinq.io/api/workspace'
|
|
49
58
|
case "stage":
|
|
50
59
|
return 'https://stage.api.blinq.io/api/workspace'
|
|
51
|
-
|
|
60
|
+
case 'prod':
|
|
61
|
+
return 'https://api.blinq.io/api/workspace'
|
|
62
|
+
case null:
|
|
52
63
|
return 'https://api.blinq.io/api/workspace'
|
|
64
|
+
case undefined:
|
|
65
|
+
return 'https://api.blinq.io/api/workspace'
|
|
66
|
+
default:
|
|
67
|
+
return `${process.env.NODE_ENV_BLINQ}/api/workspace`
|
|
53
68
|
}
|
|
54
69
|
}
|
|
55
70
|
|
|
@@ -137,6 +152,11 @@ const downloadAndInstall = async (extractPath, token) => {
|
|
|
137
152
|
},
|
|
138
153
|
})
|
|
139
154
|
|
|
155
|
+
if (res.status !== 200) {
|
|
156
|
+
console.error('Error: Unable to fetch workspace')
|
|
157
|
+
process.exit(1)
|
|
158
|
+
}
|
|
159
|
+
|
|
140
160
|
const zip = await JSZip.loadAsync(res.data)
|
|
141
161
|
for (const filename of Object.keys(zip.files)) {
|
|
142
162
|
const fileData = zip.files[filename]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axios_client.js","sourceRoot":"","sources":["../../src/configuration/axios_client.ts"],"names":[],"mappings":";;;;;;AAAA,+BAA+B;AAC/B,kDAAyB;AACzB,oDAA6C;AAG7C,MAAM,QAAQ,GAAG,GAAiB,EAAE;IAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE;QACtB,OAAO,IAAI,CAAA;KACZ;IAED,MAAM,KAAK,GAAkB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAA;IAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,WAAW,GAAiB;QAChC,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;KACvB,CAAA;IAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;IAElC,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,WAAW,CAAC,SAAS,GAAG,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAA;KAClD;IACD,OAAO,gBAAM,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;AACrD,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,GAAG,EAAE;IAC7B,IAAI;QACF,MAAM,KAAK,GAAmB,QAAQ,EAAE,CAAA;QACxC,OAAO,eAAK,CAAC,MAAM,CAAC;YAClB,
|
|
1
|
+
{"version":3,"file":"axios_client.js","sourceRoot":"","sources":["../../src/configuration/axios_client.ts"],"names":[],"mappings":";;;;;;AAAA,+BAA+B;AAC/B,kDAAyB;AACzB,oDAA6C;AAG7C,MAAM,QAAQ,GAAG,GAAiB,EAAE;IAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE;QACtB,OAAO,IAAI,CAAA;KACZ;IAED,MAAM,KAAK,GAAkB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAA;IAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,WAAW,GAAiB;QAChC,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;KACvB,CAAA;IAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;IAElC,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,WAAW,CAAC,SAAS,GAAG,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAA;KAClD;IACD,OAAO,gBAAM,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;AACrD,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,GAAG,EAAE;IAC7B,IAAI;QACF,MAAM,KAAK,GAAmB,QAAQ,EAAE,CAAA;QACxC,OAAO,eAAK,CAAC,MAAM,CAAC;YAClB,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,KAAK;SACb,CAAC,CAAA;KACH;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC1B,MAAM,IAAI,KAAK,CACb,+BACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAC1D,EAAE,CACH,CAAA;KACF;AACH,CAAC,CAAA;AAEY,QAAA,WAAW,GAAG,iBAAiB,EAAE,CAAA","sourcesContent":["/* eslint-disable no-console */\nimport axios from 'axios'\nimport tunnel, { ProxyOptions } from 'tunnel'\nimport { Agent } from 'http'\n\nconst getProxy = (): Agent | null => {\n if (!process.env.PROXY) {\n return null\n }\n\n const proxy: string | null = process.env.PROXY\n const url = new URL(proxy)\n const proxyObject: ProxyOptions = {\n host: url.hostname,\n port: Number(url.port),\n }\n\n const { username, password } = url\n\n if (username && password) {\n proxyObject.proxyAuth = `${username}:${password}`\n }\n return tunnel.httpsOverHttp({ proxy: proxyObject })\n}\n\nconst createAxiosClient = () => {\n try {\n const agent: string | Agent = getProxy()\n return axios.create({\n httpsAgent: agent,\n proxy: false,\n })\n } catch (error) {\n console.log(error.message)\n throw new Error(\n `Error creating axios client ${\n error instanceof Error ? error.message : error.response.data\n }`\n )\n }\n}\n\nexport const axiosClient = createAxiosClient()\n"]}
|
package/lib/formatter/api.js
CHANGED
|
@@ -14,8 +14,14 @@ const getSSoUrl = () => {
|
|
|
14
14
|
return 'https://dev.api.blinq.io/api/auth';
|
|
15
15
|
case 'stage':
|
|
16
16
|
return 'https://stage.api.blinq.io/api/auth';
|
|
17
|
-
|
|
17
|
+
case 'prod':
|
|
18
|
+
return 'https://api.blinq.io/api/auth';
|
|
19
|
+
case null:
|
|
18
20
|
return 'https://api.blinq.io/api/auth';
|
|
21
|
+
case undefined:
|
|
22
|
+
return 'https://api.blinq.io/api/auth';
|
|
23
|
+
default:
|
|
24
|
+
return `${process.env.NODE_ENV_BLINQ}/api/auth`;
|
|
19
25
|
}
|
|
20
26
|
};
|
|
21
27
|
const getProxy = () => {
|
package/lib/formatter/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/formatter/api.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AACzB,oDAA2B;AAE3B,MAAM,SAAS,GAAG,GAAG,EAAE;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/formatter/api.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AACzB,oDAA2B;AAE3B,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,QAAQ,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE;QAClC,KAAK,OAAO;YACV,OAAO,gCAAgC,CAAA;QACzC,KAAK,KAAK;YACR,OAAO,mCAAmC,CAAA;QAC5C,KAAK,OAAO;YACV,OAAO,qCAAqC,CAAA;QAC9C,KAAK,MAAM;YACT,OAAO,+BAA+B,CAAA;QACxC,KAAK,IAAI;YACP,OAAO,+BAA+B,CAAA;QACxC,KAAK,SAAS;YACZ,OAAO,+BAA+B,CAAA;QACxC;YACE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,WAAW,CAAA;KAClD;AACH,CAAC,CAAA;AACD,MAAM,QAAQ,GAAG,GAAG,EAAE;IACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE;QACtB,OAAO,IAAI,CAAA;KACZ;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAA;IAC/B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,WAAW,GAAG;QAClB,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;KACvB,CAAA;IAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;IAElC,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,YAAY;QACZ,WAAW,CAAC,SAAS,GAAG,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAA;KAClD;IACD,OAAO,gBAAM,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;AACrD,CAAC,CAAA;AAED,MAAM,qBAAqB,GAAG,KAAK,EAAE,UAAkB,EAAE,EAAE;IACzD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,YAAY,GAAG,GAAG,MAAM,wBAAwB,CAAA;IACtD,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,IAAI,CAAC,YAAY,EAAE;QAC9C,UAAU;QACV,SAAS,EAAE,QAAQ,EAAE;QACrB,KAAK,EAAE,KAAK;KACb,CAAC,CAAA;IACF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;QAC3B,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAA;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAChB;IACD,OAAO,QAAQ,CAAC,IAAI,CAAA;AACtB,CAAC,CAAA;AAEQ,sDAAqB","sourcesContent":["import axios from 'axios'\nimport tunnel from 'tunnel'\n\nconst getSSoUrl = () => {\n switch (process.env.NODE_ENV_BLINQ) {\n case 'local':\n return 'http://localhost:5000/api/auth'\n case 'dev':\n return 'https://dev.api.blinq.io/api/auth'\n case 'stage':\n return 'https://stage.api.blinq.io/api/auth'\n case 'prod':\n return 'https://api.blinq.io/api/auth'\n case null:\n return 'https://api.blinq.io/api/auth'\n case undefined:\n return 'https://api.blinq.io/api/auth'\n default:\n return `${process.env.NODE_ENV_BLINQ}/api/auth`\n }\n}\nconst getProxy = () => {\n if (!process.env.PROXY) {\n return null\n }\n\n const proxy = process.env.PROXY\n const url = new URL(proxy)\n const proxyObject = {\n host: url.hostname,\n port: Number(url.port),\n }\n\n const { username, password } = url\n\n if (username && password) {\n //@ts-ignore\n proxyObject.proxyAuth = `${username}:${password}`\n }\n return tunnel.httpsOverHttp({ proxy: proxyObject })\n}\n\nconst getProjectByAccessKey = async (access_key: string) => {\n const ssoUrl = getSSoUrl()\n const accessKeyUrl = `${ssoUrl}/getProjectByAccessKey`\n const response = await axios.post(accessKeyUrl, {\n access_key,\n httpAgent: getProxy(),\n proxy: false,\n })\n if (response.status !== 200) {\n console.error('Error: Invalid access key')\n process.exit(1)\n }\n return response.data\n}\n\nexport { getProjectByAccessKey }\n"]}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import Formatter, { IFormatterOptions } from '.';
|
|
2
|
+
import ReportGenerator from './helpers/report_generator';
|
|
2
3
|
export default class BVTAnalysisFormatter extends Formatter {
|
|
4
|
+
static reportGenerator: ReportGenerator;
|
|
5
|
+
static reRunFailedStepsIndex: {
|
|
6
|
+
testCaseId: string;
|
|
7
|
+
failedStepIndex: number;
|
|
8
|
+
}[] | null;
|
|
3
9
|
private reportGenerator;
|
|
4
10
|
private uploader;
|
|
5
11
|
private exit;
|
|
6
12
|
private START;
|
|
7
13
|
private runName;
|
|
14
|
+
private failedStepsIndex;
|
|
15
|
+
private summaryFormatter;
|
|
16
|
+
private rootCauseArray;
|
|
8
17
|
constructor(options: IFormatterOptions);
|
|
18
|
+
private sendEvent;
|
|
9
19
|
private uploadReport;
|
|
10
20
|
finished(): Promise<any>;
|
|
11
21
|
private analyzeReport;
|
|
@@ -13,7 +23,8 @@ export default class BVTAnalysisFormatter extends Formatter {
|
|
|
13
23
|
private processTestCase;
|
|
14
24
|
private uploadFinalReport;
|
|
15
25
|
private retrain;
|
|
26
|
+
private rerun;
|
|
16
27
|
private call_cucumber_client;
|
|
17
|
-
private logReportLink;
|
|
18
28
|
private getAppDataDir;
|
|
19
29
|
}
|
|
30
|
+
export declare function logReportLink(runId: string, projectId: string): void;
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.logReportLink = void 0;
|
|
6
7
|
const child_process_1 = require("child_process");
|
|
7
8
|
const fs_1 = require("fs");
|
|
8
9
|
const promises_1 = require("fs/promises");
|
|
@@ -14,6 +15,11 @@ const report_generator_1 = __importDefault(require("./helpers/report_generator")
|
|
|
14
15
|
const uploader_1 = __importDefault(require("./helpers/uploader"));
|
|
15
16
|
const os_1 = __importDefault(require("os"));
|
|
16
17
|
const api_1 = require("./api");
|
|
18
|
+
const summary_formatter_1 = __importDefault(require("./summary_formatter"));
|
|
19
|
+
const constants_1 = require("./helpers/constants");
|
|
20
|
+
const axios_client_1 = require("../configuration/axios_client");
|
|
21
|
+
const util_1 = require("util");
|
|
22
|
+
const child_process_2 = require("child_process");
|
|
17
23
|
//User token
|
|
18
24
|
const TOKEN = process.env.TOKEN;
|
|
19
25
|
class BVTAnalysisFormatter extends _1.default {
|
|
@@ -22,28 +28,62 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
22
28
|
this.reportGenerator = new report_generator_1.default();
|
|
23
29
|
this.uploader = new uploader_1.default(this.reportGenerator);
|
|
24
30
|
this.exit = false;
|
|
31
|
+
this.rootCauseArray = [];
|
|
32
|
+
this.summaryFormatter = new summary_formatter_1.default(options);
|
|
33
|
+
BVTAnalysisFormatter.reportGenerator = this.reportGenerator;
|
|
34
|
+
this.rootCauseArray = [];
|
|
35
|
+
this.failedStepsIndex = [];
|
|
36
|
+
BVTAnalysisFormatter.reRunFailedStepsIndex = process.env.RERUN
|
|
37
|
+
? JSON.parse(process.env.RERUN)
|
|
38
|
+
: null;
|
|
25
39
|
if (!TOKEN && process.env.BVT_FORMATTER === 'ANALYSIS') {
|
|
26
40
|
throw new Error('TOKEN must be set');
|
|
27
41
|
}
|
|
28
|
-
|
|
29
|
-
|
|
42
|
+
this.sendEvent(constants_1.ActionEvents.cli_run_tests);
|
|
43
|
+
options.eventBroadcaster.on('envelope', async (envelope, data) => {
|
|
44
|
+
if ((0, value_checker_1.doesHaveValue)(envelope.testCaseFinished) && data) {
|
|
45
|
+
const { rootCause, report } = data;
|
|
46
|
+
if (!rootCause.status) {
|
|
47
|
+
console.error(`Root cause: ${rootCause.failClass}\n, ${rootCause.analysis}\nfailing step: ${rootCause.failedStep}`);
|
|
48
|
+
this.rootCauseArray.push({ rootCause, report });
|
|
49
|
+
this.failedStepsIndex.push({
|
|
50
|
+
testCaseId: report.id,
|
|
51
|
+
failedStepIndex: rootCause.failedStep,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
await this.reportGenerator.handleMessage(envelope);
|
|
30
57
|
if ((0, value_checker_1.doesHaveValue)(envelope.meta) &&
|
|
31
58
|
(0, value_checker_1.doesHaveValue)(envelope.meta.runName)) {
|
|
32
59
|
this.runName = envelope.meta.runName;
|
|
33
60
|
}
|
|
34
61
|
if ((0, value_checker_1.doesHaveValue)(envelope.testRunFinished)) {
|
|
35
|
-
const report = this.reportGenerator.getReport();
|
|
36
62
|
this.START = Date.now();
|
|
37
63
|
if (process.env.BVT_FORMATTER === 'ANALYSIS') {
|
|
38
|
-
await this.analyzeReport(
|
|
64
|
+
await this.analyzeReport();
|
|
39
65
|
}
|
|
40
66
|
else {
|
|
41
|
-
await this.uploadReport(report)
|
|
67
|
+
// await this.uploadReport(report)
|
|
42
68
|
}
|
|
43
69
|
this.exit = true;
|
|
44
70
|
}
|
|
45
71
|
});
|
|
46
72
|
}
|
|
73
|
+
sendEvent(event) {
|
|
74
|
+
axios_client_1.axiosClient
|
|
75
|
+
.post(`${constants_1.SERVICES_URI.STORAGE}/event`, {
|
|
76
|
+
event,
|
|
77
|
+
}, {
|
|
78
|
+
headers: {
|
|
79
|
+
Authorization: `Bearer ${TOKEN}`,
|
|
80
|
+
'x-source': 'cucumber_js',
|
|
81
|
+
},
|
|
82
|
+
})
|
|
83
|
+
.catch((err) => {
|
|
84
|
+
// Error with events, ignoring
|
|
85
|
+
});
|
|
86
|
+
}
|
|
47
87
|
async uploadReport(report) {
|
|
48
88
|
const uploadSuccessful = await this.uploadFinalReport(report);
|
|
49
89
|
if (uploadSuccessful && report.result.status !== 'FAILED') {
|
|
@@ -54,83 +94,80 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
54
94
|
async finished() {
|
|
55
95
|
await new Promise((resolve) => {
|
|
56
96
|
const checkInterval = setInterval(() => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
97
|
+
let anyRem;
|
|
98
|
+
if (process.env.UPLOADING_TEST_CASE) {
|
|
99
|
+
anyRem = JSON.parse(process.env.UPLOADING_TEST_CASE);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
anyRem = undefined;
|
|
103
|
+
}
|
|
104
|
+
if (this.exit && (!anyRem || anyRem.length === 0)) {
|
|
105
|
+
// clearInterval(checkInterval)
|
|
106
|
+
// resolve(null)
|
|
107
|
+
if (this.reportGenerator.getReport().result.status === 'FAILED') {
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
process.exit(0);
|
|
112
|
+
}
|
|
60
113
|
}
|
|
61
114
|
}, 100); // check every 100ms
|
|
62
115
|
});
|
|
63
116
|
}
|
|
64
|
-
async analyzeReport(
|
|
65
|
-
if (
|
|
117
|
+
async analyzeReport() {
|
|
118
|
+
if (this.rootCauseArray.length === 0 ||
|
|
66
119
|
process.env.NO_RETRAIN === 'false') {
|
|
67
|
-
if (
|
|
120
|
+
if (this.rootCauseArray.length === 0) {
|
|
68
121
|
this.log('No test failed. No need to retrain\n');
|
|
69
122
|
}
|
|
70
123
|
if (process.env.NO_RETRAIN === 'false') {
|
|
71
124
|
this.log('Retraining is skipped since the failed step contains an API request\n');
|
|
72
125
|
}
|
|
73
|
-
const uploadSuccessful = await this.uploadFinalReport(report)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
process.exit(1);
|
|
126
|
+
// const uploadSuccessful = await this.uploadFinalReport(report)
|
|
127
|
+
// process.exit(0)
|
|
128
|
+
this.exit = true;
|
|
129
|
+
return;
|
|
78
130
|
}
|
|
79
131
|
//checking if the type of report.result is JsonResultFailed or not
|
|
80
132
|
this.log('Some tests failed, starting the retraining...\n');
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
await this.uploadFinalReport(report);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const finalReport = await this.processTestCases(report);
|
|
87
|
-
const uploadSuccessful = await this.uploadFinalReport(finalReport);
|
|
88
|
-
if (finalReport.result.status !== 'FAILED' && uploadSuccessful) {
|
|
89
|
-
process.exit(0);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
133
|
+
await this.processTestCases();
|
|
134
|
+
if (this.reportGenerator.getReport().result.status === 'FAILED') {
|
|
92
135
|
process.exit(1);
|
|
93
136
|
}
|
|
137
|
+
process.exit(0);
|
|
94
138
|
}
|
|
95
|
-
async processTestCases(
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
const modifiedTestCase = await this.processTestCase(testCase, report);
|
|
99
|
-
finalTestCases.push(modifiedTestCase);
|
|
139
|
+
async processTestCases() {
|
|
140
|
+
for (const { rootCause, report } of this.rootCauseArray) {
|
|
141
|
+
await this.processTestCase(rootCause, report);
|
|
100
142
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
async processTestCase(testCase, report) {
|
|
114
|
-
if (testCase.result.status === 'PASSED') {
|
|
115
|
-
return testCase;
|
|
143
|
+
}
|
|
144
|
+
async processTestCase(rootCause, report) {
|
|
145
|
+
const failedTestSteps = rootCause.failedStep;
|
|
146
|
+
if (BVTAnalysisFormatter.reRunFailedStepsIndex &&
|
|
147
|
+
BVTAnalysisFormatter.reRunFailedStepsIndex.length > 0) {
|
|
148
|
+
const previousRun = BVTAnalysisFormatter.reRunFailedStepsIndex[0];
|
|
149
|
+
if (previousRun.failedStepIndex === failedTestSteps) {
|
|
150
|
+
console.log('Same step has failed again, skipping retraining');
|
|
151
|
+
BVTAnalysisFormatter.reRunFailedStepsIndex.shift();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
BVTAnalysisFormatter.reRunFailedStepsIndex.shift();
|
|
116
155
|
}
|
|
117
|
-
const
|
|
118
|
-
.map((step, i) => (step.result.status === 'FAILED' ? i : null))
|
|
119
|
-
.filter((i) => i !== null);
|
|
120
|
-
const retrainStats = await this.retrain(failedTestSteps, testCase);
|
|
156
|
+
const retrainStats = await this.retrain(failedTestSteps, report);
|
|
121
157
|
if (!retrainStats) {
|
|
122
|
-
return
|
|
158
|
+
return;
|
|
123
159
|
}
|
|
124
|
-
|
|
125
|
-
...
|
|
160
|
+
await this.uploader.modifyTestCase({
|
|
161
|
+
...report,
|
|
126
162
|
retrainStats,
|
|
127
|
-
};
|
|
163
|
+
});
|
|
164
|
+
await this.rerun(report);
|
|
128
165
|
}
|
|
129
166
|
async uploadFinalReport(finalReport) {
|
|
130
167
|
let success = true;
|
|
131
168
|
try {
|
|
132
169
|
const { projectId, runId } = await this.uploader.uploadRun(finalReport, this.runName);
|
|
133
|
-
|
|
170
|
+
logReportLink(runId, projectId);
|
|
134
171
|
}
|
|
135
172
|
catch (err) {
|
|
136
173
|
this.log('Error uploading report\n');
|
|
@@ -141,7 +178,7 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
141
178
|
}
|
|
142
179
|
finally {
|
|
143
180
|
try {
|
|
144
|
-
(0, fs_1.writeFileSync)(path_1.default.join(this.reportGenerator.reportFolder,
|
|
181
|
+
(0, fs_1.writeFileSync)(path_1.default.join(this.reportGenerator.reportFolder, 'report.json'), JSON.stringify(finalReport, null, 2), 'utf-8');
|
|
145
182
|
}
|
|
146
183
|
catch (e) {
|
|
147
184
|
console.error('failed to write report.json to local disk');
|
|
@@ -159,6 +196,37 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
159
196
|
}
|
|
160
197
|
return await this.call_cucumber_client(failedTestCases, testCase);
|
|
161
198
|
}
|
|
199
|
+
async rerun(report) {
|
|
200
|
+
await new Promise((resolve) => {
|
|
201
|
+
const node_path = process.argv.shift();
|
|
202
|
+
const args = [
|
|
203
|
+
path_1.default.join(process.cwd(), 'node_modules', '@dev-blinq', 'cucumber-js', 'bin', 'cucumber.js'),
|
|
204
|
+
'--name',
|
|
205
|
+
`^${report.scenarioName}$`,
|
|
206
|
+
'--exit',
|
|
207
|
+
'--format',
|
|
208
|
+
'bvt',
|
|
209
|
+
'--run-name',
|
|
210
|
+
`${report.scenarioName}@debug`,
|
|
211
|
+
path_1.default.join(process.cwd(), 'features', `${report.featureName}.feature`),
|
|
212
|
+
];
|
|
213
|
+
const cucumberClient = (0, child_process_1.spawn)(node_path, args, {
|
|
214
|
+
env: {
|
|
215
|
+
...process.env,
|
|
216
|
+
RERUN: JSON.stringify(this.failedStepsIndex),
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
cucumberClient.stdout.on('data', (data) => {
|
|
220
|
+
console.log(data.toString());
|
|
221
|
+
});
|
|
222
|
+
cucumberClient.stderr.on('data', (data) => {
|
|
223
|
+
console.error(data.toString());
|
|
224
|
+
});
|
|
225
|
+
cucumberClient.on('close', () => {
|
|
226
|
+
resolve();
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
}
|
|
162
230
|
async call_cucumber_client(stepsToRetrain, testCase) {
|
|
163
231
|
return new Promise((resolve, reject) => {
|
|
164
232
|
const cucumber_client_path = path_1.default.resolve(process.cwd(), 'node_modules', '@dev-blinq', 'cucumber_client', 'bin', 'client', 'cucumber.js');
|
|
@@ -167,7 +235,7 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
167
235
|
path_1.default.join(process.cwd(), testCase.uri),
|
|
168
236
|
`${testCase.scenarioName}`,
|
|
169
237
|
'undefined',
|
|
170
|
-
`${stepsToRetrain
|
|
238
|
+
`${stepsToRetrain},`,
|
|
171
239
|
];
|
|
172
240
|
if (process.env.BLINQ_ENV) {
|
|
173
241
|
args.push(`--env=${process.env.BLINQ_ENV}`);
|
|
@@ -185,7 +253,6 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
185
253
|
const cucumberClient = (0, child_process_1.spawn)('node', [cucumber_client_path, ...args], {
|
|
186
254
|
env: {
|
|
187
255
|
...process.env,
|
|
188
|
-
TEMP_FILE_PATH: tempFile,
|
|
189
256
|
},
|
|
190
257
|
});
|
|
191
258
|
cucumberClient.stdout.on('data', (data) => {
|
|
@@ -203,26 +270,21 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
203
270
|
}
|
|
204
271
|
else {
|
|
205
272
|
this.log('Error retraining\n');
|
|
206
|
-
|
|
273
|
+
try {
|
|
274
|
+
const reportData = (0, fs_1.readFileSync)(tempFile, 'utf-8');
|
|
275
|
+
const retrainStats = JSON.parse(reportData);
|
|
276
|
+
await (0, promises_1.unlink)(tempFile);
|
|
277
|
+
resolve(retrainStats);
|
|
278
|
+
}
|
|
279
|
+
catch (e) {
|
|
280
|
+
this.log('Error reading scenario report\n ' + e);
|
|
281
|
+
resolve(null);
|
|
282
|
+
}
|
|
207
283
|
}
|
|
208
284
|
});
|
|
209
285
|
});
|
|
210
286
|
});
|
|
211
287
|
}
|
|
212
|
-
logReportLink(runId, projectId) {
|
|
213
|
-
let reportLinkBaseUrl = 'https://app.blinq.io';
|
|
214
|
-
if (process.env.NODE_ENV_BLINQ === 'local') {
|
|
215
|
-
reportLinkBaseUrl = 'http://localhost:3000';
|
|
216
|
-
}
|
|
217
|
-
else if (process.env.NODE_ENV_BLINQ === 'dev') {
|
|
218
|
-
reportLinkBaseUrl = 'https://dev.app.blinq.io';
|
|
219
|
-
}
|
|
220
|
-
else if (process.env.NODE_ENV_BLINQ === 'stage') {
|
|
221
|
-
reportLinkBaseUrl = 'https://stage.app.blinq.io';
|
|
222
|
-
}
|
|
223
|
-
const reportLink = `${reportLinkBaseUrl}/${projectId}/run-report/${runId}`;
|
|
224
|
-
this.log(`Report link: ${reportLink}\n`);
|
|
225
|
-
}
|
|
226
288
|
getAppDataDir() {
|
|
227
289
|
if (process.env.BLINQ_APPDATA_DIR) {
|
|
228
290
|
return process.env.BLINQ_APPDATA_DIR;
|
|
@@ -243,4 +305,38 @@ class BVTAnalysisFormatter extends _1.default {
|
|
|
243
305
|
}
|
|
244
306
|
}
|
|
245
307
|
exports.default = BVTAnalysisFormatter;
|
|
308
|
+
function logReportLink(runId, projectId) {
|
|
309
|
+
let reportLinkBaseUrl = 'https://app.blinq.io';
|
|
310
|
+
if (process.env.NODE_ENV_BLINQ === 'local') {
|
|
311
|
+
reportLinkBaseUrl = 'http://localhost:3000';
|
|
312
|
+
}
|
|
313
|
+
else if (process.env.NODE_ENV_BLINQ === 'dev') {
|
|
314
|
+
reportLinkBaseUrl = 'https://dev.app.blinq.io';
|
|
315
|
+
}
|
|
316
|
+
else if (process.env.NODE_ENV_BLINQ === 'stage') {
|
|
317
|
+
reportLinkBaseUrl = 'https://stage.app.blinq.io';
|
|
318
|
+
}
|
|
319
|
+
else if (process.env.NODE_ENV_BLINQ === 'prod') {
|
|
320
|
+
reportLinkBaseUrl = 'https://app.blinq.io';
|
|
321
|
+
}
|
|
322
|
+
else if (!process.env.NODE_ENV_BLINQ) {
|
|
323
|
+
reportLinkBaseUrl = 'https://app.blinq.io';
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
reportLinkBaseUrl = process.env.NODE_ENV_BLINQ.replace('api', 'app');
|
|
327
|
+
}
|
|
328
|
+
const reportLink = `${reportLinkBaseUrl}/${projectId}/run-report/${runId}`;
|
|
329
|
+
console.log(`Report link: ${reportLink}\n`);
|
|
330
|
+
try {
|
|
331
|
+
publishReportLinkToGuacServer(reportLink);
|
|
332
|
+
}
|
|
333
|
+
catch (err) { }
|
|
334
|
+
}
|
|
335
|
+
exports.logReportLink = logReportLink;
|
|
336
|
+
function publishReportLinkToGuacServer(reportLink) {
|
|
337
|
+
if ((0, fs_1.existsSync)('/tmp/report_publish.sh')) {
|
|
338
|
+
const execAsync = (0, util_1.promisify)(child_process_2.exec);
|
|
339
|
+
execAsync('sh /tmp/report_publish.sh ' + reportLink);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
246
342
|
//# 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 { readFileSync, existsSync, writeFileSync } from 'fs'\nimport { mkdir, unlink, writeFile } from 'fs/promises'\nimport path from 'path'\nimport { tmpName } from 'tmp'\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'\nimport os from 'os'\nimport { getProjectByAccessKey } from './api'\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 (\n report.result.status === 'PASSED' ||\n process.env.NO_RETRAIN === 'false'\n ) {\n if (report.result.status === 'PASSED') {\n this.log('No test failed. No need to retrain\\n')\n }\n if (process.env.NO_RETRAIN === 'false') {\n this.log(\n 'Retraining is skipped since the failed step contains an API request\\n'\n )\n }\n const uploadSuccessful = await this.uploadFinalReport(report)\n if (uploadSuccessful) {\n process.exit(0)\n }\n\n process.exit(1)\n }\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 finally {\n try{\n writeFileSync(path.join(this.reportGenerator.reportFolder,\"report.json\"), JSON.stringify(finalReport, null, 2), 'utf-8')\n } catch(e){\n console.error('failed to write report.json to local disk')\n}\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 data = await getProjectByAccessKey(TOKEN)\n const currentTimestampInSeconds = Math.floor(Date.now() / 1000)\n if (data.project.expriration_date < currentTimestampInSeconds) {\n console.log(\n 'Warning: Your project has expired, retraining is restricted. Please contact sales.'\n )\n process.exit(1)\n }\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\n if (!existsSync(path.join(this.getAppDataDir(), 'blinq.io', '.temp'))) {\n mkdir(path.join(this.getAppDataDir(), 'blinq.io', '.temp'), {\n recursive: true,\n })\n }\n\n tmpName(async (err, name) => {\n const tempFile = path.join(\n this.getAppDataDir(),\n 'blinq.io',\n '.temp',\n path.basename(name)\n )\n console.log('File path: ', tempFile)\n await writeFile(tempFile, '', 'utf-8')\n\n args.push(`--temp-file=${tempFile}`)\n const cucumberClient = spawn('node', [cucumber_client_path, ...args], {\n env: {\n ...process.env,\n TEMP_FILE_PATH: tempFile,\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', async (code) => {\n if (code === 0) {\n const reportData = readFileSync(tempFile, 'utf-8')\n const retrainStats = JSON.parse(reportData) as RetrainStats\n await unlink(tempFile)\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://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 const reportLink = `${reportLinkBaseUrl}/${projectId}/run-report/${runId}`\n this.log(`Report link: ${reportLink}\\n`)\n }\n\n private getAppDataDir() {\n if (process.env.BLINQ_APPDATA_DIR) {\n return process.env.BLINQ_APPDATA_DIR\n }\n\n let appDataDir: string\n\n switch (process.platform) {\n case 'win32':\n appDataDir = process.env.APPDATA!\n break\n case 'darwin':\n appDataDir = path.join(os.homedir(), 'Library', 'Application Support')\n break\n default:\n appDataDir = path.join(os.homedir(), '.config')\n break\n }\n return appDataDir\n }\n}\n"]}
|
|
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 { readFileSync, existsSync, writeFileSync } from 'fs'\nimport { mkdir, unlink, writeFile } from 'fs/promises'\nimport path from 'path'\nimport { tmpName } from 'tmp'\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'\nimport os from 'os'\nimport { getProjectByAccessKey } from './api'\nimport SummaryFormatter from './summary_formatter'\nimport { ActionEvents, SERVICES_URI } from './helpers/constants'\nimport { axiosClient } from '../configuration/axios_client'\nimport {\n FinishTestCaseResponse,\n RootCauseProps,\n} from './helpers/upload_serivce'\nimport { promisify } from 'util'\nimport { exec } from 'child_process'\n\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 static reportGenerator: ReportGenerator\n static reRunFailedStepsIndex:\n | { testCaseId: string; failedStepIndex: number }[]\n | null\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 private failedStepsIndex: { testCaseId: string; failedStepIndex: number }[]\n private summaryFormatter: SummaryFormatter\n private rootCauseArray: {\n rootCause: RootCauseProps\n report: JsonTestProgress\n }[] = []\n\n constructor(options: IFormatterOptions) {\n super(options)\n this.summaryFormatter = new SummaryFormatter(options)\n BVTAnalysisFormatter.reportGenerator = this.reportGenerator\n this.rootCauseArray = []\n this.failedStepsIndex = []\n BVTAnalysisFormatter.reRunFailedStepsIndex = process.env.RERUN\n ? JSON.parse(process.env.RERUN)\n : null\n\n if (!TOKEN && process.env.BVT_FORMATTER === 'ANALYSIS') {\n throw new Error('TOKEN must be set')\n }\n this.sendEvent(ActionEvents.cli_run_tests)\n options.eventBroadcaster.on(\n 'envelope',\n async (envelope: EnvelopeWithMetaMessage, data?: any) => {\n if (doesHaveValue(envelope.testCaseFinished) && data) {\n const { rootCause, report } = data as FinishTestCaseResponse\n\n if (!rootCause.status) {\n console.error(\n `Root cause: ${rootCause.failClass}\\n, ${rootCause.analysis}\\nfailing step: ${rootCause.failedStep}`\n )\n this.rootCauseArray.push({ rootCause, report })\n this.failedStepsIndex.push({\n testCaseId: report.id,\n failedStepIndex: rootCause.failedStep,\n })\n }\n return\n }\n await this.reportGenerator.handleMessage(envelope)\n\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 this.START = Date.now()\n if (process.env.BVT_FORMATTER === 'ANALYSIS') {\n await this.analyzeReport()\n } else {\n // await this.uploadReport(report)\n }\n this.exit = true\n }\n }\n )\n }\n\n private sendEvent(event: ActionEvents) {\n axiosClient\n .post(\n `${SERVICES_URI.STORAGE}/event`,\n {\n event,\n },\n {\n headers: {\n Authorization: `Bearer ${TOKEN}`,\n 'x-source': 'cucumber_js',\n },\n }\n )\n .catch((err) => {\n // Error with events, ignoring\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 let anyRem\n if (process.env.UPLOADING_TEST_CASE) {\n anyRem = JSON.parse(process.env.UPLOADING_TEST_CASE) as string[]\n } else {\n anyRem = undefined\n }\n\n if (this.exit && (!anyRem || anyRem.length === 0)) {\n // clearInterval(checkInterval)\n // resolve(null)\n if (this.reportGenerator.getReport().result.status === 'FAILED') {\n process.exit(1)\n } else {\n process.exit(0)\n }\n }\n }, 100) // check every 100ms\n })\n }\n private async analyzeReport() {\n if (\n this.rootCauseArray.length === 0 ||\n process.env.NO_RETRAIN === 'false'\n ) {\n if (this.rootCauseArray.length === 0) {\n this.log('No test failed. No need to retrain\\n')\n }\n if (process.env.NO_RETRAIN === 'false') {\n this.log(\n 'Retraining is skipped since the failed step contains an API request\\n'\n )\n }\n // const uploadSuccessful = await this.uploadFinalReport(report)\n // process.exit(0)\n this.exit = true\n return\n }\n\n //checking if the type of report.result is JsonResultFailed or not\n\n this.log('Some tests failed, starting the retraining...\\n')\n await this.processTestCases()\n if (this.reportGenerator.getReport().result.status === 'FAILED') {\n process.exit(1)\n }\n process.exit(0)\n }\n private async processTestCases() {\n for (const { rootCause, report } of this.rootCauseArray) {\n await this.processTestCase(rootCause, report)\n }\n }\n private async processTestCase(\n rootCause: RootCauseProps,\n report: JsonTestProgress\n ) {\n const failedTestSteps = rootCause.failedStep\n\n if (\n BVTAnalysisFormatter.reRunFailedStepsIndex &&\n BVTAnalysisFormatter.reRunFailedStepsIndex.length > 0\n ) {\n const previousRun = BVTAnalysisFormatter.reRunFailedStepsIndex[0]\n if (previousRun.failedStepIndex === failedTestSteps) {\n console.log('Same step has failed again, skipping retraining')\n BVTAnalysisFormatter.reRunFailedStepsIndex.shift()\n return\n }\n BVTAnalysisFormatter.reRunFailedStepsIndex.shift()\n }\n\n const retrainStats = await this.retrain(failedTestSteps, report)\n\n if (!retrainStats) {\n return\n }\n\n await this.uploader.modifyTestCase({\n ...report,\n retrainStats,\n })\n\n await this.rerun(report)\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 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 } finally {\n try {\n writeFileSync(\n path.join(this.reportGenerator.reportFolder, 'report.json'),\n JSON.stringify(finalReport, null, 2),\n 'utf-8'\n )\n } catch (e) {\n console.error('failed to write report.json to local disk')\n }\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 data = await getProjectByAccessKey(TOKEN)\n const currentTimestampInSeconds = Math.floor(Date.now() / 1000)\n if (data.project.expriration_date < currentTimestampInSeconds) {\n console.log(\n 'Warning: Your project has expired, retraining is restricted. Please contact sales.'\n )\n process.exit(1)\n }\n return await this.call_cucumber_client(failedTestCases, testCase)\n }\n\n private async rerun(report: JsonTestProgress) {\n await new Promise<void>((resolve) => {\n const node_path = process.argv.shift()\n const args = [\n path.join(\n process.cwd(),\n 'node_modules',\n '@dev-blinq',\n 'cucumber-js',\n 'bin',\n 'cucumber.js'\n ),\n '--name',\n `^${report.scenarioName}$`,\n '--exit',\n '--format',\n 'bvt',\n '--run-name',\n `${report.scenarioName}@debug`,\n path.join(process.cwd(), 'features', `${report.featureName}.feature`),\n ]\n const cucumberClient = spawn(node_path, args, {\n env: {\n ...process.env,\n RERUN: JSON.stringify(this.failedStepsIndex),\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', () => {\n resolve()\n })\n })\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},`,\n ]\n\n if (process.env.BLINQ_ENV) {\n args.push(`--env=${process.env.BLINQ_ENV}`)\n }\n\n if (!existsSync(path.join(this.getAppDataDir(), 'blinq.io', '.temp'))) {\n mkdir(path.join(this.getAppDataDir(), 'blinq.io', '.temp'), {\n recursive: true,\n })\n }\n\n tmpName(async (err, name) => {\n const tempFile = path.join(\n this.getAppDataDir(),\n 'blinq.io',\n '.temp',\n path.basename(name)\n )\n console.log('File path: ', tempFile)\n await writeFile(tempFile, '', 'utf-8')\n\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', async (code) => {\n if (code === 0) {\n const reportData = readFileSync(tempFile, 'utf-8')\n const retrainStats = JSON.parse(reportData) as RetrainStats\n await unlink(tempFile)\n resolve(retrainStats)\n } else {\n this.log('Error retraining\\n')\n try {\n const reportData = readFileSync(tempFile, 'utf-8')\n const retrainStats = JSON.parse(reportData) as RetrainStats\n await unlink(tempFile)\n resolve(retrainStats)\n } catch (e) {\n this.log('Error reading scenario report\\n ' + e)\n resolve(null)\n }\n }\n })\n })\n })\n }\n\n private getAppDataDir() {\n if (process.env.BLINQ_APPDATA_DIR) {\n return process.env.BLINQ_APPDATA_DIR\n }\n\n let appDataDir: string\n\n switch (process.platform) {\n case 'win32':\n appDataDir = process.env.APPDATA!\n break\n case 'darwin':\n appDataDir = path.join(os.homedir(), 'Library', 'Application Support')\n break\n default:\n appDataDir = path.join(os.homedir(), '.config')\n break\n }\n return appDataDir\n }\n}\n\nexport function logReportLink(runId: string, projectId: string) {\n let reportLinkBaseUrl = 'https://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 } else if (process.env.NODE_ENV_BLINQ === 'prod') {\n reportLinkBaseUrl = 'https://app.blinq.io'\n } else if (!process.env.NODE_ENV_BLINQ) {\n reportLinkBaseUrl = 'https://app.blinq.io'\n } else {\n reportLinkBaseUrl = process.env.NODE_ENV_BLINQ.replace('api', 'app')\n }\n const reportLink = `${reportLinkBaseUrl}/${projectId}/run-report/${runId}`\n console.log(`Report link: ${reportLink}\\n`)\n try {\n publishReportLinkToGuacServer(reportLink)\n } catch (err) {}\n}\n\nfunction publishReportLinkToGuacServer(reportLink: string) {\n if (existsSync('/tmp/report_publish.sh')) {\n const execAsync = promisify(exec)\n execAsync('sh /tmp/report_publish.sh ' + reportLink)\n }\n}\n"]}
|
|
@@ -89,7 +89,7 @@ const generateTestData = (featureFileContent, vars, fakeData, projectDir) => {
|
|
|
89
89
|
}
|
|
90
90
|
catch (err) {
|
|
91
91
|
// eslint-disable-next-line no-console
|
|
92
|
-
console.log('unknown faker variable:' + match[0])
|
|
92
|
+
//console.log('unknown faker variable:' + match[0])
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
return {
|
|
@@ -122,6 +122,9 @@ const getFakeString = (content) => {
|
|
|
122
122
|
return fakeFunc(json5_1.default.parse(argument));
|
|
123
123
|
}
|
|
124
124
|
catch (error) {
|
|
125
|
+
if (!argument) {
|
|
126
|
+
return fakeFunc();
|
|
127
|
+
}
|
|
125
128
|
return fakeFunc(argument);
|
|
126
129
|
}
|
|
127
130
|
};
|