From 6e25ac0fab717f4db31b8c4e75c09fee93263529 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Fri, 18 Oct 2024 13:19:42 +0200 Subject: [PATCH] fix json reports --- build/mocha-reporter.js | 110 ++++++++++++++++-- cypress.config.ts | 2 +- packages/core/src/utils/math.spec.ts | 2 +- .../tests/generate-typedoc-readme.spec.ts | 2 +- .../shared/tests/prepare-changelog.spec.ts | 2 +- 5 files changed, 103 insertions(+), 15 deletions(-) diff --git a/build/mocha-reporter.js b/build/mocha-reporter.js index 6f78873f2..0a4d6c2d5 100644 --- a/build/mocha-reporter.js +++ b/build/mocha-reporter.js @@ -1,23 +1,111 @@ const BaseReporter = require('mocha/lib/reporters/base'); const SpecReporter = require('mocha/lib/reporters/spec'); -// Cypress breaks the reporter ? -// https://github.com/cypress-io/cypress/issues/27636 -const JsonReporter = require('../node_modules/mocha/lib/reporters/json.js'); +const JsonReporter = require('mocha/lib/reporters/json'); const path = require('path'); +const fs = require('fs'); module.exports = class MultiReporter extends BaseReporter { constructor(runner, options) { super(runner, options); - - // mocha uses "reporterOption", cypress uses "reporterOptions" - const title = options.reporterOption?.title ?? options.reporterOptions?.title ?? 'report'; new SpecReporter(runner, {}); - new JsonReporter(runner, { - reporterOption: { - output: path.join(__dirname, '../reports', `${title}.json`), - }, - }); + if (options.reporterOptions?.cypress) { + new CypressJsonReporter(runner, { + reporterOption: { + output: path.join(__dirname, '../reports/e2e.json'), + }, + }); + } else { + new JsonReporter(runner, { + reporterOption: { + output: path.join(__dirname, '../reports', `${options.reporterOption.title}.json`), + }, + }); + } } }; + +// custom json reporter for cypress (for some reason, calling JsonReporter does not work) +// - write the results to a json file +// - fill the "file" property of each test +function CypressJsonReporter(runner, options) { + BaseReporter.call(this, runner, options); + + const tests = []; + const pending = []; + const failures = []; + const passes = []; + + runner.on('test end', function (test) { + tests.push(test); + }); + + runner.on('pass', function (test) { + passes.push(test); + }); + + runner.on('fail', function (test) { + failures.push(test); + }); + + runner.on('pending', function (test) { + pending.push(test); + }); + + runner.once('end', () => { + const obj = { + stats: this.stats, + tests: tests.map(clean), + pending: pending.map(clean), + failures: failures.map(clean), + passes: passes.map(clean) + }; + const json = JSON.stringify(obj, null, 2); + const output = options.reporterOption.output; + fs.mkdirSync(path.dirname(output), { recursive: true }); + fs.writeFileSync(output, json); + }); + + function clean(test) { + let err = test.err || {}; + if (err instanceof Error) { + err = errorJSON(err); + } + + return { + title: test.title, + fullTitle: test.fullTitle(), + file: test.invocationDetails.absoluteFile, + duration: test.duration, + currentRetry: test.currentRetry(), + speed: test.speed, + err: cleanCycles(err) + }; + } + + function cleanCycles(obj) { + let cache = []; + return JSON.parse( + JSON.stringify(obj, (key, value) => { + if (typeof value === 'object' && value !== null) { + if (cache.indexOf(value) !== -1) { + // Instead of going in a circle, we'll print [object Object] + return '' + value; + } + cache.push(value); + } + + return value; + }) + ); + } + + function errorJSON(err) { + let res = {}; + Object.getOwnPropertyNames(err).forEach((key) => { + res[key] = err[key]; + }, err); + return res; + } +} diff --git a/cypress.config.ts b/cypress.config.ts index 4f65407c7..9d49755df 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -10,6 +10,6 @@ export default defineConfig({ }, reporter: 'build/mocha-reporter.js', reporterOptions: { - title: 'e2e', + cypress: true, }, }); diff --git a/packages/core/src/utils/math.spec.ts b/packages/core/src/utils/math.spec.ts index 82968b586..b2b2fbf08 100644 --- a/packages/core/src/utils/math.spec.ts +++ b/packages/core/src/utils/math.spec.ts @@ -2,7 +2,7 @@ import assert from 'assert'; import { greatArcDistance } from './math'; describe('utils:math:greatArcDistance', () => { - it('', () => { + it('should compute the great-arc distance', () => { // easy assert.strictEqual(greatArcDistance([0, 0], [Math.PI, 0]), Math.PI); assert.strictEqual(greatArcDistance([Math.PI / 2, 0], [(3 * Math.PI) / 2, 0]), Math.PI); diff --git a/packages/shared/tests/generate-typedoc-readme.spec.ts b/packages/shared/tests/generate-typedoc-readme.spec.ts index 7b20d3565..c2b960c32 100644 --- a/packages/shared/tests/generate-typedoc-readme.spec.ts +++ b/packages/shared/tests/generate-typedoc-readme.spec.ts @@ -6,7 +6,7 @@ import assert from 'assert'; const testDir = path.join(__dirname, 'fixtures/generate-typedoc-readme'); describe('generate-typedoc-readme', () => { - it('should works', () => { + it('should generate the readme', () => { execSync(`node ${path.join(__dirname, '../../../build/generate-typedoc-readme.mjs')}`, { cwd: testDir }); const cases = { diff --git a/packages/shared/tests/prepare-changelog.spec.ts b/packages/shared/tests/prepare-changelog.spec.ts index 7ea1a79d3..7f7e59ad9 100644 --- a/packages/shared/tests/prepare-changelog.spec.ts +++ b/packages/shared/tests/prepare-changelog.spec.ts @@ -6,7 +6,7 @@ import assert from 'assert'; const testDir = path.join(__dirname, 'fixtures/prepare-changelog'); describe('prepare-changelog', () => { - it('should works', (done) => { + it('should generate the changelog', (done) => { const gitLog = readFileSync(path.join(testDir, 'git-log.txt'), { encoding: 'utf8' }); const proc = exec(`node ${path.join(__dirname, '../../../build/prepare-changelog.mjs')} 5.7.4 5.8.0`, { cwd: testDir }, (err) => {