@dev-blinq/cucumber-js 1.0.8 → 1.0.10
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 +4 -0
- package/lib/formatter/bvt_formatter.js +44 -2
- package/lib/formatter/bvt_formatter.js.map +1 -1
- package/lib/formatter/helpers/report_generator.d.ts +19 -19
- package/lib/formatter/helpers/report_generator.js +52 -36
- package/lib/formatter/helpers/report_generator.js.map +1 -1
- 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 +3 -1
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import Formatter, { IFormatterOptions } from '.';
|
|
2
|
+
import { JsonReport } from './helpers/report_generator';
|
|
2
3
|
export default class BVTFormatter extends Formatter {
|
|
3
4
|
private reportGenerator;
|
|
5
|
+
private uploadService;
|
|
4
6
|
constructor(options: IFormatterOptions);
|
|
7
|
+
uploadRun(report: JsonReport): Promise<void>;
|
|
8
|
+
createZip(reportFolder: string | null, report: JsonReport): Promise<string>;
|
|
5
9
|
}
|
|
@@ -5,17 +5,59 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const _1 = __importDefault(require("."));
|
|
7
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
|
+
if (!REPORT_SERVICE_URL || !REPORT_SERVICE_TOKEN) {
|
|
16
|
+
throw new Error("REPORT_SERVICE_URL and REPORT_SERVICE_TOKEN must be set");
|
|
17
|
+
}
|
|
8
18
|
class BVTFormatter extends _1.default {
|
|
9
19
|
constructor(options) {
|
|
10
20
|
super(options);
|
|
11
21
|
this.reportGenerator = new report_generator_1.default();
|
|
12
|
-
|
|
22
|
+
this.uploadService = new upload_serivce_1.RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);
|
|
23
|
+
options.eventBroadcaster.on('envelope', async (envelope) => {
|
|
13
24
|
this.reportGenerator.handleMessage(envelope);
|
|
14
25
|
if (envelope.testRunFinished) {
|
|
15
|
-
this.
|
|
26
|
+
const report = this.reportGenerator.getReport();
|
|
27
|
+
this.log(JSON.stringify(report, null, 2));
|
|
28
|
+
await this.uploadRun(report);
|
|
16
29
|
}
|
|
17
30
|
});
|
|
18
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
|
+
console.log(zipPath);
|
|
42
|
+
formData.append(runDocId, fs_1.default.readFileSync(zipPath), "report.zip");
|
|
43
|
+
await this.uploadService.upload(formData);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
async createZip(reportFolder, report) {
|
|
47
|
+
const zip = new jszip_1.default();
|
|
48
|
+
zip.file("report.json", JSON.stringify(report, null, 2));
|
|
49
|
+
const folder = zip.folder("screenshots");
|
|
50
|
+
const files = fs_1.default.readdirSync(reportFolder);
|
|
51
|
+
files.forEach((file) => {
|
|
52
|
+
folder.file(file, fs_1.default.readFileSync(path_1.default.join(reportFolder, file)));
|
|
53
|
+
});
|
|
54
|
+
const zipBuffer = await zip.generateAsync({ type: "nodebuffer" });
|
|
55
|
+
// save zip file
|
|
56
|
+
const zipPath = path_1.default.join(reportFolder, 'report.zip');
|
|
57
|
+
fs_1.default.writeFileSync(zipPath, zipBuffer);
|
|
58
|
+
fs_1.default.writeFileSync(path_1.default.join(reportFolder, 'report.json'), JSON.stringify(report, null, 2));
|
|
59
|
+
return zipPath;
|
|
60
|
+
}
|
|
19
61
|
}
|
|
20
62
|
exports.default = BVTFormatter;
|
|
21
63
|
//# sourceMappingURL=bvt_formatter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bvt_formatter.js","sourceRoot":"","sources":["../../src/formatter/bvt_formatter.ts"],"names":[],"mappings":";;;;;AACA,yCAAgD;AAChD,
|
|
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;\nif(!REPORT_SERVICE_URL || !REPORT_SERVICE_TOKEN){\n throw new Error(\"REPORT_SERVICE_URL and REPORT_SERVICE_TOKEN must be set\")\n}\n\nexport default class BVTFormatter extends Formatter {\n private reportGenerator = new ReportGenerator()\n private uploadService = new RunUploadService(REPORT_SERVICE_URL, REPORT_SERVICE_TOKEN);\n constructor(options: IFormatterOptions) {\n super(options)\n options.eventBroadcaster.on('envelope', 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 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 console.log(zipPath);\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(reportFolder);\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(path.join(reportFolder,'report.json'), JSON.stringify(report, null, 2));\n return zipPath\n }\n}"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as messages from '@cucumber/messages';
|
|
2
|
-
type JsonTimestamp =
|
|
3
|
-
type
|
|
4
|
-
type JsonStepType = messages.PickleStepType;
|
|
2
|
+
type JsonTimestamp = number;
|
|
3
|
+
type JsonStepType = 'Unknown' | 'Context' | 'Action' | 'Outcome';
|
|
5
4
|
type JsonResultUnknown = {
|
|
6
5
|
status: 'UNKNOWN';
|
|
7
6
|
};
|
|
@@ -16,24 +15,23 @@ type JsonResultAmbiguous = {
|
|
|
16
15
|
};
|
|
17
16
|
type JsonResultStarted = {
|
|
18
17
|
status: 'STARTED';
|
|
19
|
-
|
|
18
|
+
startTime: JsonTimestamp;
|
|
20
19
|
};
|
|
21
20
|
type JsonResultPending = {
|
|
22
21
|
status: 'PENDING';
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
startTime: JsonTimestamp;
|
|
23
|
+
endTime: JsonTimestamp;
|
|
25
24
|
};
|
|
26
25
|
type JsonResultPassed = {
|
|
27
26
|
status: 'PASSED';
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
startTime: JsonTimestamp;
|
|
28
|
+
endTime: JsonTimestamp;
|
|
30
29
|
};
|
|
31
30
|
type JsonResultFailed = {
|
|
32
31
|
status: 'FAILED';
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
startTime: JsonTimestamp;
|
|
33
|
+
endTime: JsonTimestamp;
|
|
35
34
|
message?: string;
|
|
36
|
-
exception?: JsonException;
|
|
37
35
|
};
|
|
38
36
|
type JsonCommandResult = JsonResultPassed | JsonResultFailed;
|
|
39
37
|
type JsonStepResult = JsonResultUnknown | JsonResultSkipped | JsonResultUndefined | JsonResultAmbiguous | JsonResultStarted | JsonResultPending | JsonResultPassed | JsonResultFailed;
|
|
@@ -41,11 +39,9 @@ type JsonTestResult = JsonResultUnknown | JsonResultStarted | JsonResultPassed |
|
|
|
41
39
|
type JsonReportResult = JsonTestResult;
|
|
42
40
|
type JsonCommand = {
|
|
43
41
|
type: string;
|
|
42
|
+
value?: string;
|
|
44
43
|
text: string;
|
|
45
|
-
|
|
46
|
-
reasoning?: string;
|
|
47
|
-
description: string;
|
|
48
|
-
value: string;
|
|
44
|
+
screenshotPath?: string;
|
|
49
45
|
result: JsonCommandResult;
|
|
50
46
|
};
|
|
51
47
|
type JsonStep = {
|
|
@@ -60,24 +56,28 @@ type JsonTestProgress = {
|
|
|
60
56
|
uri: string;
|
|
61
57
|
scenarioName: string;
|
|
62
58
|
parameters: Record<string, string>;
|
|
63
|
-
steps:
|
|
59
|
+
steps: JsonStep[];
|
|
64
60
|
result: JsonTestResult;
|
|
65
61
|
};
|
|
66
|
-
type JsonReport = {
|
|
67
|
-
|
|
62
|
+
export type JsonReport = {
|
|
63
|
+
testCases: JsonTestProgress[];
|
|
68
64
|
result: JsonReportResult;
|
|
69
65
|
};
|
|
70
66
|
export default class ReportGenerator {
|
|
71
67
|
private report;
|
|
72
68
|
private gherkinDocumentMap;
|
|
73
69
|
private pickleMap;
|
|
74
|
-
private pickleStepMap;
|
|
75
70
|
private testCaseMap;
|
|
76
71
|
private testStepMap;
|
|
72
|
+
private stepProgressMap;
|
|
73
|
+
private testProgressMap;
|
|
74
|
+
reportFolder: null | string;
|
|
77
75
|
handleMessage(envelope: messages.Envelope): void;
|
|
78
76
|
getReport(): JsonReport;
|
|
77
|
+
private handleParseError;
|
|
79
78
|
private onGherkinDocument;
|
|
80
79
|
private onPickle;
|
|
80
|
+
private getTimeStamp;
|
|
81
81
|
private onTestRunStarted;
|
|
82
82
|
private onTestCase;
|
|
83
83
|
private onTestCaseStarted;
|
|
@@ -6,13 +6,15 @@ class ReportGenerator {
|
|
|
6
6
|
result: {
|
|
7
7
|
status: 'UNKNOWN',
|
|
8
8
|
},
|
|
9
|
-
|
|
9
|
+
testCases: [],
|
|
10
10
|
};
|
|
11
11
|
this.gherkinDocumentMap = new Map();
|
|
12
12
|
this.pickleMap = new Map();
|
|
13
|
-
this.pickleStepMap = new Map();
|
|
14
13
|
this.testCaseMap = new Map();
|
|
15
14
|
this.testStepMap = new Map();
|
|
15
|
+
this.stepProgressMap = new Map();
|
|
16
|
+
this.testProgressMap = new Map();
|
|
17
|
+
this.reportFolder = null;
|
|
16
18
|
}
|
|
17
19
|
handleMessage(envelope) {
|
|
18
20
|
const type = Object.keys(envelope)[0];
|
|
@@ -21,8 +23,7 @@ class ReportGenerator {
|
|
|
21
23
|
// case "source": { break}
|
|
22
24
|
case 'parseError': {
|
|
23
25
|
const parseError = envelope[type];
|
|
24
|
-
|
|
25
|
-
// TODO: handle parseError
|
|
26
|
+
this.handleParseError(parseError);
|
|
26
27
|
break;
|
|
27
28
|
}
|
|
28
29
|
case 'gherkinDocument': {
|
|
@@ -85,19 +86,29 @@ class ReportGenerator {
|
|
|
85
86
|
getReport() {
|
|
86
87
|
return this.report;
|
|
87
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
|
+
}
|
|
88
99
|
onGherkinDocument(doc) {
|
|
89
100
|
this.gherkinDocumentMap.set(doc.uri, doc);
|
|
90
101
|
}
|
|
91
102
|
onPickle(pickle) {
|
|
92
103
|
this.pickleMap.set(pickle.id, pickle);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
104
|
+
}
|
|
105
|
+
getTimeStamp(timestamp) {
|
|
106
|
+
return timestamp.seconds * 1000 + timestamp.nanos / 1000000;
|
|
96
107
|
}
|
|
97
108
|
onTestRunStarted(testRunStarted) {
|
|
98
109
|
this.report.result = {
|
|
99
110
|
status: 'STARTED',
|
|
100
|
-
|
|
111
|
+
startTime: this.getTimeStamp(testRunStarted.timestamp),
|
|
101
112
|
};
|
|
102
113
|
}
|
|
103
114
|
onTestCase(testCase) {
|
|
@@ -119,18 +130,18 @@ class ReportGenerator {
|
|
|
119
130
|
throw new Error(`gherkinDocument with uri ${pickle.uri} not found`);
|
|
120
131
|
const featureName = doc.feature.name;
|
|
121
132
|
const scenarioName = pickle.name;
|
|
122
|
-
const steps = pickle.steps.
|
|
123
|
-
|
|
133
|
+
const steps = pickle.steps.map((step) => {
|
|
134
|
+
this.stepProgressMap.set(step.id, {
|
|
124
135
|
type: step.type,
|
|
125
136
|
text: step.text,
|
|
126
137
|
commands: [],
|
|
127
138
|
result: {
|
|
128
139
|
status: 'UNKNOWN',
|
|
129
140
|
},
|
|
130
|
-
};
|
|
131
|
-
return
|
|
132
|
-
}
|
|
133
|
-
this.
|
|
141
|
+
});
|
|
142
|
+
return this.stepProgressMap.get(step.id);
|
|
143
|
+
});
|
|
144
|
+
this.testProgressMap.set(id, {
|
|
134
145
|
id,
|
|
135
146
|
uri: pickle.uri,
|
|
136
147
|
featureName,
|
|
@@ -140,9 +151,10 @@ class ReportGenerator {
|
|
|
140
151
|
steps,
|
|
141
152
|
result: {
|
|
142
153
|
status: 'STARTED',
|
|
143
|
-
|
|
154
|
+
startTime: this.getTimeStamp(timestamp),
|
|
144
155
|
},
|
|
145
|
-
};
|
|
156
|
+
});
|
|
157
|
+
this.report.testCases.push(this.testProgressMap.get(id));
|
|
146
158
|
}
|
|
147
159
|
onTestStepStarted(testStepStarted) {
|
|
148
160
|
const { testStepId, timestamp, testCaseStartedId } = testStepStarted;
|
|
@@ -151,22 +163,27 @@ class ReportGenerator {
|
|
|
151
163
|
throw new Error(`testStep with id ${testStepId} not found`);
|
|
152
164
|
if (testStep.pickleStepId === undefined)
|
|
153
165
|
return;
|
|
154
|
-
const
|
|
155
|
-
const stepProgess = this.report.testCaseMap[testCaseStartedId].steps[pickleStep.id];
|
|
166
|
+
const stepProgess = this.stepProgressMap.get(testStep.pickleStepId);
|
|
156
167
|
stepProgess.result = {
|
|
157
168
|
status: 'STARTED',
|
|
158
|
-
|
|
169
|
+
startTime: this.getTimeStamp(timestamp),
|
|
159
170
|
};
|
|
160
|
-
this.report.testCaseMap[testCaseStartedId].steps[pickleStep.id] =
|
|
161
|
-
stepProgess;
|
|
162
171
|
}
|
|
163
172
|
onAttachment(attachment) {
|
|
164
173
|
const { testCaseStartedId, testStepId, body, mediaType, contentEncoding, fileName, source, url, } = attachment;
|
|
174
|
+
if (mediaType === 'text/plain') {
|
|
175
|
+
this.reportFolder = body.replaceAll('\\', '/');
|
|
176
|
+
}
|
|
165
177
|
const testStep = this.testStepMap.get(testStepId);
|
|
166
|
-
|
|
167
|
-
|
|
178
|
+
if (testStep.pickleStepId === undefined)
|
|
179
|
+
return;
|
|
180
|
+
const stepProgess = this.stepProgressMap.get(testStep.pickleStepId);
|
|
168
181
|
if (mediaType === 'application/json') {
|
|
169
|
-
|
|
182
|
+
const command = JSON.parse(body);
|
|
183
|
+
command.screenshotPath = command.screenshotPath
|
|
184
|
+
.replaceAll('\\', '/')
|
|
185
|
+
.replace(this.reportFolder, '');
|
|
186
|
+
stepProgess.commands.push(command);
|
|
170
187
|
}
|
|
171
188
|
}
|
|
172
189
|
onTestStepFinished(testStepFinished) {
|
|
@@ -174,15 +191,14 @@ class ReportGenerator {
|
|
|
174
191
|
const testStep = this.testStepMap.get(testStepId);
|
|
175
192
|
if (testStep.pickleStepId === undefined)
|
|
176
193
|
return;
|
|
177
|
-
const
|
|
178
|
-
const stepProgess = this.report.testCaseMap[testCaseStartedId].steps[pickleStep.id];
|
|
194
|
+
const stepProgess = this.stepProgressMap.get(testStep.pickleStepId);
|
|
179
195
|
const prevStepResult = stepProgess.result;
|
|
180
196
|
stepProgess.result = {
|
|
181
197
|
status: testStepResult.status,
|
|
182
|
-
|
|
183
|
-
|
|
198
|
+
startTime: prevStepResult.startTime,
|
|
199
|
+
endTime: this.getTimeStamp(timestamp),
|
|
184
200
|
message: testStepResult.message,
|
|
185
|
-
exception: testStepResult.exception,
|
|
201
|
+
// exception: testStepResult.exception,
|
|
186
202
|
};
|
|
187
203
|
}
|
|
188
204
|
getTestCaseResult(steps) {
|
|
@@ -192,7 +208,7 @@ class ReportGenerator {
|
|
|
192
208
|
return {
|
|
193
209
|
status: step.result.status,
|
|
194
210
|
message: step.result.message,
|
|
195
|
-
exception: step.result.exception,
|
|
211
|
+
// exception: step.result.exception,
|
|
196
212
|
};
|
|
197
213
|
case 'AMBIGUOUS':
|
|
198
214
|
case 'UNDEFINED':
|
|
@@ -209,14 +225,14 @@ class ReportGenerator {
|
|
|
209
225
|
}
|
|
210
226
|
onTestCaseFinished(testCaseFinished) {
|
|
211
227
|
const { testCaseStartedId, timestamp } = testCaseFinished;
|
|
212
|
-
const testProgress = this.
|
|
228
|
+
const testProgress = this.testProgressMap.get(testCaseStartedId);
|
|
213
229
|
const prevResult = testProgress.result;
|
|
214
230
|
const steps = Object.values(testProgress.steps);
|
|
215
231
|
const result = this.getTestCaseResult(steps);
|
|
216
232
|
testProgress.result = {
|
|
217
233
|
...result,
|
|
218
|
-
|
|
219
|
-
|
|
234
|
+
startTime: prevResult.startTime,
|
|
235
|
+
endTime: this.getTimeStamp(timestamp),
|
|
220
236
|
};
|
|
221
237
|
}
|
|
222
238
|
onTestRunFinished(testRunFinished) {
|
|
@@ -224,10 +240,10 @@ class ReportGenerator {
|
|
|
224
240
|
const prevResult = this.report.result;
|
|
225
241
|
this.report.result = {
|
|
226
242
|
status: success ? 'PASSED' : 'FAILED',
|
|
227
|
-
|
|
228
|
-
|
|
243
|
+
startTime: prevResult.startTime,
|
|
244
|
+
endTime: this.getTimeStamp(timestamp),
|
|
229
245
|
message,
|
|
230
|
-
exception,
|
|
246
|
+
// exception,
|
|
231
247
|
};
|
|
232
248
|
}
|
|
233
249
|
}
|
|
@@ -1 +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\ntype JsonTimestamp = messages.Timestamp\ntype JsonException = messages.Exception\ntype JsonStepType = messages.PickleStepType\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 startTimestamp: JsonTimestamp\n}\ntype JsonResultPending = {\n status: 'PENDING'\n startTimestamp: JsonTimestamp\n endTimestamp: JsonTimestamp\n}\ntype JsonResultPassed = {\n status: 'PASSED'\n startTimestamp: JsonTimestamp\n endTimestamp: JsonTimestamp\n}\ntype JsonResultFailed = {\n status: 'FAILED'\n startTimestamp: JsonTimestamp\n endTimestamp: 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 text: string\n screenShotId?: string\n reasoning?: string\n description: string\n value: string\n result: JsonCommandResult\n}\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: Record<string, JsonStep>\n result: JsonTestResult\n}\n\ntype JsonReport = {\n testCaseMap: Record<string, JsonTestProgress>\n result: JsonReportResult\n}\n\nexport default class ReportGenerator {\n private report: JsonReport = {\n result: {\n status: 'UNKNOWN',\n },\n testCaseMap: {},\n }\n private gherkinDocumentMap = new Map<string, messages.GherkinDocument>()\n private pickleMap = new Map<string, messages.Pickle>()\n private pickleStepMap = new Map<string, messages.PickleStep>()\n private testCaseMap = new Map<string, messages.TestCase>()\n private testStepMap = new Map<string, messages.TestStep>()\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 // console.log(parseError)\n // TODO: handle 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 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 pickle.steps.forEach((step) => {\n this.pickleStepMap.set(step.id, step)\n })\n }\n private onTestRunStarted(testRunStarted: messages.TestRunStarted) {\n this.report.result = {\n status: 'STARTED',\n startTimestamp: 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 const steps = pickle.steps.reduce((s, step) => {\n s[step.id] = {\n type: step.type,\n text: step.text,\n commands: [],\n result: {\n status: 'UNKNOWN',\n },\n }\n return s\n }, {} as JsonTestProgress['steps'])\n\n this.report.testCaseMap[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 startTimestamp: timestamp,\n },\n }\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 pickleStep = this.pickleStepMap.get(testStep.pickleStepId)\n const stepProgess =\n this.report.testCaseMap[testCaseStartedId].steps[pickleStep.id]\n stepProgess.result = {\n status: 'STARTED',\n startTimestamp: timestamp,\n }\n this.report.testCaseMap[testCaseStartedId].steps[pickleStep.id] =\n stepProgess\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 const testStep = this.testStepMap.get(testStepId)\n const pickleStep = this.pickleStepMap.get(testStep.pickleStepId)\n const stepProgess =\n this.report.testCaseMap[testCaseStartedId].steps[pickleStep.id]\n if (mediaType === 'application/json') {\n stepProgess.commands.push(JSON.parse(body) as JsonCommand)\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 pickleStep = this.pickleStepMap.get(testStep.pickleStepId)\n const stepProgess =\n this.report.testCaseMap[testCaseStartedId].steps[pickleStep.id]\n const prevStepResult = stepProgess.result as {\n status: 'STARTED'\n startTimestamp: JsonTimestamp\n }\n stepProgess.result = {\n status: testStepResult.status,\n startTimestamp: prevStepResult.startTimestamp,\n endTimestamp: 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.report.testCaseMap[testCaseStartedId]\n const prevResult = testProgress.result as {\n status: 'STARTED'\n startTimestamp: JsonTimestamp\n }\n const steps = Object.values(testProgress.steps)\n const result = this.getTestCaseResult(steps)\n testProgress.result = {\n ...result,\n startTimestamp: prevResult.startTimestamp,\n endTimestamp: 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 startTimestamp: JsonTimestamp\n }\n this.report.result = {\n status: success ? 'PASSED' : 'FAILED',\n startTimestamp: prevResult.startTimestamp,\n endTimestamp: timestamp,\n message,\n exception,\n }\n }\n}\n"]}
|
|
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 screenshotPath?: 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 = JSON.parse(body)\n command.screenshotPath = command.screenshotPath\n .replaceAll('\\\\', '/')\n .replace(this.reportFolder, '')\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\";\r\nimport FormData from \"form-data\";\r\nclass RunUploadService {\r\n constructor(private runsApiBaseURL:string, private accessToken:string){\r\n }\r\n async createRunDocument(name:string){\r\n const runDocResult = await axios.post(\r\n this.runsApiBaseURL + \"/cucumber-runs/create\",\r\n {\r\n name,\r\n },\r\n {\r\n headers: {\r\n Authorization: \"Bearer \" + this.accessToken,\r\n \"x-source\":\"cucumber_js\"\r\n },\r\n }\r\n );\r\n if(runDocResult.status !== 200){\r\n throw new Error(\"Failed to create run document in the server\");\r\n }\r\n if(runDocResult.data.status !== true){\r\n throw new Error(\"Failed to create run document in the server\");\r\n }\r\n return runDocResult.data.run\r\n }\r\n async upload(formData:FormData){\r\n const response = await axios.post(this.runsApiBaseURL + \"/cucumber-runs/upload\", formData, {\r\n headers: {\r\n ...formData.getHeaders(),\r\n Authorization: \"Bearer \" + this.accessToken,\r\n \"x-source\":\"cucumber_js\"\r\n },\r\n })\r\n if(response.status !== 200){\r\n throw new Error(\"Failed to upload run to the server\");\r\n }\r\n if(response.data.status !== true){\r\n throw new Error(\"Failed to upload run to the server\");\r\n }\r\n }\r\n}\r\nexport {RunUploadService}"]}
|
package/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.0.
|
|
1
|
+
export declare const version = "1.0.10";
|
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,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,OAAO,GAAG,QAAQ,CAAA","sourcesContent":["// Generated by genversion.\nexport const version = '1.0.10'\n"]}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"gherkin",
|
|
9
9
|
"tests"
|
|
10
10
|
],
|
|
11
|
-
"version": "1.0.
|
|
11
|
+
"version": "1.0.10",
|
|
12
12
|
"homepage": "https://github.com/blinq-io/cucumber-js",
|
|
13
13
|
"author": "blinq.io",
|
|
14
14
|
"contributors": [
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"@cucumber/tag-expressions": "5.0.1",
|
|
62
62
|
"@faker-js/faker": "^8.0.2",
|
|
63
63
|
"assertion-error-formatter": "^3.0.0",
|
|
64
|
+
"axios": "^1.6.2",
|
|
64
65
|
"capital-case": "^1.0.4",
|
|
65
66
|
"chalk": "^4.1.2",
|
|
66
67
|
"cli-table3": "0.6.3",
|
|
@@ -73,6 +74,7 @@
|
|
|
73
74
|
"indent-string": "^4.0.0",
|
|
74
75
|
"is-installed-globally": "^0.4.0",
|
|
75
76
|
"is-stream": "^2.0.0",
|
|
77
|
+
"jszip": "^3.10.1",
|
|
76
78
|
"knuth-shuffle-seeded": "^1.0.6",
|
|
77
79
|
"lodash.merge": "^4.6.2",
|
|
78
80
|
"lodash.mergewith": "^4.6.2",
|