@dev-blinq/cucumber-js 1.0.4 → 1.0.5
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/lib/formatter/bvt_formatter.d.ts +9 -0
- package/lib/formatter/bvt_formatter.js +62 -0
- package/lib/formatter/bvt_formatter.js.map +1 -0
- package/lib/formatter/feature_data_format.js +6 -6
- package/lib/formatter/feature_data_format.js.map +1 -1
- package/lib/formatter/helpers/formatters.js +2 -0
- package/lib/formatter/helpers/formatters.js.map +1 -1
- package/lib/formatter/helpers/report_generator.d.ts +91 -0
- package/lib/formatter/helpers/report_generator.js +248 -0
- package/lib/formatter/helpers/report_generator.js.map +1 -0
- package/lib/formatter/helpers/upload_serivce.d.ts +9 -0
- package/lib/formatter/helpers/upload_serivce.js +47 -0
- package/lib/formatter/helpers/upload_serivce.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Formatter, { IFormatterOptions } from '.';
|
|
2
|
+
import { JsonReport } from './helpers/report_generator';
|
|
3
|
+
export default class BVTFormatter extends Formatter {
|
|
4
|
+
private reportGenerator;
|
|
5
|
+
private uploadService;
|
|
6
|
+
constructor(options: IFormatterOptions);
|
|
7
|
+
uploadRun(report: JsonReport): Promise<void>;
|
|
8
|
+
createZip(reportFolder: string | null, report: JsonReport): Promise<string>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const _1 = __importDefault(require("."));
|
|
7
|
+
const report_generator_1 = __importDefault(require("./helpers/report_generator"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const jszip_1 = __importDefault(require("jszip"));
|
|
11
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
12
|
+
const upload_serivce_1 = require("./helpers/upload_serivce");
|
|
13
|
+
const REPORT_SERVICE_URL = process.env.REPORT_SERVICE_URL;
|
|
14
|
+
const REPORT_SERVICE_TOKEN = process.env.REPORT_SERVICE_TOKEN;
|
|
15
|
+
class BVTFormatter extends _1.default {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
super(options);
|
|
18
|
+
this.reportGenerator = new report_generator_1.default();
|
|
19
|
+
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
20
|
+
if (!REPORT_SERVICE_URL || !REPORT_SERVICE_TOKEN) {
|
|
21
|
+
throw new Error('REPORT_SERVICE_URL and REPORT_SERVICE_TOKEN must be set');
|
|
22
|
+
}
|
|
23
|
+
options.eventBroadcaster.on('envelope', async (envelope) => {
|
|
24
|
+
this.reportGenerator.handleMessage(envelope);
|
|
25
|
+
if (envelope.testRunFinished) {
|
|
26
|
+
const report = this.reportGenerator.getReport();
|
|
27
|
+
// this.log(JSON.stringify(report, null, 2))
|
|
28
|
+
await this.uploadRun(report);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async uploadRun(report) {
|
|
33
|
+
const runDoc = await this.uploadService.createRunDocument('test');
|
|
34
|
+
const runDocId = runDoc._id;
|
|
35
|
+
const formData = new form_data_1.default();
|
|
36
|
+
const reportFolder = this.reportGenerator.reportFolder;
|
|
37
|
+
if (!fs_1.default.existsSync(reportFolder)) {
|
|
38
|
+
fs_1.default.mkdirSync(reportFolder);
|
|
39
|
+
}
|
|
40
|
+
const zipPath = await this.createZip(reportFolder, report);
|
|
41
|
+
formData.append(runDocId, fs_1.default.readFileSync(zipPath), 'report.zip');
|
|
42
|
+
await this.uploadService.upload(formData);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
async createZip(reportFolder, report) {
|
|
46
|
+
const zip = new jszip_1.default();
|
|
47
|
+
zip.file('report.json', JSON.stringify(report, null, 2));
|
|
48
|
+
const folder = zip.folder('screenshots');
|
|
49
|
+
const files = fs_1.default.readdirSync(path_1.default.join(reportFolder, 'screenshots'));
|
|
50
|
+
files.forEach((file) => {
|
|
51
|
+
folder.file(file, fs_1.default.readFileSync(path_1.default.join(reportFolder, file)));
|
|
52
|
+
});
|
|
53
|
+
const zipBuffer = await zip.generateAsync({ type: 'nodebuffer' });
|
|
54
|
+
// save zip file
|
|
55
|
+
const zipPath = path_1.default.join(reportFolder, 'report.zip');
|
|
56
|
+
fs_1.default.writeFileSync(zipPath, zipBuffer);
|
|
57
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, 'report.json'), JSON.stringify(report, null, 2));
|
|
58
|
+
return zipPath;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.default = BVTFormatter;
|
|
62
|
+
//# sourceMappingURL=bvt_formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bvt_formatter.js","sourceRoot":"","sources":["../../src/formatter/bvt_formatter.ts"],"names":[],"mappings":"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","sourcesContent":["import * as messages from '@cucumber/messages'\nimport Formatter, { IFormatterOptions } from '.'\nimport ReportGenerator, { JsonReport } from './helpers/report_generator'\nimport path from 'path'\nimport fs from 'fs'\nimport JSZip from 'jszip'\nimport FormData from 'form-data'\nimport { RunUploadService } from './helpers/upload_serivce'\n\nconst REPORT_SERVICE_URL = process.env.REPORT_SERVICE_URL\nconst REPORT_SERVICE_TOKEN = process.env.REPORT_SERVICE_TOKEN\n\nexport default class BVTFormatter extends Formatter {\n private reportGenerator = new ReportGenerator()\n private uploadService = new RunUploadService(\n REPORT_SERVICE_URL,\n REPORT_SERVICE_TOKEN\n )\n constructor(options: IFormatterOptions) {\n super(options)\n if (!REPORT_SERVICE_URL || !REPORT_SERVICE_TOKEN) {\n throw new Error('REPORT_SERVICE_URL and REPORT_SERVICE_TOKEN must be set')\n }\n options.eventBroadcaster.on(\n 'envelope',\n async (envelope: messages.Envelope) => {\n this.reportGenerator.handleMessage(envelope)\n if (envelope.testRunFinished) {\n const report = this.reportGenerator.getReport()\n // this.log(JSON.stringify(report, null, 2))\n await this.uploadRun(report)\n }\n }\n )\n }\n async uploadRun(report: JsonReport) {\n const runDoc = await this.uploadService.createRunDocument('test')\n const runDocId = runDoc._id\n const formData = new FormData()\n const reportFolder = this.reportGenerator.reportFolder\n if (!fs.existsSync(reportFolder)) {\n fs.mkdirSync(reportFolder)\n }\n const zipPath = await this.createZip(reportFolder, report)\n formData.append(runDocId, fs.readFileSync(zipPath), 'report.zip')\n await this.uploadService.upload(formData)\n process.exit(0)\n }\n async createZip(reportFolder: string | null, report: JsonReport) {\n const zip = new JSZip()\n zip.file('report.json', JSON.stringify(report, null, 2))\n const folder = zip.folder('screenshots')\n const files = fs.readdirSync(path.join(reportFolder, 'screenshots'))\n files.forEach((file) => {\n folder.file(file, fs.readFileSync(path.join(reportFolder, file)))\n })\n const zipBuffer = await zip.generateAsync({ type: 'nodebuffer' })\n // save zip file\n const zipPath = path.join(reportFolder, 'report.zip')\n fs.writeFileSync(zipPath, zipBuffer)\n fs.writeFileSync(\n path.join(reportFolder, 'report.json'),\n JSON.stringify(report, null, 2)\n )\n return zipPath\n }\n}\n"]}
|
|
@@ -7,16 +7,16 @@ const generateTestData = (featureFileContent, vars, fakeData) => {
|
|
|
7
7
|
const variableRegex = /^([a-zA-Z0-9_]*)=(.*)/g;
|
|
8
8
|
let newContent = featureFileContent;
|
|
9
9
|
let match;
|
|
10
|
-
const
|
|
10
|
+
const matches = [];
|
|
11
11
|
// collect all matches
|
|
12
12
|
while ((match = regexp.exec(featureFileContent)) !== null) {
|
|
13
|
-
|
|
13
|
+
matches.push(match);
|
|
14
14
|
}
|
|
15
15
|
// find all variables in the matches
|
|
16
16
|
const variables = { ...vars };
|
|
17
17
|
if (Object.keys(variables).length > 0) {
|
|
18
|
-
for (let i = 0; i <
|
|
19
|
-
const _match =
|
|
18
|
+
for (let i = 0; i < matches.length; i++) {
|
|
19
|
+
const _match = matches[i];
|
|
20
20
|
const value = _match[1];
|
|
21
21
|
const variableMatch = variableRegex.exec(value);
|
|
22
22
|
if (variableMatch !== null) {
|
|
@@ -29,8 +29,8 @@ const generateTestData = (featureFileContent, vars, fakeData) => {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
32
|
-
for (let i = 0; i <
|
|
33
|
-
const _match =
|
|
32
|
+
for (let i = 0; i < matches.length; i++) {
|
|
33
|
+
const _match = matches[i];
|
|
34
34
|
const value = _match[1];
|
|
35
35
|
const variableMatch = variableRegex.exec(value);
|
|
36
36
|
if (variableMatch !== null) {
|
|
@@ -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
|
|
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"]}
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const json_formatter_1 = __importDefault(require("../json_formatter"));
|
|
7
|
+
const bvt_formatter_1 = __importDefault(require("../bvt_formatter"));
|
|
7
8
|
const message_formatter_1 = __importDefault(require("../message_formatter"));
|
|
8
9
|
const progress_bar_formatter_1 = __importDefault(require("../progress_bar_formatter"));
|
|
9
10
|
const progress_formatter_1 = __importDefault(require("../progress_formatter"));
|
|
@@ -18,6 +19,7 @@ const Formatters = {
|
|
|
18
19
|
getFormatters() {
|
|
19
20
|
return {
|
|
20
21
|
json: json_formatter_1.default,
|
|
22
|
+
bvt: bvt_formatter_1.default,
|
|
21
23
|
message: message_formatter_1.default,
|
|
22
24
|
html: html_formatter_1.default,
|
|
23
25
|
progress: progress_formatter_1.default,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../../src/formatter/helpers/formatters.ts"],"names":[],"mappings":";;;;;AACA,uEAA6C;AAC7C,6EAAmD;AACnD,uFAA4D;AAC5D,+EAAqD;AACrD,yEAA+C;AAC/C,+EAAqD;AACrD,6EAAmD;AACnD,yEAA+C;AAC/C,mFAAwD;AACxD,uEAA6C;AAC7C,yEAA+C;AAE/C,MAAM,UAAU,GAAG;IACjB,aAAa;QACX,OAAO;YACL,IAAI,EAAE,wBAAa;YACnB,OAAO,EAAE,2BAAgB;YACzB,IAAI,EAAE,wBAAa;YACnB,QAAQ,EAAE,4BAAiB;YAC3B,cAAc,EAAE,gCAAoB;YACpC,KAAK,EAAE,yBAAc;YACrB,QAAQ,EAAE,4BAAiB;YAC3B,OAAO,EAAE,2BAAgB;YACzB,KAAK,EAAE,yBAAc;YACrB,YAAY,EAAE,8BAAkB;YAChC,KAAK,EAAE,yBAAc;SACtB,CAAA;IACH,CAAC;IACD,kCAAkC;QAChC,IAAI,mCAAmC,GAAW,EAAE,CAAA;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACvC,KAAK,MAAM,aAAa,IAAI,UAAU,EAAE;YACtC,mCAAmC,IAAI,OAAO,aAAa,KAAK,UAAU,CAAC,aAAa,CAAC,CAAC,aAAa,IAAI,CAAA;SAC5G;QAED,OAAO,mCAAmC,CAAA;IAC5C,CAAC;CACF,CAAA;AAED,kBAAe,UAAU,CAAA","sourcesContent":["import Formatter from '../.'\nimport JsonFormatter from '../json_formatter'\nimport MessageFormatter from '../message_formatter'\nimport ProgressBarFormatter from '../progress_bar_formatter'\nimport ProgressFormatter from '../progress_formatter'\nimport RerunFormatter from '../rerun_formatter'\nimport SnippetsFormatter from '../snippets_formatter'\nimport SummaryFormatter from '../summary_formatter'\nimport UsageFormatter from '../usage_formatter'\nimport UsageJsonFormatter from '../usage_json_formatter'\nimport HtmlFormatter from '../html_formatter'\nimport JunitFormatter from '../junit_formatter'\n\nconst Formatters = {\n getFormatters(): Record<string, typeof Formatter> {\n return {\n json: JsonFormatter,\n message: MessageFormatter,\n html: HtmlFormatter,\n progress: ProgressFormatter,\n 'progress-bar': ProgressBarFormatter,\n rerun: RerunFormatter,\n snippets: SnippetsFormatter,\n summary: SummaryFormatter,\n usage: UsageFormatter,\n 'usage-json': UsageJsonFormatter,\n junit: JunitFormatter,\n }\n },\n buildFormattersDocumentationString(): string {\n let concatanatedFormattersDocumentation: string = ''\n const formatters = this.getFormatters()\n for (const formatterName in formatters) {\n concatanatedFormattersDocumentation += ` ${formatterName}: ${formatters[formatterName].documentation}\\n`\n }\n\n return concatanatedFormattersDocumentation\n },\n}\n\nexport default Formatters\n"]}
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../../src/formatter/helpers/formatters.ts"],"names":[],"mappings":";;;;;AACA,uEAA6C;AAC7C,qEAA2C;AAC3C,6EAAmD;AACnD,uFAA4D;AAC5D,+EAAqD;AACrD,yEAA+C;AAC/C,+EAAqD;AACrD,6EAAmD;AACnD,yEAA+C;AAC/C,mFAAwD;AACxD,uEAA6C;AAC7C,yEAA+C;AAE/C,MAAM,UAAU,GAAG;IACjB,aAAa;QACX,OAAO;YACL,IAAI,EAAE,wBAAa;YACnB,GAAG,EAAE,uBAAY;YACjB,OAAO,EAAE,2BAAgB;YACzB,IAAI,EAAE,wBAAa;YACnB,QAAQ,EAAE,4BAAiB;YAC3B,cAAc,EAAE,gCAAoB;YACpC,KAAK,EAAE,yBAAc;YACrB,QAAQ,EAAE,4BAAiB;YAC3B,OAAO,EAAE,2BAAgB;YACzB,KAAK,EAAE,yBAAc;YACrB,YAAY,EAAE,8BAAkB;YAChC,KAAK,EAAE,yBAAc;SACtB,CAAA;IACH,CAAC;IACD,kCAAkC;QAChC,IAAI,mCAAmC,GAAW,EAAE,CAAA;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACvC,KAAK,MAAM,aAAa,IAAI,UAAU,EAAE;YACtC,mCAAmC,IAAI,OAAO,aAAa,KAAK,UAAU,CAAC,aAAa,CAAC,CAAC,aAAa,IAAI,CAAA;SAC5G;QAED,OAAO,mCAAmC,CAAA;IAC5C,CAAC;CACF,CAAA;AAED,kBAAe,UAAU,CAAA","sourcesContent":["import Formatter from '../.'\nimport JsonFormatter from '../json_formatter'\nimport BVTFormatter from '../bvt_formatter'\nimport MessageFormatter from '../message_formatter'\nimport ProgressBarFormatter from '../progress_bar_formatter'\nimport ProgressFormatter from '../progress_formatter'\nimport RerunFormatter from '../rerun_formatter'\nimport SnippetsFormatter from '../snippets_formatter'\nimport SummaryFormatter from '../summary_formatter'\nimport UsageFormatter from '../usage_formatter'\nimport UsageJsonFormatter from '../usage_json_formatter'\nimport HtmlFormatter from '../html_formatter'\nimport JunitFormatter from '../junit_formatter'\n\nconst Formatters = {\n getFormatters(): Record<string, typeof Formatter> {\n return {\n json: JsonFormatter,\n bvt: BVTFormatter,\n message: MessageFormatter,\n html: HtmlFormatter,\n progress: ProgressFormatter,\n 'progress-bar': ProgressBarFormatter,\n rerun: RerunFormatter,\n snippets: SnippetsFormatter,\n summary: SummaryFormatter,\n usage: UsageFormatter,\n 'usage-json': UsageJsonFormatter,\n junit: JunitFormatter,\n }\n },\n buildFormattersDocumentationString(): string {\n let concatanatedFormattersDocumentation: string = ''\n const formatters = this.getFormatters()\n for (const formatterName in formatters) {\n concatanatedFormattersDocumentation += ` ${formatterName}: ${formatters[formatterName].documentation}\\n`\n }\n\n return concatanatedFormattersDocumentation\n },\n}\n\nexport default Formatters\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as messages from '@cucumber/messages';
|
|
2
|
+
type JsonTimestamp = number;
|
|
3
|
+
type JsonStepType = 'Unknown' | 'Context' | 'Action' | 'Outcome';
|
|
4
|
+
type JsonResultUnknown = {
|
|
5
|
+
status: 'UNKNOWN';
|
|
6
|
+
};
|
|
7
|
+
type JsonResultSkipped = {
|
|
8
|
+
status: 'SKIPPED';
|
|
9
|
+
};
|
|
10
|
+
type JsonResultUndefined = {
|
|
11
|
+
status: 'UNDEFINED';
|
|
12
|
+
};
|
|
13
|
+
type JsonResultAmbiguous = {
|
|
14
|
+
status: 'AMBIGUOUS';
|
|
15
|
+
};
|
|
16
|
+
type JsonResultStarted = {
|
|
17
|
+
status: 'STARTED';
|
|
18
|
+
startTime: JsonTimestamp;
|
|
19
|
+
};
|
|
20
|
+
type JsonResultPending = {
|
|
21
|
+
status: 'PENDING';
|
|
22
|
+
startTime: JsonTimestamp;
|
|
23
|
+
endTime: JsonTimestamp;
|
|
24
|
+
};
|
|
25
|
+
type JsonResultPassed = {
|
|
26
|
+
status: 'PASSED';
|
|
27
|
+
startTime: JsonTimestamp;
|
|
28
|
+
endTime: JsonTimestamp;
|
|
29
|
+
};
|
|
30
|
+
type JsonResultFailed = {
|
|
31
|
+
status: 'FAILED';
|
|
32
|
+
startTime: JsonTimestamp;
|
|
33
|
+
endTime: JsonTimestamp;
|
|
34
|
+
message?: string;
|
|
35
|
+
};
|
|
36
|
+
type JsonCommandResult = JsonResultPassed | JsonResultFailed;
|
|
37
|
+
type JsonStepResult = JsonResultUnknown | JsonResultSkipped | JsonResultUndefined | JsonResultAmbiguous | JsonResultStarted | JsonResultPending | JsonResultPassed | JsonResultFailed;
|
|
38
|
+
type JsonTestResult = JsonResultUnknown | JsonResultStarted | JsonResultPassed | JsonResultFailed;
|
|
39
|
+
type JsonReportResult = JsonTestResult;
|
|
40
|
+
type JsonCommand = {
|
|
41
|
+
type: string;
|
|
42
|
+
value?: string;
|
|
43
|
+
text: string;
|
|
44
|
+
screenshotId?: string;
|
|
45
|
+
result: JsonCommandResult;
|
|
46
|
+
};
|
|
47
|
+
type JsonStep = {
|
|
48
|
+
type: JsonStepType;
|
|
49
|
+
text: string;
|
|
50
|
+
commands: JsonCommand[];
|
|
51
|
+
result: JsonStepResult;
|
|
52
|
+
};
|
|
53
|
+
type JsonTestProgress = {
|
|
54
|
+
id: string;
|
|
55
|
+
featureName: string;
|
|
56
|
+
uri: string;
|
|
57
|
+
scenarioName: string;
|
|
58
|
+
parameters: Record<string, string>;
|
|
59
|
+
steps: JsonStep[];
|
|
60
|
+
result: JsonTestResult;
|
|
61
|
+
};
|
|
62
|
+
export type JsonReport = {
|
|
63
|
+
testCases: JsonTestProgress[];
|
|
64
|
+
result: JsonReportResult;
|
|
65
|
+
};
|
|
66
|
+
export default class ReportGenerator {
|
|
67
|
+
private report;
|
|
68
|
+
private gherkinDocumentMap;
|
|
69
|
+
private pickleMap;
|
|
70
|
+
private testCaseMap;
|
|
71
|
+
private testStepMap;
|
|
72
|
+
private stepProgressMap;
|
|
73
|
+
private testProgressMap;
|
|
74
|
+
reportFolder: null | string;
|
|
75
|
+
handleMessage(envelope: messages.Envelope): void;
|
|
76
|
+
getReport(): JsonReport;
|
|
77
|
+
private handleParseError;
|
|
78
|
+
private onGherkinDocument;
|
|
79
|
+
private onPickle;
|
|
80
|
+
private getTimeStamp;
|
|
81
|
+
private onTestRunStarted;
|
|
82
|
+
private onTestCase;
|
|
83
|
+
private onTestCaseStarted;
|
|
84
|
+
private onTestStepStarted;
|
|
85
|
+
private onAttachment;
|
|
86
|
+
private onTestStepFinished;
|
|
87
|
+
private getTestCaseResult;
|
|
88
|
+
private onTestCaseFinished;
|
|
89
|
+
private onTestRunFinished;
|
|
90
|
+
}
|
|
91
|
+
export {};
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class ReportGenerator {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.report = {
|
|
6
|
+
result: {
|
|
7
|
+
status: 'UNKNOWN',
|
|
8
|
+
},
|
|
9
|
+
testCases: [],
|
|
10
|
+
};
|
|
11
|
+
this.gherkinDocumentMap = new Map();
|
|
12
|
+
this.pickleMap = new Map();
|
|
13
|
+
this.testCaseMap = new Map();
|
|
14
|
+
this.testStepMap = new Map();
|
|
15
|
+
this.stepProgressMap = new Map();
|
|
16
|
+
this.testProgressMap = new Map();
|
|
17
|
+
this.reportFolder = null;
|
|
18
|
+
}
|
|
19
|
+
handleMessage(envelope) {
|
|
20
|
+
const type = Object.keys(envelope)[0];
|
|
21
|
+
switch (type) {
|
|
22
|
+
// case "meta": { break}
|
|
23
|
+
// case "source": { break}
|
|
24
|
+
case 'parseError': {
|
|
25
|
+
const parseError = envelope[type];
|
|
26
|
+
this.handleParseError(parseError);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case 'gherkinDocument': {
|
|
30
|
+
const doc = envelope[type];
|
|
31
|
+
this.onGherkinDocument(doc);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case 'pickle': {
|
|
35
|
+
const pickle = envelope[type];
|
|
36
|
+
this.onPickle(pickle);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
// case "stepDefinition": { break}
|
|
40
|
+
// case "hook": { break} // Before Hook
|
|
41
|
+
case 'testRunStarted': {
|
|
42
|
+
const testRunStarted = envelope[type];
|
|
43
|
+
this.onTestRunStarted(testRunStarted);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case 'testCase': {
|
|
47
|
+
const testCase = envelope[type];
|
|
48
|
+
this.onTestCase(testCase);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case 'testCaseStarted': {
|
|
52
|
+
const testCaseStarted = envelope[type];
|
|
53
|
+
this.onTestCaseStarted(testCaseStarted);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'testStepStarted': {
|
|
57
|
+
const testStepStarted = envelope[type];
|
|
58
|
+
this.onTestStepStarted(testStepStarted);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'attachment': {
|
|
62
|
+
const attachment = envelope[type];
|
|
63
|
+
this.onAttachment(attachment);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'testStepFinished': {
|
|
67
|
+
const testStepFinished = envelope[type];
|
|
68
|
+
this.onTestStepFinished(testStepFinished);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'testCaseFinished': {
|
|
72
|
+
const testCaseFinished = envelope[type];
|
|
73
|
+
this.onTestCaseFinished(testCaseFinished);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
// case "hook": { break} // After Hook
|
|
77
|
+
case 'testRunFinished': {
|
|
78
|
+
const testRunFinished = envelope[type];
|
|
79
|
+
this.onTestRunFinished(testRunFinished);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
// case "parameterType" : { break}
|
|
83
|
+
// case "undefinedParameterType": { break}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
getReport() {
|
|
87
|
+
return this.report;
|
|
88
|
+
}
|
|
89
|
+
handleParseError(parseError) {
|
|
90
|
+
const { message, source } = parseError;
|
|
91
|
+
const timestamp = new Date().getTime();
|
|
92
|
+
this.report.result = {
|
|
93
|
+
status: 'FAILED',
|
|
94
|
+
startTime: timestamp,
|
|
95
|
+
endTime: timestamp,
|
|
96
|
+
message: message,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
onGherkinDocument(doc) {
|
|
100
|
+
this.gherkinDocumentMap.set(doc.uri, doc);
|
|
101
|
+
}
|
|
102
|
+
onPickle(pickle) {
|
|
103
|
+
this.pickleMap.set(pickle.id, pickle);
|
|
104
|
+
}
|
|
105
|
+
getTimeStamp(timestamp) {
|
|
106
|
+
return timestamp.seconds * 1000 + timestamp.nanos / 1000000;
|
|
107
|
+
}
|
|
108
|
+
onTestRunStarted(testRunStarted) {
|
|
109
|
+
this.report.result = {
|
|
110
|
+
status: 'STARTED',
|
|
111
|
+
startTime: this.getTimeStamp(testRunStarted.timestamp),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
onTestCase(testCase) {
|
|
115
|
+
this.testCaseMap.set(testCase.id, testCase);
|
|
116
|
+
testCase.testSteps.forEach((testStep) => {
|
|
117
|
+
this.testStepMap.set(testStep.id, testStep);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
onTestCaseStarted(testCaseStarted) {
|
|
121
|
+
const { testCaseId, id, timestamp } = testCaseStarted;
|
|
122
|
+
const testCase = this.testCaseMap.get(testCaseId);
|
|
123
|
+
if (testCase === undefined)
|
|
124
|
+
throw new Error(`testCase with id ${testCaseId} not found`);
|
|
125
|
+
const pickle = this.pickleMap.get(testCase.pickleId);
|
|
126
|
+
if (pickle === undefined)
|
|
127
|
+
throw new Error(`pickle with id ${testCase.pickleId} not found`);
|
|
128
|
+
const doc = this.gherkinDocumentMap.get(pickle.uri);
|
|
129
|
+
if (doc === undefined)
|
|
130
|
+
throw new Error(`gherkinDocument with uri ${pickle.uri} not found`);
|
|
131
|
+
const featureName = doc.feature.name;
|
|
132
|
+
const scenarioName = pickle.name;
|
|
133
|
+
const steps = pickle.steps.map((step) => {
|
|
134
|
+
this.stepProgressMap.set(step.id, {
|
|
135
|
+
type: step.type,
|
|
136
|
+
text: step.text,
|
|
137
|
+
commands: [],
|
|
138
|
+
result: {
|
|
139
|
+
status: 'UNKNOWN',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
return this.stepProgressMap.get(step.id);
|
|
143
|
+
});
|
|
144
|
+
this.testProgressMap.set(id, {
|
|
145
|
+
id,
|
|
146
|
+
uri: pickle.uri,
|
|
147
|
+
featureName,
|
|
148
|
+
scenarioName,
|
|
149
|
+
// TODO: compute parameters
|
|
150
|
+
parameters: {},
|
|
151
|
+
steps,
|
|
152
|
+
result: {
|
|
153
|
+
status: 'STARTED',
|
|
154
|
+
startTime: this.getTimeStamp(timestamp),
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
this.report.testCases.push(this.testProgressMap.get(id));
|
|
158
|
+
}
|
|
159
|
+
onTestStepStarted(testStepStarted) {
|
|
160
|
+
const { testStepId, timestamp, testCaseStartedId } = testStepStarted;
|
|
161
|
+
const testStep = this.testStepMap.get(testStepId);
|
|
162
|
+
if (testStep === undefined)
|
|
163
|
+
throw new Error(`testStep with id ${testStepId} not found`);
|
|
164
|
+
if (testStep.pickleStepId === undefined)
|
|
165
|
+
return;
|
|
166
|
+
const stepProgess = this.stepProgressMap.get(testStep.pickleStepId);
|
|
167
|
+
stepProgess.result = {
|
|
168
|
+
status: 'STARTED',
|
|
169
|
+
startTime: this.getTimeStamp(timestamp),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
onAttachment(attachment) {
|
|
173
|
+
const { testCaseStartedId, testStepId, body, mediaType, contentEncoding, fileName, source, url, } = attachment;
|
|
174
|
+
if (mediaType === 'text/plain') {
|
|
175
|
+
this.reportFolder = body.replaceAll('\\', '/');
|
|
176
|
+
}
|
|
177
|
+
const testStep = this.testStepMap.get(testStepId);
|
|
178
|
+
if (testStep.pickleStepId === undefined)
|
|
179
|
+
return;
|
|
180
|
+
const stepProgess = this.stepProgressMap.get(testStep.pickleStepId);
|
|
181
|
+
if (mediaType === 'application/json') {
|
|
182
|
+
const command = JSON.parse(body);
|
|
183
|
+
stepProgess.commands.push(command);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
onTestStepFinished(testStepFinished) {
|
|
187
|
+
const { testStepId, testCaseStartedId, testStepResult, timestamp } = testStepFinished;
|
|
188
|
+
const testStep = this.testStepMap.get(testStepId);
|
|
189
|
+
if (testStep.pickleStepId === undefined)
|
|
190
|
+
return;
|
|
191
|
+
const stepProgess = this.stepProgressMap.get(testStep.pickleStepId);
|
|
192
|
+
const prevStepResult = stepProgess.result;
|
|
193
|
+
stepProgess.result = {
|
|
194
|
+
status: testStepResult.status,
|
|
195
|
+
startTime: prevStepResult.startTime,
|
|
196
|
+
endTime: this.getTimeStamp(timestamp),
|
|
197
|
+
message: testStepResult.message,
|
|
198
|
+
// exception: testStepResult.exception,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
getTestCaseResult(steps) {
|
|
202
|
+
for (const step of steps) {
|
|
203
|
+
switch (step.result.status) {
|
|
204
|
+
case 'FAILED':
|
|
205
|
+
return {
|
|
206
|
+
status: step.result.status,
|
|
207
|
+
message: step.result.message,
|
|
208
|
+
// exception: step.result.exception,
|
|
209
|
+
};
|
|
210
|
+
case 'AMBIGUOUS':
|
|
211
|
+
case 'UNDEFINED':
|
|
212
|
+
case 'PENDING':
|
|
213
|
+
return {
|
|
214
|
+
status: 'FAILED',
|
|
215
|
+
message: `step "${step.text}" is ${step.result.status}`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
status: 'PASSED',
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
onTestCaseFinished(testCaseFinished) {
|
|
224
|
+
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
225
|
+
const testProgress = this.testProgressMap.get(testCaseStartedId);
|
|
226
|
+
const prevResult = testProgress.result;
|
|
227
|
+
const steps = Object.values(testProgress.steps);
|
|
228
|
+
const result = this.getTestCaseResult(steps);
|
|
229
|
+
testProgress.result = {
|
|
230
|
+
...result,
|
|
231
|
+
startTime: prevResult.startTime,
|
|
232
|
+
endTime: this.getTimeStamp(timestamp),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
onTestRunFinished(testRunFinished) {
|
|
236
|
+
const { timestamp, success, exception, message } = testRunFinished;
|
|
237
|
+
const prevResult = this.report.result;
|
|
238
|
+
this.report.result = {
|
|
239
|
+
status: success ? 'PASSED' : 'FAILED',
|
|
240
|
+
startTime: prevResult.startTime,
|
|
241
|
+
endTime: this.getTimeStamp(timestamp),
|
|
242
|
+
message,
|
|
243
|
+
// exception,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.default = ReportGenerator;
|
|
248
|
+
//# sourceMappingURL=report_generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report_generator.js","sourceRoot":"","sources":["../../../src/formatter/helpers/report_generator.ts"],"names":[],"mappings":"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","sourcesContent":["import * as messages from '@cucumber/messages'\n\n// type JsonException = messages.Exception\ntype JsonTimestamp = number //messages.Timestamp\ntype JsonStepType = 'Unknown' | 'Context' | 'Action' | 'Outcome'\n\ntype JsonResultUnknown = {\n status: 'UNKNOWN'\n}\ntype JsonResultSkipped = {\n status: 'SKIPPED'\n}\ntype JsonResultUndefined = {\n status: 'UNDEFINED'\n}\ntype JsonResultAmbiguous = {\n status: 'AMBIGUOUS'\n}\ntype JsonResultStarted = {\n status: 'STARTED'\n startTime: JsonTimestamp\n}\ntype JsonResultPending = {\n status: 'PENDING'\n startTime: JsonTimestamp\n endTime: JsonTimestamp\n}\ntype JsonResultPassed = {\n status: 'PASSED'\n startTime: JsonTimestamp\n endTime: JsonTimestamp\n}\ntype JsonResultFailed = {\n status: 'FAILED'\n startTime: JsonTimestamp\n endTime: JsonTimestamp\n message?: string\n // exception?: JsonException\n}\n\ntype JsonCommandResult = JsonResultPassed | JsonResultFailed\ntype JsonStepResult =\n | JsonResultUnknown\n | JsonResultSkipped\n | JsonResultUndefined\n | JsonResultAmbiguous\n | JsonResultStarted\n | JsonResultPending\n | JsonResultPassed\n | JsonResultFailed\ntype JsonTestResult =\n | JsonResultUnknown\n | JsonResultStarted\n | JsonResultPassed\n | JsonResultFailed\ntype JsonReportResult = JsonTestResult\n\ntype JsonCommand = {\n type: string\n value?: string\n text: string\n screenshotId?: string\n result: JsonCommandResult\n}\ntype JsonStep = {\n type: JsonStepType\n text: string\n commands: JsonCommand[]\n result: JsonStepResult\n}\n\ntype JsonTestProgress = {\n id: string\n featureName: string\n uri: string\n scenarioName: string\n parameters: Record<string, string>\n steps: JsonStep[]\n result: JsonTestResult\n}\n\nexport type JsonReport = {\n testCases: JsonTestProgress[]\n result: JsonReportResult\n}\n\nexport default class ReportGenerator {\n private report: JsonReport = {\n result: {\n status: 'UNKNOWN',\n },\n testCases: [] as JsonTestProgress[],\n }\n private gherkinDocumentMap = new Map<string, messages.GherkinDocument>()\n private pickleMap = new Map<string, messages.Pickle>()\n private testCaseMap = new Map<string, messages.TestCase>()\n private testStepMap = new Map<string, messages.TestStep>()\n private stepProgressMap = new Map<string, JsonStep>()\n private testProgressMap = new Map<string, JsonTestProgress>()\n\n reportFolder:null|string = null\n\n handleMessage(envelope: messages.Envelope) {\n const type = Object.keys(envelope)[0] as keyof messages.Envelope\n switch (type) {\n // case \"meta\": { break}\n // case \"source\": { break}\n case 'parseError': {\n const parseError = envelope[type]\n this.handleParseError(parseError)\n break\n }\n case 'gherkinDocument': {\n const doc = envelope[type]\n this.onGherkinDocument(doc)\n break\n }\n case 'pickle': {\n const pickle = envelope[type]\n this.onPickle(pickle)\n break\n }\n // case \"stepDefinition\": { break}\n // case \"hook\": { break} // Before Hook\n case 'testRunStarted': {\n const testRunStarted = envelope[type]\n this.onTestRunStarted(testRunStarted)\n break\n }\n case 'testCase': {\n const testCase = envelope[type]\n this.onTestCase(testCase)\n break\n }\n case 'testCaseStarted': {\n const testCaseStarted = envelope[type]\n this.onTestCaseStarted(testCaseStarted)\n break\n }\n case 'testStepStarted': {\n const testStepStarted = envelope[type]\n this.onTestStepStarted(testStepStarted)\n break\n }\n case 'attachment': {\n const attachment = envelope[type]\n this.onAttachment(attachment)\n break\n }\n case 'testStepFinished': {\n const testStepFinished = envelope[type]\n this.onTestStepFinished(testStepFinished)\n break\n }\n case 'testCaseFinished': {\n const testCaseFinished = envelope[type]\n this.onTestCaseFinished(testCaseFinished)\n break\n }\n // case \"hook\": { break} // After Hook\n case 'testRunFinished': {\n const testRunFinished = envelope[type]\n this.onTestRunFinished(testRunFinished)\n break\n }\n // case \"parameterType\" : { break}\n // case \"undefinedParameterType\": { break}\n }\n }\n getReport() {\n return this.report\n }\n private handleParseError(parseError: messages.ParseError) {\n const { message, source } = parseError\n const timestamp = new Date().getTime()\n this.report.result = {\n status: 'FAILED',\n startTime: timestamp,\n endTime: timestamp,\n message: message,\n }\n }\n private onGherkinDocument(doc: messages.GherkinDocument) {\n this.gherkinDocumentMap.set(doc.uri, doc)\n }\n private onPickle(pickle: messages.Pickle) {\n this.pickleMap.set(pickle.id, pickle)\n }\n private getTimeStamp(timestamp: messages.Timestamp) {\n return timestamp.seconds * 1000 + timestamp.nanos / 1000000\n }\n private onTestRunStarted(testRunStarted: messages.TestRunStarted) {\n this.report.result = {\n status: 'STARTED',\n startTime: this.getTimeStamp(testRunStarted.timestamp),\n }\n }\n private onTestCase(testCase: messages.TestCase) {\n this.testCaseMap.set(testCase.id, testCase)\n testCase.testSteps.forEach((testStep) => {\n this.testStepMap.set(testStep.id, testStep)\n })\n }\n private onTestCaseStarted(testCaseStarted: messages.TestCaseStarted) {\n const { testCaseId, id, timestamp } = testCaseStarted\n const testCase = this.testCaseMap.get(testCaseId)\n if (testCase === undefined)\n throw new Error(`testCase with id ${testCaseId} not found`)\n const pickle = this.pickleMap.get(testCase.pickleId)\n if (pickle === undefined)\n throw new Error(`pickle with id ${testCase.pickleId} not found`)\n\n const doc = this.gherkinDocumentMap.get(pickle.uri)\n if (doc === undefined)\n throw new Error(`gherkinDocument with uri ${pickle.uri} not found`)\n const featureName = doc.feature.name\n\n const scenarioName = pickle.name\n\n const steps: JsonStep[] = pickle.steps.map((step) => {\n this.stepProgressMap.set(step.id, {\n type: step.type,\n text: step.text,\n commands: [],\n result: {\n status: 'UNKNOWN',\n },\n })\n return this.stepProgressMap.get(step.id)\n })\n this.testProgressMap.set(id, {\n id,\n uri: pickle.uri,\n featureName,\n scenarioName,\n // TODO: compute parameters\n parameters: {},\n steps,\n result: {\n status: 'STARTED',\n startTime: this.getTimeStamp(timestamp),\n },\n })\n this.report.testCases.push(this.testProgressMap.get(id))\n }\n private onTestStepStarted(testStepStarted: messages.TestStepStarted) {\n const { testStepId, timestamp, testCaseStartedId } = testStepStarted\n const testStep = this.testStepMap.get(testStepId)\n if (testStep === undefined)\n throw new Error(`testStep with id ${testStepId} not found`)\n if (testStep.pickleStepId === undefined) return\n const stepProgess = this.stepProgressMap.get(testStep.pickleStepId)\n stepProgess.result = {\n status: 'STARTED',\n startTime: this.getTimeStamp(timestamp),\n }\n }\n private onAttachment(attachment: messages.Attachment) {\n const {\n testCaseStartedId,\n testStepId,\n body,\n mediaType,\n contentEncoding,\n fileName,\n source,\n url,\n } = attachment\n if (mediaType === 'text/plain') {\n this.reportFolder = body.replaceAll('\\\\', '/')\n }\n const testStep = this.testStepMap.get(testStepId)\n if (testStep.pickleStepId === undefined) return\n\n const stepProgess = this.stepProgressMap.get(testStep.pickleStepId)\n if (mediaType === 'application/json') {\n const command:JsonCommand = JSON.parse(body)\n stepProgess.commands.push(command)\n }\n }\n private onTestStepFinished(testStepFinished: messages.TestStepFinished) {\n const { testStepId, testCaseStartedId, testStepResult, timestamp } =\n testStepFinished\n const testStep = this.testStepMap.get(testStepId)\n if (testStep.pickleStepId === undefined) return\n const stepProgess = this.stepProgressMap.get(testStep.pickleStepId)\n const prevStepResult = stepProgess.result as {\n status: 'STARTED'\n startTime: JsonTimestamp\n }\n stepProgess.result = {\n status: testStepResult.status,\n startTime: prevStepResult.startTime,\n endTime: this.getTimeStamp(timestamp),\n message: testStepResult.message,\n // exception: testStepResult.exception,\n }\n }\n private getTestCaseResult(steps: JsonStep[]) {\n for (const step of steps) {\n switch (step.result.status) {\n case 'FAILED':\n return {\n status: step.result.status,\n message: step.result.message,\n // exception: step.result.exception,\n } as const\n case 'AMBIGUOUS':\n case 'UNDEFINED':\n case 'PENDING':\n return {\n status: 'FAILED',\n message: `step \"${step.text}\" is ${step.result.status}`,\n } as const\n }\n }\n return {\n status: 'PASSED',\n } as const\n }\n private onTestCaseFinished(testCaseFinished: messages.TestCaseFinished) {\n const { testCaseStartedId, timestamp } = testCaseFinished\n const testProgress = this.testProgressMap.get(testCaseStartedId)\n const prevResult = testProgress.result as {\n status: 'STARTED'\n startTime: JsonTimestamp\n }\n const steps = Object.values(testProgress.steps)\n const result = this.getTestCaseResult(steps)\n testProgress.result = {\n ...result,\n startTime: prevResult.startTime,\n endTime: this.getTimeStamp(timestamp),\n }\n }\n private onTestRunFinished(testRunFinished: messages.TestRunFinished) {\n const { timestamp, success, exception, message } = testRunFinished\n const prevResult = this.report.result as {\n status: 'STARTED'\n startTime: JsonTimestamp\n }\n this.report.result = {\n status: success ? 'PASSED' : 'FAILED',\n startTime: prevResult.startTime,\n endTime: this.getTimeStamp(timestamp),\n message,\n // exception,\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import FormData from "form-data";
|
|
2
|
+
declare class RunUploadService {
|
|
3
|
+
private runsApiBaseURL;
|
|
4
|
+
private accessToken;
|
|
5
|
+
constructor(runsApiBaseURL: string, accessToken: string);
|
|
6
|
+
createRunDocument(name: string): Promise<any>;
|
|
7
|
+
upload(formData: FormData): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export { RunUploadService };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RunUploadService = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
class RunUploadService {
|
|
9
|
+
constructor(runsApiBaseURL, accessToken) {
|
|
10
|
+
this.runsApiBaseURL = runsApiBaseURL;
|
|
11
|
+
this.accessToken = accessToken;
|
|
12
|
+
}
|
|
13
|
+
async createRunDocument(name) {
|
|
14
|
+
const runDocResult = await axios_1.default.post(this.runsApiBaseURL + "/cucumber-runs/create", {
|
|
15
|
+
name,
|
|
16
|
+
}, {
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: "Bearer " + this.accessToken,
|
|
19
|
+
"x-source": "cucumber_js"
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (runDocResult.status !== 200) {
|
|
23
|
+
throw new Error("Failed to create run document in the server");
|
|
24
|
+
}
|
|
25
|
+
if (runDocResult.data.status !== true) {
|
|
26
|
+
throw new Error("Failed to create run document in the server");
|
|
27
|
+
}
|
|
28
|
+
return runDocResult.data.run;
|
|
29
|
+
}
|
|
30
|
+
async upload(formData) {
|
|
31
|
+
const response = await axios_1.default.post(this.runsApiBaseURL + "/cucumber-runs/upload", formData, {
|
|
32
|
+
headers: {
|
|
33
|
+
...formData.getHeaders(),
|
|
34
|
+
Authorization: "Bearer " + this.accessToken,
|
|
35
|
+
"x-source": "cucumber_js"
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
if (response.status !== 200) {
|
|
39
|
+
throw new Error("Failed to upload run to the server");
|
|
40
|
+
}
|
|
41
|
+
if (response.data.status !== true) {
|
|
42
|
+
throw new Error("Failed to upload run to the server");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.RunUploadService = RunUploadService;
|
|
47
|
+
//# sourceMappingURL=upload_serivce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload_serivce.js","sourceRoot":"","sources":["../../../src/formatter/helpers/upload_serivce.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,MAAM,gBAAgB;IAClB,YAAoB,cAAqB,EAAU,WAAkB;QAAjD,mBAAc,GAAd,cAAc,CAAO;QAAU,gBAAW,GAAX,WAAW,CAAO;IACrE,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,IAAW;QACjC,MAAM,YAAY,GAAG,MAAM,eAAK,CAAC,IAAI,CACnC,IAAI,CAAC,cAAc,GAAG,uBAAuB,EAC7C;YACE,IAAI;SACL,EACD;YACE,OAAO,EAAE;gBACP,aAAa,EAAE,SAAS,GAAG,IAAI,CAAC,WAAW;gBAC3C,UAAU,EAAC,aAAa;aACzB;SACF,CACF,CAAC;QACF,IAAG,YAAY,CAAC,MAAM,KAAK,GAAG,EAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;SAChE;QACD,IAAG,YAAY,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,EAAC;YACnC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;SAChE;QACD,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,CAAA;IAC9B,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,QAAiB;QAC1B,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,uBAAuB,EAAE,QAAQ,EAAE;YACvF,OAAO,EAAE;gBACP,GAAG,QAAQ,CAAC,UAAU,EAAE;gBACxB,aAAa,EAAE,SAAS,GAAG,IAAI,CAAC,WAAW;gBAC3C,UAAU,EAAC,aAAa;aACzB;SACF,CAAC,CAAA;QACF,IAAG,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAC;YACzB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACvD;QACD,IAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,EAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACvD;IACP,CAAC;CACJ;AACO,4CAAgB","sourcesContent":["import axios from \"axios\";\nimport FormData from \"form-data\";\nclass RunUploadService {\n constructor(private runsApiBaseURL:string, private accessToken:string){\n }\n async createRunDocument(name:string){\n const runDocResult = await axios.post(\n this.runsApiBaseURL + \"/cucumber-runs/create\",\n {\n name,\n },\n {\n headers: {\n Authorization: \"Bearer \" + this.accessToken,\n \"x-source\":\"cucumber_js\"\n },\n }\n );\n if(runDocResult.status !== 200){\n throw new Error(\"Failed to create run document in the server\");\n }\n if(runDocResult.data.status !== true){\n throw new Error(\"Failed to create run document in the server\");\n }\n return runDocResult.data.run\n }\n async upload(formData:FormData){\n const response = await axios.post(this.runsApiBaseURL + \"/cucumber-runs/upload\", formData, {\n headers: {\n ...formData.getHeaders(),\n Authorization: \"Bearer \" + this.accessToken,\n \"x-source\":\"cucumber_js\"\n },\n })\n if(response.status !== 200){\n throw new Error(\"Failed to upload run to the server\");\n }\n if(response.data.status !== true){\n throw new Error(\"Failed to upload run to the server\");\n }\n }\n}\nexport {RunUploadService}"]}
|
package/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.0.
|
|
1
|
+
export declare const version = "1.0.5";
|
package/lib/version.js
CHANGED
package/lib/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,OAAO,GAAG,OAAO,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '1.0.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,OAAO,GAAG,OAAO,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '1.0.5'\n"]}
|
package/package.json
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
"gherkin",
|
|
9
9
|
"tests"
|
|
10
10
|
],
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
"version": "1.0.5",
|
|
13
|
+
|
|
12
14
|
"homepage": "https://github.com/blinq-io/cucumber-js",
|
|
13
15
|
"author": "blinq.io",
|
|
14
16
|
"contributors": [
|
|
@@ -61,6 +63,7 @@
|
|
|
61
63
|
"@cucumber/tag-expressions": "5.0.1",
|
|
62
64
|
"@faker-js/faker": "^8.0.2",
|
|
63
65
|
"assertion-error-formatter": "^3.0.0",
|
|
66
|
+
"axios": "^1.6.2",
|
|
64
67
|
"capital-case": "^1.0.4",
|
|
65
68
|
"chalk": "^4.1.2",
|
|
66
69
|
"cli-table3": "0.6.3",
|
|
@@ -73,6 +76,7 @@
|
|
|
73
76
|
"indent-string": "^4.0.0",
|
|
74
77
|
"is-installed-globally": "^0.4.0",
|
|
75
78
|
"is-stream": "^2.0.0",
|
|
79
|
+
"jszip": "^3.10.1",
|
|
76
80
|
"knuth-shuffle-seeded": "^1.0.6",
|
|
77
81
|
"lodash.merge": "^4.6.2",
|
|
78
82
|
"lodash.mergewith": "^4.6.2",
|
|
@@ -169,7 +173,7 @@
|
|
|
169
173
|
"prelint-code": "npm run build-local",
|
|
170
174
|
"precck-test": "npm run build-local",
|
|
171
175
|
"prefeature-test": "npm run build-local",
|
|
172
|
-
"prepublishOnly": "rm -rf lib && npm run build-local",
|
|
176
|
+
"prepublishOnly": "shx rm -rf lib && npm run build-local",
|
|
173
177
|
"pretest-coverage": "npm run build-local",
|
|
174
178
|
"pretypes-test": "npm run build-local",
|
|
175
179
|
"test-coverage": "nyc --silent mocha 'src/**/*_spec.ts' 'compatibility/**/*_spec.ts' && nyc --silent --no-clean node bin/cucumber.js --tags \"not @source-mapping\" && nyc report --reporter=lcov",
|