1 | import events from 'events'
|
2 | import Allure from 'allure-js-commons-workflo'
|
3 | import Step from 'allure-js-commons-workflo/beans/step'
|
4 | import * as fs from 'fs'
|
5 | import * as path from 'path'
|
6 |
|
7 | function isEmpty (object) {
|
8 | return !object || Object.keys(object).length === 0
|
9 | }
|
10 |
|
11 | const LOGGING_HOOKS = ['"before all" hook', '"after all" hook']
|
12 |
|
13 | let debug = false
|
14 | let debugSeleniumCommand = false
|
15 |
|
16 | function logger () {
|
17 | if (debug) {
|
18 | console.log(arguments)
|
19 | }
|
20 | }
|
21 | function error () {
|
22 | console.error(arguments)
|
23 | }
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | class AllureReporter extends events.EventEmitter {
|
32 | constructor (baseReporter, config, options = {}) {
|
33 | super()
|
34 |
|
35 | this.baseReporter = baseReporter
|
36 | this.config = config
|
37 | this.options = options
|
38 | if (options) {
|
39 | debug = options.debug
|
40 | debugSeleniumCommand = options.debugSeleniumCommand
|
41 | }
|
42 | this.allures = {}
|
43 | this.currentTestId = ''
|
44 | this.startedSpecs = false
|
45 | this.testIds = {}
|
46 | this.errorCtr = 0
|
47 |
|
48 |
|
49 |
|
50 | this.on('end', () => {
|
51 |
|
52 | if (this.startedSpecs) {
|
53 | this.addResults()
|
54 | }
|
55 | })
|
56 |
|
57 | this.on('startSpecs', (runner) => {
|
58 | if (!this.startedSpecs) {
|
59 | this.startedSpecs = true
|
60 | }
|
61 | })
|
62 |
|
63 | this.on('suite:start', (suite) => {
|
64 | const allure = this.getAllure(suite.cid)
|
65 | const currentSuite = allure.getCurrentSuite()
|
66 | const prefix = currentSuite ? currentSuite.name + ' ' : ''
|
67 |
|
68 | process.workflo.currentCid = suite.cid
|
69 |
|
70 | allure.startSuite(prefix + suite.title)
|
71 | })
|
72 |
|
73 | this.on('suite:end', (suite) => {
|
74 | this.getAllure(suite.cid).endSuite()
|
75 | })
|
76 |
|
77 | this.on('test:setCurrentId', (test) => {
|
78 | const allure = this.getAllure(test.cid)
|
79 | this.currentTestId = test.id
|
80 |
|
81 | const currentTest = allure.getCurrentTest()
|
82 |
|
83 | if (this.currentTestId) {
|
84 | if (test.testcase) {
|
85 | const traceInfo = this.config.traceInfo.testcases[this.currentTestId]
|
86 |
|
87 | currentTest.addParameter('argument', 'Testcase File', traceInfo.testcaseFile)
|
88 | currentTest.addParameter('argument', 'Verifies Specs', traceInfo.specs.join(', '))
|
89 | } else if (test.spec) {
|
90 | const parts = this.currentTestId.split('|')
|
91 | const spec = parts[0]
|
92 | const criteria = parts[1]
|
93 |
|
94 | const traceInfo = this.config.traceInfo.specs[spec]
|
95 |
|
96 | currentTest.addParameter('argument', 'Spec File', traceInfo.specFile)
|
97 |
|
98 | const manualFile = traceInfo.criteriaVerificationFiles[criteria].manualFile
|
99 | const testcases = traceInfo.criteriaVerificationFiles[criteria].testcases
|
100 |
|
101 | if (manualFile) {
|
102 | currentTest.addParameter('argument', 'Verified by Manual Results', manualFile)
|
103 | } else if (testcases.length > 0) {
|
104 | currentTest.addParameter('argument', 'Verified in Testcases', testcases.join(', '))
|
105 | }
|
106 | }
|
107 | }
|
108 | })
|
109 |
|
110 | this.on('test:start', (test) => {
|
111 | const allure = this.getAllure(test.cid)
|
112 | allure.startCase(test.title)
|
113 |
|
114 | this.lastCid = test.cid
|
115 |
|
116 | const currentTest = allure.getCurrentTest()
|
117 |
|
118 | if (test.metadata) {
|
119 | for (const key in test.metadata) {
|
120 | const meta = {
|
121 | event: 'test:meta',
|
122 | cid: test.cid
|
123 | }
|
124 | meta[key] = test.metadata[key]
|
125 |
|
126 | this.handleMetadata(meta)
|
127 | }
|
128 | }
|
129 |
|
130 |
|
131 | let printObject = this.config.printObject
|
132 |
|
133 | const filterFilesStr = `${printObject['Spec Files']} specFiles, ${printObject['Testcase Files']} testcaseFiles, ${printObject['Manual Result Files']} manualResultFiles`
|
134 | const filtersStr = `${printObject['Features']} features, ${printObject['Specs']} specs, ${printObject['Suites']} suites, ${printObject['Testcases']} testcases`
|
135 | const coverageStr = `${printObject['Automated Criteria'].count} automated ${printObject['Automated Criteria'].percentage}, ${printObject['Manual Criteria'].count} manual ${printObject['Manual Criteria'].percentage}, ${printObject['Uncovered Criteria'].count} uncovered ${printObject['Uncovered Criteria'].percentage}`
|
136 | let uncoveredCriteriaStr = ''
|
137 |
|
138 | for (const spec in printObject['Uncovered Criteria Object']) {
|
139 | uncoveredCriteriaStr += `${spec}: [${printObject['Uncovered Criteria Object'][spec].join(', ')}], `
|
140 | }
|
141 |
|
142 | uncoveredCriteriaStr = uncoveredCriteriaStr.substring(0, uncoveredCriteriaStr.length - 2)
|
143 |
|
144 |
|
145 | currentTest.addParameter('environment-variable', 'BROWSER', test.runner[test.cid].browserName)
|
146 | currentTest.addParameter('environment-variable', 'BASE URL', this.config.baseUrl)
|
147 |
|
148 | if (this.config.manualOnly) {
|
149 | currentTest.addParameter('environment-variable', 'EXECUTION MODE: ', 'Manual Only')
|
150 | } else if (this.config.automaticOnly) {
|
151 | currentTest.addParameter('environment-variable', 'EXECUTION MODE: ', 'Automatic Only')
|
152 | } else {
|
153 | currentTest.addParameter('environment-variable', 'EXECUTION MODE: ', 'Automatic and Manual')
|
154 | }
|
155 |
|
156 |
|
157 |
|
158 |
|
159 | currentTest.addParameter('environment-variable', 'CRITERIA COVERAGE: ', coverageStr)
|
160 | currentTest.addParameter('environment-variable', 'FILTER FILES: ', filterFilesStr)
|
161 | currentTest.addParameter('environment-variable', 'FILTERS: ', filtersStr)
|
162 |
|
163 | if (uncoveredCriteriaStr) {
|
164 | currentTest.addParameter('environment-variable', 'UNCOVERED CRITERIA: ', uncoveredCriteriaStr)
|
165 | }
|
166 | })
|
167 |
|
168 | this.on('test:pass', (test) => {
|
169 | const allure = this.getAllure(test.cid)
|
170 |
|
171 | this.addArguments(test)
|
172 | this.addResultsDummy(test)
|
173 | allure.endCase('passed')
|
174 | })
|
175 |
|
176 | this.on('test:fail', (test) => {
|
177 | const allure = this.getAllure(test.cid)
|
178 |
|
179 | if (!allure.getCurrentTest()) {
|
180 | allure.startCase(test.title)
|
181 | } else {
|
182 | allure.getCurrentTest().name = test.title
|
183 | }
|
184 |
|
185 | while (allure.getCurrentSuite().currentStep instanceof Step) {
|
186 | allure.endStep('failed')
|
187 | }
|
188 |
|
189 | this.addArguments(test)
|
190 | this.addResultsDummy(test)
|
191 | allure.endCase('failed', {
|
192 | message: '\n' + test.err.message,
|
193 | stack: '\n' + test.err.stack
|
194 | })
|
195 | })
|
196 |
|
197 | this.on('test:broken', (test) => {
|
198 | const allure = this.getAllure(test.cid)
|
199 |
|
200 | if (!allure.getCurrentTest()) {
|
201 | allure.startCase(test.title)
|
202 | } else {
|
203 | allure.getCurrentTest().name = test.title
|
204 | }
|
205 |
|
206 | while (allure.getCurrentSuite().currentStep instanceof Step) {
|
207 | allure.endStep('broken')
|
208 | }
|
209 |
|
210 | this.addArguments(test)
|
211 | this.addResultsDummy(test)
|
212 |
|
213 | allure.endCase('broken', {
|
214 | message: '\n' + test.err.message,
|
215 | stack: '\n' + test.err.stack
|
216 | })
|
217 | })
|
218 |
|
219 | this.on('test:pending', (test) => {
|
220 | const allure = this.getAllure(test.cid)
|
221 |
|
222 | this.addArguments(test)
|
223 | this.addResultsDummy(test)
|
224 | allure.endCase('pending', {message: 'Test ignored', stack: ''})
|
225 | })
|
226 |
|
227 | this.on('test:unverified', (test) => {
|
228 | const allure = this.getAllure(test.cid)
|
229 |
|
230 | if (!allure.getCurrentTest()) {
|
231 | allure.startCase(test.title)
|
232 | } else {
|
233 | allure.getCurrentTest().name = test.title
|
234 | }
|
235 |
|
236 | this.addArguments(test)
|
237 | this.addResultsDummy(test)
|
238 | allure.endCase('unknown', {
|
239 | message: '\n' + test.err.message
|
240 | })
|
241 | })
|
242 |
|
243 | this.on('runner:command', (command) => {
|
244 | const allure = this.getAllure(command.cid)
|
245 |
|
246 | if (!this.isAnyTestRunning(allure)) {
|
247 | return
|
248 | }
|
249 |
|
250 | if (debugSeleniumCommand) {
|
251 | allure.startStep(`${command.method} ${command.uri.path}`)
|
252 |
|
253 | if (!isEmpty(command.data)) {
|
254 | this.dumpJSON(allure, 'Request', command.data)
|
255 | }
|
256 | }
|
257 | })
|
258 |
|
259 | this.on('runner:result', (command) => {
|
260 | const allure = this.getAllure(command.cid)
|
261 | let status = 'passed'
|
262 |
|
263 | if (!this.isAnyTestRunning(allure)) {
|
264 | return
|
265 | }
|
266 |
|
267 | if (debugSeleniumCommand) {
|
268 | if (command.body.screenshot) {
|
269 | allure.addAttachment('Screenshot', new Buffer(command.body.screenshot, 'base64'))
|
270 | delete command.body.screenshot
|
271 | }
|
272 | if (command.body.type && command.body.type === 'RuntimeError') {
|
273 | status = 'broken'
|
274 | }
|
275 |
|
276 | this.dumpJSON(allure, 'Response', command.body)
|
277 |
|
278 | allure.endStep(status)
|
279 | }
|
280 | })
|
281 |
|
282 | |
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 | this.on('test:meta', function (meta) {
|
296 | this.handleMetadata(meta)
|
297 | })
|
298 |
|
299 | this.on('step:start', function (step) {
|
300 | const allure = this.getAllure(step.cid)
|
301 | logger('step:start', step)
|
302 |
|
303 | if (!this.isAnyTestRunning(allure)) {
|
304 | error('ERROR', 'cannot start step because no test is running', step)
|
305 | return
|
306 | }
|
307 | allure.startStep(step.title != null ? step.title : 'No name defined')
|
308 |
|
309 | if (step.arg) {
|
310 | this.dumpJSON(allure, 'Step Arg', step.arg)
|
311 | }
|
312 | })
|
313 |
|
314 | this.on('step:end', function (step) {
|
315 | const allure = this.getAllure(step.cid)
|
316 | logger('step:end', step)
|
317 |
|
318 | if (!this.isAnyTestRunning(allure)) {
|
319 | error('ERROR', 'cannot end step because no test is running', step)
|
320 | return
|
321 | }
|
322 |
|
323 | if (step.arg) {
|
324 | this.dumpJSON(allure, 'Step Result', step.arg)
|
325 | }
|
326 |
|
327 | if (step.assertionFailures) {
|
328 | this.dumpJSON(allure, 'Verification Failures', step.assertionFailures)
|
329 | }
|
330 |
|
331 | if (step.screenshots) {
|
332 | for (const screenshotMessage in step.screenshots) {
|
333 | for (let i = 0; i < step.screenshots[screenshotMessage].length; ++i) {
|
334 | allure.addAttachment(`${screenshotMessage} (${(i + 1)})`, new Buffer(fs.readFileSync(step.screenshots[screenshotMessage][i], {encoding: 'base64'}), 'base64'))
|
335 | }
|
336 | }
|
337 | }
|
338 |
|
339 | allure.endStep(step.status)
|
340 | })
|
341 |
|
342 | this.on('step:pass', function (step) {
|
343 | const allure = this.getAllure(step.cid)
|
344 | logger('step:pass', step)
|
345 |
|
346 | allure.endStep('passed')
|
347 | })
|
348 |
|
349 | this.on('step:fail', function (step) {
|
350 | const allure = this.getAllure(step.cid)
|
351 | logger('step:fail', step)
|
352 |
|
353 | this.dumpJSON(allure, 'Verification Failures', step.errs)
|
354 |
|
355 | if (step.screenshots) {
|
356 | for (const screenshotMessage in step.screenshots) {
|
357 | for (let i = 0; i < step.screenshots[screenshotMessage].length; ++i) {
|
358 | allure.addAttachment(`${screenshotMessage} (${(i + 1)})`, new Buffer(fs.readFileSync(step.screenshots[screenshotMessage][i], {encoding: 'base64'}), 'base64'))
|
359 | }
|
360 | }
|
361 | }
|
362 |
|
363 | allure.endStep('failed')
|
364 | })
|
365 |
|
366 | this.on('step:broken', function (step) {
|
367 | const allure = this.getAllure(step.cid)
|
368 | logger('step:broken', step)
|
369 |
|
370 | this.dumpJSON(allure, 'Errors', step.assertion)
|
371 |
|
372 | if (step.assertion.screenshotFilename) {
|
373 | allure.addAttachment(step.assertion.message, new Buffer(fs.readFileSync(step.assertion.screenshotFilename, {encoding: 'base64'}), 'base64'))
|
374 | }
|
375 |
|
376 | allure.endStep('broken')
|
377 | })
|
378 |
|
379 | this.on('step:unverified', function (step) {
|
380 | const allure = this.getAllure(step.cid)
|
381 | logger('step:unverified', step)
|
382 |
|
383 | this.dumpJSON(allure, 'Unverified Specifications', step.err)
|
384 |
|
385 | allure.endStep('unknown')
|
386 | })
|
387 |
|
388 | |
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 | this.on('test:attach', function (attachment) {
|
399 | const allure = this.getAllure(attachment.cid)
|
400 | logger('test:attach', attachment)
|
401 |
|
402 | if (this.isAnyTestRunning(allure)) {
|
403 | error('ERROR', 'cannot attach because no test is running', attachment)
|
404 | return
|
405 | }
|
406 | allure.addAttachment(
|
407 | attachment.title,
|
408 | fs.readFileSync(attachment.file),
|
409 | attachment.type
|
410 | )
|
411 | })
|
412 |
|
413 | |
414 |
|
415 |
|
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 |
|
422 | this.on('test:log', function (log) {
|
423 | const allure = this.getAllure(log.cid)
|
424 | logger('test:log', log)
|
425 |
|
426 | if (this.isAnyTestRunning(allure)) {
|
427 | error('ERROR', 'cannot log because no test is running', log)
|
428 | return
|
429 | }
|
430 | const content = log.detail != null ? JSON.stringify(log.detail, null, ' ') : ''
|
431 | allure.addAttachment(
|
432 | log.message, content, 'application/json'
|
433 | )
|
434 | })
|
435 |
|
436 | this.on('runner:screenshot', function (command) {
|
437 |
|
438 | })
|
439 |
|
440 | this.on('hook:start', (hook) => {
|
441 | const allure = this.getAllure(hook.cid)
|
442 |
|
443 | if (!allure.getCurrentSuite() || LOGGING_HOOKS.indexOf(hook.title) === -1) {
|
444 | return
|
445 | }
|
446 |
|
447 | allure.startCase(hook.title)
|
448 | })
|
449 |
|
450 | this.on('hook:end', (hook) => {
|
451 | const allure = this.getAllure(hook.cid)
|
452 |
|
453 | if (!allure.getCurrentSuite() || LOGGING_HOOKS.indexOf(hook.title) === -1) {
|
454 | return
|
455 | }
|
456 |
|
457 | allure.endCase('passed')
|
458 |
|
459 | if (allure.getCurrentTest().steps.length === 0) {
|
460 | allure.getCurrentSuite().testcases.pop()
|
461 | }
|
462 | })
|
463 | }
|
464 |
|
465 | handleMetadata (meta) {
|
466 | var allure = this.getAllure(meta.cid)
|
467 | logger('test:meta', meta)
|
468 |
|
469 | if (!this.isAnyTestRunning(allure)) {
|
470 | error('ERROR', 'test:meta : NO TEST RUNNING')
|
471 | return
|
472 | }
|
473 | const currentTest = allure.getCurrentTest()
|
474 |
|
475 |
|
476 | if (meta.description) {
|
477 | currentTest.setDescription(meta.description)
|
478 | }
|
479 |
|
480 | if (meta.feature) {
|
481 | if (typeof (meta.feature) === 'string') {
|
482 | currentTest.addLabel('feature', meta.feature)
|
483 | } else {
|
484 | for (const i in meta.feature) {
|
485 | currentTest.addLabel('feature', meta.feature[i])
|
486 | }
|
487 | }
|
488 | }
|
489 | if (meta.story) {
|
490 | if (typeof (meta.story) === 'string') {
|
491 | currentTest.addLabel('story', meta.story)
|
492 | } else {
|
493 | for (const i in meta.story) {
|
494 | currentTest.addLabel('story', meta.story[i])
|
495 | }
|
496 | }
|
497 | }
|
498 | if (meta.issue) {
|
499 | if (typeof (meta.issue) === 'string') {
|
500 | currentTest.addLabel('issue', meta.issue)
|
501 | } else {
|
502 | for (const issue of meta.issue) {
|
503 | currentTest.addLabel('issue', issue)
|
504 | }
|
505 | }
|
506 | }
|
507 | if (meta.bug) {
|
508 | if (typeof (meta.bug) === 'string') {
|
509 | currentTest.addLabel('issue', this.getBug(meta.bug))
|
510 | currentTest.addLabel('bug', this.getBug(meta.bug))
|
511 | } else {
|
512 | for (const bug of meta.bug) {
|
513 | currentTest.addLabel('issue', this.getBug(bug))
|
514 | currentTest.addLabel('bug', this.getBug(bug))
|
515 | }
|
516 | }
|
517 | }
|
518 | if (meta.severity) {
|
519 | if (typeof (meta.severity) === 'string') {
|
520 | currentTest.addLabel('severity', meta.severity)
|
521 | } else {
|
522 | error('ERROR : meta.severity should be a string', meta)
|
523 | }
|
524 | }
|
525 |
|
526 | if (meta.argument) {
|
527 | if (typeof (meta.argument) === 'object') {
|
528 | const keys = Object.keys(meta.argument)
|
529 | for (const i in keys) {
|
530 | const key = keys[i]
|
531 | const val = meta.argument[key]
|
532 | currentTest.addParameter('argument', key, val)
|
533 | }
|
534 | } else {
|
535 | error('ERROR : meta.argument should be an object { name2: val1, name2: val2.. }', meta)
|
536 | }
|
537 | }
|
538 | if (meta.environment) {
|
539 | if (typeof (meta.environment) === 'object') {
|
540 | const keys = Object.keys(meta.environment)
|
541 | for (const i in keys) {
|
542 | const key = keys[i]
|
543 | const val = meta.environment[key]
|
544 | currentTest.addParameter('environment-variable', key, val)
|
545 | }
|
546 | } else {
|
547 | error('ERROR : meta.environment should be an object { name2: val1, name2: val2.. }', meta)
|
548 | }
|
549 | }
|
550 | }
|
551 |
|
552 | getBug (bug) {
|
553 | if (this.config.allure && this.config.allure.bugAppendix) {
|
554 | bug = `${bug}${this.config.allure.bugAppendix}`
|
555 | }
|
556 | if (this.config.allure && this.config.allure.bugPrefix) {
|
557 | bug = `${this.config.allure.bugPrefix}${bug}`
|
558 | }
|
559 | return bug
|
560 | }
|
561 |
|
562 |
|
563 | addArguments (test) {
|
564 | if (test.arguments) {
|
565 | for (const key in test.arguments) {
|
566 | if (test.arguments[key].value) {
|
567 | this.getAllure(test.cid).getCurrentTest().addParameter('argument', test.arguments[key].caption, test.arguments[key].value)
|
568 | }
|
569 | }
|
570 | }
|
571 | }
|
572 |
|
573 | buildResultStr (results) {
|
574 | let str = ''
|
575 |
|
576 | str += `${results.passing.count} passing (~${Math.round(results.passing.percentage)}%)`
|
577 |
|
578 | if (results.skipped.count > 0) {
|
579 | str += `, ${results.skipped.count} skipped (~${Math.round(results.skipped.percentage)}%)`
|
580 | }
|
581 |
|
582 | if (results.unverified.count > 0) {
|
583 | str += `, ${results.unverified.count} unverified (~${Math.round(results.unverified.percentage)}%)`
|
584 | }
|
585 |
|
586 | if (results.failing.count > 0) {
|
587 | str += `, ${results.failing.count} failing (~${Math.round(results.failing.percentage)}%)`
|
588 | }
|
589 |
|
590 | if (results.broken.count > 0) {
|
591 | str += `, ${results.broken.count} broken (~${Math.round(results.broken.percentage)}%)`
|
592 | }
|
593 |
|
594 | return str
|
595 | }
|
596 |
|
597 | addResultsDummy (test) {
|
598 | if (test.cid) {
|
599 | const allure = this.getAllure(test.cid)
|
600 | const currentTest = allure.getCurrentTest()
|
601 |
|
602 | this.testIds[currentTest] = true
|
603 |
|
604 | currentTest.addParameter('environment-variable', 'TESTCASE RESULTS: ', 'TESTCASE_RESULTS_STR')
|
605 | currentTest.addParameter('environment-variable', 'SPEC RESULTS: ', 'SPEC_RESULTS_STR')
|
606 | }
|
607 | }
|
608 |
|
609 | addResults () {
|
610 | const tcResults = this.baseReporter.getTestcaseResults()
|
611 | const specResults = this.baseReporter.getSpecResults()
|
612 |
|
613 | let tcResultsStr = this.buildResultStr(tcResults)
|
614 | let specResultsStr = this.buildResultStr(specResults)
|
615 |
|
616 | const latestRun = fs.readFileSync(this.config.latestRunPath, 'utf8')
|
617 |
|
618 |
|
619 |
|
620 | getAllFiles(path.join(this.config.resultsPath, latestRun), '.xml').forEach(
|
621 | file => {
|
622 | let content = fs.readFileSync(file, 'utf8')
|
623 |
|
624 | content = content.replace(/TESTCASE_RESULTS_STR/g, tcResultsStr)
|
625 | content = content.replace(/SPEC_RESULTS_STR/g, specResultsStr)
|
626 |
|
627 | fs.unlinkSync(file)
|
628 |
|
629 | fs.writeFileSync(file, content, 'utf8')
|
630 | }
|
631 | )
|
632 | }
|
633 |
|
634 | getAllure (cid) {
|
635 | if (typeof cid === 'undefined') {
|
636 | cid = process.workflo.cid
|
637 | } else {
|
638 | if (typeof process.workflo === 'undefined') {
|
639 | process.workflo = {
|
640 | }
|
641 | } else {
|
642 | process.workflo.currentCid = cid
|
643 | }
|
644 | }
|
645 |
|
646 | if (this.allures[cid]) {
|
647 | return this.allures[cid]
|
648 | }
|
649 |
|
650 | const allure = new Allure()
|
651 | allure.setOptions({ targetDir: this.options.outputDir || 'allure-results' })
|
652 | this.allures[cid] = allure
|
653 | return this.allures[cid]
|
654 | }
|
655 |
|
656 | isAnyTestRunning (allure) {
|
657 | return allure.getCurrentSuite() && allure.getCurrentTest()
|
658 | }
|
659 |
|
660 | dumpJSON (allure, name, json) {
|
661 | const jsonStr = JSON.stringify(json, null, ' ').split(`\\\"`).join(`'`).replace(/(?:\\n)/g, '')
|
662 | allure.addAttachment(name, jsonStr, 'application/json')
|
663 | }
|
664 | }
|
665 |
|
666 | const read = (dir) =>
|
667 | fs.readdirSync(dir)
|
668 | .reduce(
|
669 | (files, file) =>
|
670 | fs.statSync(path.join(dir, file)).isDirectory()
|
671 | ? files.concat(read(path.join(dir, file)))
|
672 | : files.concat(path.join(dir, file)),
|
673 | []
|
674 | )
|
675 |
|
676 | function getAllFiles (dirPath, extension) {
|
677 | return read(dirPath).filter(
|
678 | (fileName) => fileName.endsWith(extension)
|
679 | )
|
680 | }
|
681 |
|
682 | export default AllureReporter
|