import events from 'events'
import Allure from 'allure-js-commons'

/**
 * Initialize a new `Allure` test reporter.
 *
 * @param {Runner} runner
 * @api public
 */
class AllureReporter extends events.EventEmitter {
    constructor (baseReporter, config) {
        super()

        this.baseReporter = baseReporter
        this.config = config
        this.allure = new Allure()

        const { epilogue } = this.baseReporter

        this.on('end', () => {
            this.parseStats()
            epilogue.call(baseReporter)
        })
    }

    parseStats () {
        for (let cid of Object.keys(this.baseReporter.stats.runners)) {
            const capabilities = this.baseReporter.stats.runners[cid]

            for (let specId of Object.keys(capabilities.specs)) {
                const spec = capabilities.specs[specId]

                for (let suiteName of Object.keys(spec.suites)) {
                    const suite = spec.suites[suiteName]
                    this.allure.startSuite(suiteName, suite.start.getTime())

                    for (let testName of Object.keys(suite.tests)) {
                        const test = suite.tests[testName]

                        if (test.state === 'pending') {
                            this.allure.pendingCase(testName, test.start.getTime())
                            continue
                        }

                        this.allure.startCase(testName, test.start.getTime())

                        if (test.state === 'pass') {
                            this.allure.endCase('passed')
                        } else {
                            // TODO: determine if test was broken: status='broken'
                            this.allure.endCase('failed', test.error)
                        }

                        this.allure.getCurrentSuite().currentTest.addLabel('specId', specId)
                        this.allure.getCurrentSuite().currentTest.addLabel('capabilities', capabilities.sanitizedCapabilities)
                    }
                    this.allure.endSuite(spec.suites[suiteName].end.getTime())
                }
            }
        }
    }
}

export default AllureReporter

@@ -368,24 +368,103 @@
 w Allure()%0A%0A
+        // TODO: find a way to get options%0A        this.allure.setOptions(%7B%7D)%0A%0A
         cons
@@ -1545,95 +1545,418 @@
     
-if (test.state === 'pass') %7B%0A                            this.allure.endCase('passed')%0A
+// NB: 'parameters' are appropriate here, but not yet implemented: https://github.com/allure-framework/allure-js-commons/issues/8%0A                        // this.allure.getCurrentSuite().currentTest.addLabel('specId', specId)%0A                        // this.allure.getCurrentSuite().currentTest.addLabel('capabilities', capabilities.sanitizedCapabilities)%0A%0A                        test.output.map(output =%3E %7B%0A 
     
@@ -1979,14 +1979,31 @@
     
-%7D else
+   switch (output.type)
  %7B%0A 
@@ -2033,253 +2033,1083 @@
     
-// TODO: determine if test was broken: status='broken'%0A                            this.allure.endCase('failed', test.error)%0A                        %7D%0A%0A                        this.allure.getCurrentSuite().currentTest.addLabel('specId', specId)%0A
+case 'beforecommand':%0A                                this.allure.startStep(%0A                                    %60$%7Boutput.payload.command%7D $%7BJSON.stringify(output.payload.args)%7D%60,%0A                                    output.payload.time.getTime()%0A                                )%0A                                break%0A                            case 'aftercommand':%0A                                this.allure.endStep(%0A                                    %60$%7Boutput.payload.command%7D $%7BJSON.stringify(output.payload.args)%7D%60,%0A                                    output.payload.time.getTime()%0A                                )%0A                                break%0A                            case 'screenshot':%0A                                this.allure.startStep('screenshot', output.payload.time.getTime())%0A                                this.allure.addAttachment(%0A                                    %60$%7Boutput.payload.title%7D @ $%7Boutput.payload.parent%7D%60,%0A                                    new Buffer(output.payload.data, 'base64')%0A                                )%0A     
     
@@ -3120,32 +3120,35 @@
                 
+   
 this.allure.getC
@@ -3147,98 +3147,555 @@
 ure.
-getCurrentSuite().currentTest.addLabel('capabilities', capabilities.sanitizedCapabilities)
+endStep('screenshot', output.payload.time.getTime())%0A                                break%0A                            %7D%0A                        %7D)%0A%0A                        if (test.state === 'pass') %7B%0A                            this.allure.endCase('passed')%0A                        %7D else if (test.error && test.error.type === 'AssertionError') %7B%0A                            this.allure.endCase('failed', test.error)%0A                        %7D else %7B%0A                            this.allure.endCase('broken', test.error)%0A                        %7D
 %0A   
@@ -3780,16 +3780,46 @@
 ame%5D.end
+ && spec.suites%5BsuiteName%5D.end
 .getTime

Add commands (as steps) and screenshot attachments