🏡 index : quine-global/webdriverio.git

import WDIOReporter, { type RunnerStats } from '@wdio/reporter'
import type { Reporters } from '@wdio/types'

import type { ResultSet, TestSuite } from './types.js'

import { mapHooks, mapTests } from './utils.js'

export default class JsonReporter extends WDIOReporter {
    constructor (options: Reporters.Options) {
        if (options.logFile && options.logFile.endsWith('.log')) {
            options.logFile = options.logFile.slice(0, -4) + '.json'
        }
        super(options)
    }

    onRunnerEnd (runner: RunnerStats) {
        const json = this.#prepareJson(runner)
        this.write(JSON.stringify(json))
    }

    #prepareJson (runner: RunnerStats) {
        const resultSet: ResultSet = {
            start: runner.start,
            end: runner.end,
            capabilities: runner.capabilities,
            framework: runner.config.framework,
            mochaOpts: runner.config.mochaOpts,
            suites: [],
            specs: [],
            state: { passed: 0, failed: 0, skipped: 0 },
        }

        for (const spec of runner.specs) {
            resultSet.specs.push(spec)
            for (const suiteKey of Object.keys(this.suites)) {
                const suite = this.suites[suiteKey]
                const testSuite: TestSuite = {
                    name: suite.title,
                    duration: suite._duration,
                    start: suite.start,
                    end: suite.end,
                    sessionId: runner.sessionId,
                    tests: mapTests(suite.tests),
                    hooks: mapHooks(suite.hooks)
                }

                resultSet.state.failed += testSuite.hooks.filter(
                    (hook) => hook.error).length
                resultSet.state.passed += testSuite.tests.filter(
                    (test) => test.state === 'passed').length
                resultSet.state.failed += testSuite.tests.filter(
                    (test) => test.state === 'failed').length
                resultSet.state.skipped += testSuite.tests.filter(
                    (test) => test.state === 'skipped').length
                resultSet.suites.push(testSuite)
            }
        }

        return resultSet
    }
}