@wdio/allure-reporter 8.0.13 → 8.1.0
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/build/common/api.d.ts +108 -0
- package/build/common/api.d.ts.map +1 -0
- package/build/common/api.js +139 -0
- package/build/compoundError.js +3 -5
- package/build/constants.d.ts +7 -8
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +6 -7
- package/build/index.d.ts +3 -148
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -596
- package/build/reporter.d.ts +70 -0
- package/build/reporter.d.ts.map +1 -0
- package/build/reporter.js +485 -0
- package/build/types.d.ts +6 -0
- package/build/types.d.ts.map +1 -1
- package/build/types.js +1 -1
- package/build/utils.d.ts +3 -10
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +8 -15
- package/cjs/common/api.js +155 -0
- package/cjs/constants.js +40 -0
- package/cjs/package.json +3 -0
- package/cjs/types.js +9 -0
- package/package.json +17 -8
- package/tsconfig.cjs.json +12 -0
package/build/index.js
CHANGED
|
@@ -1,597 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { stringify } from 'csv-stringify/sync';
|
|
3
|
-
import WDIOReporter from '@wdio/reporter';
|
|
4
|
-
import { getTestStatus, isEmpty, tellReporter, isMochaEachHooks, getErrorFromFailedTest, isMochaAllHooks, getLinkByTemplate, attachConsoleLogs } from './utils.js';
|
|
5
|
-
import { events, PASSED, PENDING, SKIPPED, stepStatuses } from './constants.js';
|
|
6
|
-
const require = createRequire(import.meta.url);
|
|
7
|
-
/**
|
|
8
|
-
* Allure v1 has no proper TS support
|
|
9
|
-
* ToDo(Christian): update to Allure v2 (https://github.com/webdriverio/webdriverio/issues/6313)
|
|
10
|
-
*/
|
|
11
|
-
const Allure = require('allure-js-commons');
|
|
12
|
-
const Step = require('allure-js-commons/beans/step.js');
|
|
13
|
-
class AllureReporter extends WDIOReporter {
|
|
14
|
-
_allure;
|
|
15
|
-
_capabilities;
|
|
16
|
-
_isMultiremote;
|
|
17
|
-
_config;
|
|
18
|
-
_lastScreenshot;
|
|
19
|
-
_options;
|
|
20
|
-
_consoleOutput;
|
|
21
|
-
_originalStdoutWrite;
|
|
22
|
-
_addConsoleLogs;
|
|
23
|
-
_startedFeatures = [];
|
|
24
|
-
constructor(options = {}) {
|
|
25
|
-
const outputDir = options.outputDir || 'allure-results';
|
|
26
|
-
super({
|
|
27
|
-
...options,
|
|
28
|
-
outputDir,
|
|
29
|
-
});
|
|
30
|
-
this._addConsoleLogs = false;
|
|
31
|
-
this._consoleOutput = '';
|
|
32
|
-
this._originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
33
|
-
this._allure = new Allure();
|
|
34
|
-
this._capabilities = {};
|
|
35
|
-
this._options = options;
|
|
36
|
-
this._allure.setOptions({ targetDir: outputDir });
|
|
37
|
-
this.registerListeners();
|
|
38
|
-
this._lastScreenshot = undefined;
|
|
39
|
-
let processObj = process;
|
|
40
|
-
if (options.addConsoleLogs || this._addConsoleLogs) {
|
|
41
|
-
processObj.stdout.write = (chunk, encoding, callback) => {
|
|
42
|
-
if (typeof chunk === 'string' && !chunk.includes('mwebdriver')) {
|
|
43
|
-
this._consoleOutput += chunk;
|
|
44
|
-
}
|
|
45
|
-
return this._originalStdoutWrite(chunk, encoding, callback);
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
registerListeners() {
|
|
50
|
-
process.on(events.addLabel, this.addLabel.bind(this));
|
|
51
|
-
process.on(events.addFeature, this.addFeature.bind(this));
|
|
52
|
-
process.on(events.addStory, this.addStory.bind(this));
|
|
53
|
-
process.on(events.addSeverity, this.addSeverity.bind(this));
|
|
54
|
-
process.on(events.addIssue, this.addIssue.bind(this));
|
|
55
|
-
process.on(events.addTestId, this.addTestId.bind(this));
|
|
56
|
-
process.on(events.addEnvironment, this.addEnvironment.bind(this));
|
|
57
|
-
process.on(events.addAttachment, this.addAttachment.bind(this));
|
|
58
|
-
process.on(events.addDescription, this.addDescription.bind(this));
|
|
59
|
-
process.on(events.startStep, this.startStep.bind(this));
|
|
60
|
-
process.on(events.endStep, this.endStep.bind(this));
|
|
61
|
-
process.on(events.addStep, this.addStep.bind(this));
|
|
62
|
-
process.on(events.addArgument, this.addArgument.bind(this));
|
|
63
|
-
}
|
|
64
|
-
onRunnerStart(runner) {
|
|
65
|
-
this._config = runner.config;
|
|
66
|
-
this._capabilities = runner.capabilities;
|
|
67
|
-
this._isMultiremote = runner.isMultiremote || false;
|
|
68
|
-
}
|
|
69
|
-
onSuiteStart(suite) {
|
|
70
|
-
const isFeature = suite.type === 'feature';
|
|
71
|
-
if (!this._options.useCucumberStepReporter) {
|
|
72
|
-
const currentSuite = this._allure.getCurrentSuite();
|
|
73
|
-
const prefix = currentSuite ? currentSuite.name + ': ' : '';
|
|
74
|
-
this._allure.startSuite(prefix + suite.title);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
// handle cucumber features as allure "suite"
|
|
78
|
-
if (isFeature) {
|
|
79
|
-
// temp solution to keep suites stats index for saving allure test ops feature based structure
|
|
80
|
-
this._startedFeatures.push(suite);
|
|
81
|
-
this._allure.startSuite(suite.title);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
// handle cucumber scenario as allure "case" instead of "suite"
|
|
85
|
-
this._allure.startCase(suite.title);
|
|
86
|
-
const currentTest = this._allure.getCurrentTest();
|
|
87
|
-
this.getLabels(suite).forEach(({ name, value }) => {
|
|
88
|
-
currentTest.addLabel(name, value);
|
|
89
|
-
});
|
|
90
|
-
if (suite.description) {
|
|
91
|
-
this.addDescription(suite);
|
|
92
|
-
}
|
|
93
|
-
this.setCaseParameters(suite.cid, suite.parent);
|
|
94
|
-
}
|
|
95
|
-
onSuiteEnd(suite) {
|
|
96
|
-
// cleanup suites index to prevent resource leaks
|
|
97
|
-
if (suite.type === 'feature') {
|
|
98
|
-
this._startedFeatures = this._startedFeatures.filter((suite) => suite.uid !== suite.uid);
|
|
99
|
-
}
|
|
100
|
-
if (this._options.useCucumberStepReporter && suite.type === 'scenario') {
|
|
101
|
-
// passing hooks are missing the 'state' property
|
|
102
|
-
suite.hooks = suite.hooks.map((hook) => {
|
|
103
|
-
hook.state = hook.state ? hook.state : 'passed';
|
|
104
|
-
return hook;
|
|
105
|
-
});
|
|
106
|
-
const suiteChildren = [...suite.tests, ...suite.hooks];
|
|
107
|
-
const isPassed = !suiteChildren.some(item => item.state !== 'passed');
|
|
108
|
-
if (isPassed) {
|
|
109
|
-
return this._allure.endCase('passed');
|
|
110
|
-
}
|
|
111
|
-
// A scenario is it skipped if every steps are skipped and hooks are passed or skipped
|
|
112
|
-
const isSkipped = suite.tests.every(item => [SKIPPED].indexOf(item.state) >= 0) && suite.hooks.every(item => [PASSED, SKIPPED].indexOf(item.state) >= 0);
|
|
113
|
-
if (isSkipped) {
|
|
114
|
-
return this._allure.endCase(PENDING);
|
|
115
|
-
}
|
|
116
|
-
// A scenario is it passed if certain steps are passed and all other are skipped and every hooks are passed or skipped
|
|
117
|
-
const isPartiallySkipped = suiteChildren.every(item => [PASSED, SKIPPED].indexOf(item.state) >= 0);
|
|
118
|
-
if (isPartiallySkipped) {
|
|
119
|
-
return this._allure.endCase('passed');
|
|
120
|
-
}
|
|
121
|
-
// Only close passing and skipped tests because
|
|
122
|
-
// failing tests are closed in onTestFailed event
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
this._allure.endSuite();
|
|
126
|
-
}
|
|
127
|
-
onTestStart(test) {
|
|
128
|
-
this._consoleOutput = '';
|
|
129
|
-
const testTitle = test.currentTest ? test.currentTest : test.title;
|
|
130
|
-
if (this.isAnyTestRunning() && this._allure.getCurrentTest().name == testTitle) {
|
|
131
|
-
// Test already in progress, most likely started by a before each hook
|
|
132
|
-
this.setCaseParameters(test.cid, test.parent);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
if (this._options.useCucumberStepReporter) {
|
|
136
|
-
this._allure.startStep(testTitle);
|
|
137
|
-
const testObj = test;
|
|
138
|
-
const argument = testObj?.argument;
|
|
139
|
-
const dataTable = argument?.rows?.map((a) => a?.cells);
|
|
140
|
-
if (dataTable) {
|
|
141
|
-
this._allure.addAttachment('Data Table', stringify(dataTable), 'text/csv');
|
|
142
|
-
}
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
this._allure.startCase(testTitle);
|
|
146
|
-
this.setCaseParameters(test.cid, test.parent);
|
|
147
|
-
}
|
|
148
|
-
setCaseParameters(cid, parentUid) {
|
|
149
|
-
const parentSuite = this.getParentSuite(parentUid);
|
|
150
|
-
const currentTest = this._allure.getCurrentTest();
|
|
151
|
-
if (!this._isMultiremote) {
|
|
152
|
-
const caps = this._capabilities;
|
|
153
|
-
const { browserName, deviceName, desired, device } = caps;
|
|
154
|
-
let targetName = device || browserName || deviceName || cid;
|
|
155
|
-
// custom mobile grids can have device information in a `desired` cap
|
|
156
|
-
if (desired && desired.deviceName && desired.platformVersion) {
|
|
157
|
-
targetName = `${device || desired.deviceName} ${desired.platformVersion}`;
|
|
158
|
-
}
|
|
159
|
-
const browserstackVersion = caps.os_version || caps.osVersion;
|
|
160
|
-
const version = browserstackVersion || caps.browserVersion || caps.version || caps.platformVersion || '';
|
|
161
|
-
const paramName = (deviceName || device) ? 'device' : 'browser';
|
|
162
|
-
const paramValue = version ? `${targetName}-${version}` : targetName;
|
|
163
|
-
currentTest.addParameter('argument', paramName, paramValue);
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
currentTest.addParameter('argument', 'isMultiremote', 'true');
|
|
167
|
-
}
|
|
168
|
-
// Allure analytics labels. See https://github.com/allure-framework/allure2/blob/master/Analytics.md
|
|
169
|
-
currentTest.addLabel('language', 'javascript');
|
|
170
|
-
currentTest.addLabel('framework', 'wdio');
|
|
171
|
-
currentTest.addLabel('thread', cid);
|
|
172
|
-
if (parentSuite?.title) {
|
|
173
|
-
currentTest.addLabel('feature', parentSuite?.title);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
getParentSuite(uid) {
|
|
177
|
-
if (!uid) {
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
|
-
return this._startedFeatures.find((suite) => suite.uid === uid);
|
|
181
|
-
}
|
|
182
|
-
getLabels({ tags }) {
|
|
183
|
-
const labels = [];
|
|
184
|
-
if (tags) {
|
|
185
|
-
tags.forEach((tag) => {
|
|
186
|
-
const label = tag.name.replace(/[@]/, '').split('=');
|
|
187
|
-
if (label.length === 2) {
|
|
188
|
-
labels.push({ name: label[0], value: label[1] });
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
return labels;
|
|
193
|
-
}
|
|
194
|
-
onTestPass() {
|
|
195
|
-
attachConsoleLogs(this._consoleOutput, this._allure);
|
|
196
|
-
if (this._options.useCucumberStepReporter) {
|
|
197
|
-
const suite = this._allure.getCurrentSuite();
|
|
198
|
-
if (suite && suite.currentStep instanceof Step) {
|
|
199
|
-
return this._allure.endStep('passed');
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
this._allure.endCase(PASSED);
|
|
203
|
-
}
|
|
204
|
-
onTestFail(test) {
|
|
205
|
-
if (this._options.useCucumberStepReporter) {
|
|
206
|
-
attachConsoleLogs(this._consoleOutput, this._allure);
|
|
207
|
-
const testStatus = getTestStatus(test, this._config);
|
|
208
|
-
const stepStatus = Object.values(stepStatuses).indexOf(testStatus) >= 0 ?
|
|
209
|
-
testStatus : 'failed';
|
|
210
|
-
const suite = this._allure.getCurrentSuite();
|
|
211
|
-
if (suite && suite.currentStep instanceof Step) {
|
|
212
|
-
this._allure.endStep(stepStatus);
|
|
213
|
-
}
|
|
214
|
-
this._allure.endCase(testStatus, getErrorFromFailedTest(test));
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
if (!this.isAnyTestRunning()) { // is any CASE running
|
|
218
|
-
this.onTestStart(test);
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
this._allure.getCurrentTest().name = test.title;
|
|
222
|
-
}
|
|
223
|
-
attachConsoleLogs(this._consoleOutput, this._allure);
|
|
224
|
-
const status = getTestStatus(test, this._config);
|
|
225
|
-
while (this._allure.getCurrentSuite().currentStep instanceof Step) {
|
|
226
|
-
this._allure.endStep(status);
|
|
227
|
-
}
|
|
228
|
-
this._allure.endCase(status, getErrorFromFailedTest(test));
|
|
229
|
-
}
|
|
230
|
-
onTestSkip(test) {
|
|
231
|
-
attachConsoleLogs(this._consoleOutput, this._allure);
|
|
232
|
-
if (this._options.useCucumberStepReporter) {
|
|
233
|
-
const suite = this._allure.getCurrentSuite();
|
|
234
|
-
if (suite && suite.currentStep instanceof Step) {
|
|
235
|
-
this._allure.endStep('canceled');
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
else if (!this._allure.getCurrentTest() || this._allure.getCurrentTest().name !== test.title) {
|
|
239
|
-
this._allure.pendingCase(test.title);
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
this._allure.endCase('pending');
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
onBeforeCommand(command) {
|
|
246
|
-
if (!this.isAnyTestRunning()) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
const { disableWebdriverStepsReporting } = this._options;
|
|
250
|
-
if (disableWebdriverStepsReporting || this._isMultiremote) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
this._allure.startStep(command.method
|
|
254
|
-
? `${command.method} ${command.endpoint}`
|
|
255
|
-
: command.command);
|
|
256
|
-
const payload = command.body || command.params;
|
|
257
|
-
if (!isEmpty(payload)) {
|
|
258
|
-
this.dumpJSON('Request', payload);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
onAfterCommand(command) {
|
|
262
|
-
const { disableWebdriverStepsReporting, disableWebdriverScreenshotsReporting } = this._options;
|
|
263
|
-
if (this.isScreenshotCommand(command) && command.result.value) {
|
|
264
|
-
if (!disableWebdriverScreenshotsReporting) {
|
|
265
|
-
this._lastScreenshot = command.result.value;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
if (!this.isAnyTestRunning()) {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
this.attachScreenshot();
|
|
272
|
-
if (this._isMultiremote) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
if (!disableWebdriverStepsReporting) {
|
|
276
|
-
if (command.result && command.result.value && !this.isScreenshotCommand(command)) {
|
|
277
|
-
this.dumpJSON('Response', command.result.value);
|
|
278
|
-
}
|
|
279
|
-
const suite = this._allure.getCurrentSuite();
|
|
280
|
-
if (!suite || !(suite.currentStep instanceof Step)) {
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
this._allure.endStep('passed');
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
onHookStart(hook) {
|
|
287
|
-
// ignore global hooks
|
|
288
|
-
if (!hook.parent || !this._allure.getCurrentSuite()) {
|
|
289
|
-
return false;
|
|
290
|
-
}
|
|
291
|
-
// add beforeEach / afterEach hook as step to test
|
|
292
|
-
if (this._options.disableMochaHooks && isMochaEachHooks(hook.title)) {
|
|
293
|
-
if (this._allure.getCurrentTest()) {
|
|
294
|
-
this._allure.startStep(hook.title);
|
|
295
|
-
}
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
// don't add hook as test to suite for mocha All hooks
|
|
299
|
-
if (this._options.disableMochaHooks && isMochaAllHooks(hook.title)) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
// add hook as test to suite
|
|
303
|
-
this.onTestStart(hook);
|
|
304
|
-
}
|
|
305
|
-
onHookEnd(hook) {
|
|
306
|
-
// ignore global hooks
|
|
307
|
-
if (!hook.parent || !this._allure.getCurrentSuite() || (this._options.disableMochaHooks && !isMochaAllHooks(hook.title) && !this._allure.getCurrentTest())) {
|
|
308
|
-
return false;
|
|
309
|
-
}
|
|
310
|
-
// set beforeEach / afterEach hook (step) status
|
|
311
|
-
if (this._options.disableMochaHooks && isMochaEachHooks(hook.title)) {
|
|
312
|
-
if (hook.error) {
|
|
313
|
-
this._allure.endStep('failed');
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
this._allure.endStep('passed');
|
|
317
|
-
}
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
// set hook (test) status
|
|
321
|
-
if (hook.error) {
|
|
322
|
-
if (this._options.disableMochaHooks && isMochaAllHooks(hook.title)) {
|
|
323
|
-
this.onTestStart(hook);
|
|
324
|
-
this.attachScreenshot();
|
|
325
|
-
}
|
|
326
|
-
this.onTestFail(hook);
|
|
327
|
-
}
|
|
328
|
-
else if (this._options.disableMochaHooks || this._options.useCucumberStepReporter) {
|
|
329
|
-
if (!isMochaAllHooks(hook.title)) {
|
|
330
|
-
this.onTestPass();
|
|
331
|
-
// remove hook from suite if it has no steps
|
|
332
|
-
if (this._allure.getCurrentTest().steps.length === 0 && !this._options.useCucumberStepReporter) {
|
|
333
|
-
this._allure.getCurrentSuite().testcases.pop();
|
|
334
|
-
}
|
|
335
|
-
else if (this._options.useCucumberStepReporter) {
|
|
336
|
-
// remove hook when it's registered as a step and if it's passed
|
|
337
|
-
const step = this._allure.getCurrentTest().steps.pop();
|
|
338
|
-
// if it had any attachments, reattach them to current test
|
|
339
|
-
if (step && step.attachments.length >= 1) {
|
|
340
|
-
step.attachments.forEach((attachment) => {
|
|
341
|
-
this._allure.getCurrentTest().addAttachment(attachment);
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
else if (!this._options.disableMochaHooks)
|
|
348
|
-
this.onTestPass();
|
|
349
|
-
}
|
|
350
|
-
addLabel({ name, value }) {
|
|
351
|
-
if (!this.isAnyTestRunning()) {
|
|
352
|
-
return false;
|
|
353
|
-
}
|
|
354
|
-
const test = this._allure.getCurrentTest();
|
|
355
|
-
test.addLabel(name, value);
|
|
356
|
-
}
|
|
357
|
-
addStory({ storyName }) {
|
|
358
|
-
if (!this.isAnyTestRunning()) {
|
|
359
|
-
return false;
|
|
360
|
-
}
|
|
361
|
-
const test = this._allure.getCurrentTest();
|
|
362
|
-
test.addLabel('story', storyName);
|
|
363
|
-
}
|
|
364
|
-
addFeature({ featureName }) {
|
|
365
|
-
if (!this.isAnyTestRunning()) {
|
|
366
|
-
return false;
|
|
367
|
-
}
|
|
368
|
-
const test = this._allure.getCurrentTest();
|
|
369
|
-
test.addLabel('feature', featureName);
|
|
370
|
-
}
|
|
371
|
-
addSeverity({ severity }) {
|
|
372
|
-
if (!this.isAnyTestRunning()) {
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
const test = this._allure.getCurrentTest();
|
|
376
|
-
test.addLabel('severity', severity);
|
|
377
|
-
}
|
|
378
|
-
addIssue({ issue }) {
|
|
379
|
-
if (!this.isAnyTestRunning()) {
|
|
380
|
-
return false;
|
|
381
|
-
}
|
|
382
|
-
const test = this._allure.getCurrentTest();
|
|
383
|
-
const issueLink = getLinkByTemplate(this._options.issueLinkTemplate, issue);
|
|
384
|
-
test.addLabel('issue', issueLink);
|
|
385
|
-
}
|
|
386
|
-
addTestId({ testId }) {
|
|
387
|
-
if (!this.isAnyTestRunning()) {
|
|
388
|
-
return false;
|
|
389
|
-
}
|
|
390
|
-
const test = this._allure.getCurrentTest();
|
|
391
|
-
const tmsLink = getLinkByTemplate(this._options.tmsLinkTemplate, testId);
|
|
392
|
-
test.addLabel('testId', tmsLink);
|
|
393
|
-
}
|
|
394
|
-
addEnvironment({ name, value }) {
|
|
395
|
-
if (!this.isAnyTestRunning()) {
|
|
396
|
-
return false;
|
|
397
|
-
}
|
|
398
|
-
const test = this._allure.getCurrentTest();
|
|
399
|
-
test.addParameter('environment-variable', name, value);
|
|
400
|
-
}
|
|
401
|
-
addDescription({ description, descriptionType }) {
|
|
402
|
-
if (!this.isAnyTestRunning()) {
|
|
403
|
-
return false;
|
|
404
|
-
}
|
|
405
|
-
const test = this._allure.getCurrentTest();
|
|
406
|
-
test.setDescription(description, descriptionType);
|
|
407
|
-
}
|
|
408
|
-
addAttachment({ name, content, type = 'text/plain' }) {
|
|
409
|
-
if (!this.isAnyTestRunning()) {
|
|
410
|
-
return false;
|
|
411
|
-
}
|
|
412
|
-
if (type === 'application/json') {
|
|
413
|
-
this.dumpJSON(name, content);
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
this._allure.addAttachment(name, Buffer.from(content), type);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
startStep(title) {
|
|
420
|
-
if (!this.isAnyTestRunning()) {
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
423
|
-
this._allure.startStep(title);
|
|
424
|
-
}
|
|
425
|
-
endStep(status) {
|
|
426
|
-
if (!this.isAnyTestRunning()) {
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
this._allure.endStep(status);
|
|
430
|
-
}
|
|
431
|
-
addStep({ step }) {
|
|
432
|
-
if (!this.isAnyTestRunning()) {
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
this.startStep(step.title);
|
|
436
|
-
if (step.attachment) {
|
|
437
|
-
this.addAttachment(step.attachment);
|
|
438
|
-
}
|
|
439
|
-
this.endStep(step.status);
|
|
440
|
-
}
|
|
441
|
-
addArgument({ name, value }) {
|
|
442
|
-
if (!this.isAnyTestRunning()) {
|
|
443
|
-
return false;
|
|
444
|
-
}
|
|
445
|
-
const test = this._allure.getCurrentTest();
|
|
446
|
-
test.addParameter('argument', name, value);
|
|
447
|
-
}
|
|
448
|
-
isAnyTestRunning() {
|
|
449
|
-
return this._allure.getCurrentSuite() && this._allure.getCurrentTest();
|
|
450
|
-
}
|
|
451
|
-
isScreenshotCommand(command) {
|
|
452
|
-
const isScrenshotEndpoint = /\/session\/[^/]*(\/element\/[^/]*)?\/screenshot/;
|
|
453
|
-
return (
|
|
454
|
-
// WebDriver protocol
|
|
455
|
-
(command.endpoint && isScrenshotEndpoint.test(command.endpoint)) ||
|
|
456
|
-
// DevTools protocol
|
|
457
|
-
command.command === 'takeScreenshot');
|
|
458
|
-
}
|
|
459
|
-
dumpJSON(name, json) {
|
|
460
|
-
const content = JSON.stringify(json, null, 2);
|
|
461
|
-
const isStr = typeof content === 'string';
|
|
462
|
-
this._allure.addAttachment(name, isStr ? content : `${content}`, isStr ? 'application/json' : 'text/plain');
|
|
463
|
-
}
|
|
464
|
-
attachScreenshot() {
|
|
465
|
-
if (this._lastScreenshot && !this._options.disableWebdriverScreenshotsReporting) {
|
|
466
|
-
this._allure.addAttachment('Screenshot', Buffer.from(this._lastScreenshot, 'base64'));
|
|
467
|
-
this._lastScreenshot = undefined;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Assign feature to test
|
|
472
|
-
* @name addFeature
|
|
473
|
-
* @param {(string)} featureName - feature name or an array of names
|
|
474
|
-
*/
|
|
475
|
-
static addFeature = (featureName) => {
|
|
476
|
-
tellReporter(events.addFeature, { featureName });
|
|
477
|
-
};
|
|
478
|
-
/**
|
|
479
|
-
* Assign label to test
|
|
480
|
-
* @name addLabel
|
|
481
|
-
* @param {string} name - label name
|
|
482
|
-
* @param {string} value - label value
|
|
483
|
-
*/
|
|
484
|
-
static addLabel = (name, value) => {
|
|
485
|
-
tellReporter(events.addLabel, { name, value });
|
|
486
|
-
};
|
|
487
|
-
/**
|
|
488
|
-
* Assign severity to test
|
|
489
|
-
* @name addSeverity
|
|
490
|
-
* @param {string} severity - severity value
|
|
491
|
-
*/
|
|
492
|
-
static addSeverity = (severity) => {
|
|
493
|
-
tellReporter(events.addSeverity, { severity });
|
|
494
|
-
};
|
|
495
|
-
/**
|
|
496
|
-
* Assign issue id to test
|
|
497
|
-
* @name addIssue
|
|
498
|
-
* @param {string} issue - issue id value
|
|
499
|
-
*/
|
|
500
|
-
static addIssue = (issue) => {
|
|
501
|
-
tellReporter(events.addIssue, { issue });
|
|
502
|
-
};
|
|
503
|
-
/**
|
|
504
|
-
* Assign TMS test id to test
|
|
505
|
-
* @name addTestId
|
|
506
|
-
* @param {string} testId - test id value
|
|
507
|
-
*/
|
|
508
|
-
static addTestId = (testId) => {
|
|
509
|
-
tellReporter(events.addTestId, { testId });
|
|
510
|
-
};
|
|
511
|
-
/**
|
|
512
|
-
* Assign story to test
|
|
513
|
-
* @name addStory
|
|
514
|
-
* @param {string} storyName - story name for test
|
|
515
|
-
*/
|
|
516
|
-
static addStory = (storyName) => {
|
|
517
|
-
tellReporter(events.addStory, { storyName });
|
|
518
|
-
};
|
|
519
|
-
/**
|
|
520
|
-
* Add environment value
|
|
521
|
-
* @name addEnvironment
|
|
522
|
-
* @param {string} name - environment name
|
|
523
|
-
* @param {string} value - environment value
|
|
524
|
-
*/
|
|
525
|
-
static addEnvironment = (name, value) => {
|
|
526
|
-
tellReporter(events.addEnvironment, { name, value });
|
|
527
|
-
};
|
|
528
|
-
/**
|
|
529
|
-
* Assign test description to test
|
|
530
|
-
* @name addDescription
|
|
531
|
-
* @param {string} description - description for test
|
|
532
|
-
* @param {string} descriptionType - description type 'text'\'html'\'markdown'
|
|
533
|
-
*/
|
|
534
|
-
static addDescription = (description, descriptionType) => {
|
|
535
|
-
tellReporter(events.addDescription, { description, descriptionType });
|
|
536
|
-
};
|
|
537
|
-
/**
|
|
538
|
-
* Add attachment
|
|
539
|
-
* @name addAttachment
|
|
540
|
-
* @param {string} name - attachment file name
|
|
541
|
-
* @param {*} content - attachment content
|
|
542
|
-
* @param {string=} mimeType - attachment mime type
|
|
543
|
-
*/
|
|
544
|
-
static addAttachment = (name, content, type) => {
|
|
545
|
-
if (!type) {
|
|
546
|
-
type = content instanceof Buffer ? 'image/png' : typeof content === 'string' ? 'text/plain' : 'application/json';
|
|
547
|
-
}
|
|
548
|
-
tellReporter(events.addAttachment, { name, content, type });
|
|
549
|
-
};
|
|
550
|
-
/**
|
|
551
|
-
* Start allure step
|
|
552
|
-
* @name startStep
|
|
553
|
-
* @param {string} title - step name in report
|
|
554
|
-
*/
|
|
555
|
-
static startStep = (title) => {
|
|
556
|
-
tellReporter(events.startStep, title);
|
|
557
|
-
};
|
|
558
|
-
/**
|
|
559
|
-
* End current allure step
|
|
560
|
-
* @name endStep
|
|
561
|
-
* @param {StepStatus} [status='passed'] - step status
|
|
562
|
-
*/
|
|
563
|
-
static endStep = (status = 'passed') => {
|
|
564
|
-
if (!Object.values(stepStatuses).includes(status)) {
|
|
565
|
-
throw new Error(`Step status must be ${Object.values(stepStatuses).join(' or ')}. You tried to set "${status}"`);
|
|
566
|
-
}
|
|
567
|
-
tellReporter(events.endStep, status);
|
|
568
|
-
};
|
|
569
|
-
/**
|
|
570
|
-
* Create allure step
|
|
571
|
-
* @name addStep
|
|
572
|
-
* @param {string} title - step name in report
|
|
573
|
-
* @param {Object} [attachmentObject={}] - attachment for step
|
|
574
|
-
* @param {string} attachmentObject.content - attachment content
|
|
575
|
-
* @param {string} [attachmentObject.name='attachment'] - attachment name
|
|
576
|
-
* @param {string} [attachmentObject.type='text/plain'] - attachment type
|
|
577
|
-
* @param {string} [status='passed'] - step status
|
|
578
|
-
*/
|
|
579
|
-
static addStep = (title, { content, name = 'attachment', type = 'text/plain' } = {}, status = 'passed') => {
|
|
580
|
-
if (!Object.values(stepStatuses).includes(status)) {
|
|
581
|
-
throw new Error(`Step status must be ${Object.values(stepStatuses).join(' or ')}. You tried to set "${status}"`);
|
|
582
|
-
}
|
|
583
|
-
const step = content ? { title, attachment: { content, name, type }, status } : { title, status };
|
|
584
|
-
tellReporter(events.addStep, { step });
|
|
585
|
-
};
|
|
586
|
-
/**
|
|
587
|
-
* Add additional argument to test
|
|
588
|
-
* @name addArgument
|
|
589
|
-
* @param {string} name - argument name
|
|
590
|
-
* @param {string} value - argument value
|
|
591
|
-
*/
|
|
592
|
-
static addArgument = (name, value) => {
|
|
593
|
-
tellReporter(events.addArgument, { name, value });
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
export default AllureReporter;
|
|
1
|
+
import AllureReporter from './reporter.js';
|
|
597
2
|
export * from './types.js';
|
|
3
|
+
export * from './common/api.js';
|
|
4
|
+
export default AllureReporter;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { SuiteStats, HookStats, RunnerStats, TestStats, BeforeCommandArgs, AfterCommandArgs, CommandArgs } from '@wdio/reporter';
|
|
2
|
+
import WDIOReporter from '@wdio/reporter';
|
|
3
|
+
import { addFeature, addLabel, addSeverity, addIssue, addTestId, addStory, addEnvironment, addDescription, addAttachment, startStep, endStep, addStep, addArgument } from './common/api.js';
|
|
4
|
+
import type { AddAttachmentEventArgs, AddDescriptionEventArgs, AddEnvironmentEventArgs, AddFeatureEventArgs, AddIssueEventArgs, AddLabelEventArgs, AddSeverityEventArgs, AddStoryEventArgs, AddTestIdEventArgs, Status, AllureReporterOptions } from './types.js';
|
|
5
|
+
export default class AllureReporter extends WDIOReporter {
|
|
6
|
+
private _allure;
|
|
7
|
+
private _capabilities;
|
|
8
|
+
private _isMultiremote?;
|
|
9
|
+
private _config?;
|
|
10
|
+
private _lastScreenshot?;
|
|
11
|
+
private _options;
|
|
12
|
+
private _consoleOutput;
|
|
13
|
+
private _originalStdoutWrite;
|
|
14
|
+
private _addConsoleLogs;
|
|
15
|
+
private _startedFeatures;
|
|
16
|
+
constructor(options?: AllureReporterOptions);
|
|
17
|
+
registerListeners(): void;
|
|
18
|
+
onRunnerStart(runner: RunnerStats): void;
|
|
19
|
+
onSuiteStart(suite: SuiteStats): void;
|
|
20
|
+
onSuiteEnd(suite: SuiteStats): any;
|
|
21
|
+
onTestStart(test: TestStats | HookStats): void;
|
|
22
|
+
setCaseParameters(cid: string | undefined, parentUid: string | undefined): void;
|
|
23
|
+
getParentSuite(uid?: string): SuiteStats | undefined;
|
|
24
|
+
getLabels({ tags }: SuiteStats): {
|
|
25
|
+
name: string;
|
|
26
|
+
value: string;
|
|
27
|
+
}[];
|
|
28
|
+
onTestPass(): any;
|
|
29
|
+
onTestFail(test: TestStats | HookStats): void;
|
|
30
|
+
onTestSkip(test: TestStats): void;
|
|
31
|
+
onBeforeCommand(command: BeforeCommandArgs): void;
|
|
32
|
+
onAfterCommand(command: AfterCommandArgs): void;
|
|
33
|
+
onHookStart(hook: HookStats): false | undefined;
|
|
34
|
+
onHookEnd(hook: HookStats): false | undefined;
|
|
35
|
+
addLabel({ name, value }: AddLabelEventArgs): false | undefined;
|
|
36
|
+
addStory({ storyName }: AddStoryEventArgs): false | undefined;
|
|
37
|
+
addFeature({ featureName }: AddFeatureEventArgs): false | undefined;
|
|
38
|
+
addSeverity({ severity }: AddSeverityEventArgs): false | undefined;
|
|
39
|
+
addIssue({ issue }: AddIssueEventArgs): false | undefined;
|
|
40
|
+
addTestId({ testId }: AddTestIdEventArgs): false | undefined;
|
|
41
|
+
addEnvironment({ name, value }: AddEnvironmentEventArgs): false | undefined;
|
|
42
|
+
addDescription({ description, descriptionType }: AddDescriptionEventArgs): false | undefined;
|
|
43
|
+
addAttachment({ name, content, type }: AddAttachmentEventArgs): false | undefined;
|
|
44
|
+
startStep(title: string): false | undefined;
|
|
45
|
+
endStep(status: Status): false | undefined;
|
|
46
|
+
addStep({ step }: any): false | undefined;
|
|
47
|
+
addArgument({ name, value }: any): false | undefined;
|
|
48
|
+
isAnyTestRunning(): any;
|
|
49
|
+
isScreenshotCommand(command: CommandArgs): boolean;
|
|
50
|
+
dumpJSON(name: string, json: object): void;
|
|
51
|
+
attachScreenshot(): void;
|
|
52
|
+
/**
|
|
53
|
+
* public API attached to the reporter
|
|
54
|
+
* deprecated approach and only here for backwards compatibility
|
|
55
|
+
*/
|
|
56
|
+
static addFeature: typeof addFeature;
|
|
57
|
+
static addLabel: typeof addLabel;
|
|
58
|
+
static addSeverity: typeof addSeverity;
|
|
59
|
+
static addIssue: typeof addIssue;
|
|
60
|
+
static addTestId: typeof addTestId;
|
|
61
|
+
static addStory: typeof addStory;
|
|
62
|
+
static addEnvironment: typeof addEnvironment;
|
|
63
|
+
static addDescription: typeof addDescription;
|
|
64
|
+
static addAttachment: typeof addAttachment;
|
|
65
|
+
static startStep: typeof startStep;
|
|
66
|
+
static endStep: typeof endStep;
|
|
67
|
+
static addStep: typeof addStep;
|
|
68
|
+
static addArgument: typeof addArgument;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|