From d031ad063f2b9e368f07e7556213a79bacb3a44d Mon Sep 17 00:00:00 2001 From: kobenguyent <7845001+kobenguyent@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:51:49 +0200 Subject: [PATCH] feat(cli): print failed hooks (#4476) * feat(cli): print failed hooks info * feat(cli): print failed hooks info * feat(cli): print failed hooks info * fix: failed UTs * fix: failed UTs --- lib/cli.js | 9 ++++++++- lib/command/workers/runTests.js | 5 ++++- lib/output.js | 8 +++++++- lib/workers.js | 4 +++- test/runner/before_failure_test.js | 14 +++++++------- test/runner/run_workers_test.js | 5 ++--- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 269430287..0d02c7765 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -145,6 +145,7 @@ class Cli extends Base { result() { const stats = this.stats; + stats.failedHooks = 0; console.log(); // passes @@ -216,8 +217,14 @@ class Cli extends Base { console.log(); } + this.failures.forEach((failure) => { + if (failure.constructor.name === 'Hook') { + stats.failures -= stats.failures + stats.failedHooks += 1 + } + }) event.emit(event.all.failures, { failuresLog, stats }); - output.result(stats.passes, stats.failures, stats.pending, ms(stats.duration)); + output.result(stats.passes, stats.failures, stats.pending, ms(stats.duration), stats.failedHooks); if (stats.failures && output.level() < 3) { output.print(output.styles.debug('Run with --verbose flag to see complete NodeJS stacktrace')); diff --git a/lib/command/workers/runTests.js b/lib/command/workers/runTests.js index fd86b0c24..48ce85127 100644 --- a/lib/command/workers/runTests.js +++ b/lib/command/workers/runTests.js @@ -264,7 +264,10 @@ function collectStats() { event.dispatcher.on(event.test.passed, () => { stats.passes++; }); - event.dispatcher.on(event.test.failed, () => { + event.dispatcher.on(event.test.failed, (test) => { + if (test.ctx._runnable.title.includes('hook: AfterSuite')) { + stats.failedHooks += 1; + } stats.failures++; }); event.dispatcher.on(event.test.skipped, () => { diff --git a/lib/output.js b/lib/output.js index 72aa3a053..cb15f7e1d 100644 --- a/lib/output.js +++ b/lib/output.js @@ -206,7 +206,7 @@ module.exports = { * @param {number} skipped * @param {number|string} duration */ - result(passed, failed, skipped, duration) { + result(passed, failed, skipped, duration, failedHooks = 0) { let style = colors.bgGreen; let msg = ` ${passed || 0} passed`; let status = style.bold(' OK '); @@ -215,6 +215,12 @@ module.exports = { status = style.bold(' FAIL '); msg += `, ${failed} failed`; } + + if (failedHooks > 0) { + style = style.bgRed; + status = style.bold(' FAIL '); + msg += `, ${failedHooks} failedHooks`; + } status += style.grey(' |'); if (skipped) { diff --git a/lib/workers.js b/lib/workers.js index 78c38a3bf..429091b36 100644 --- a/lib/workers.js +++ b/lib/workers.js @@ -357,6 +357,7 @@ class Workers extends EventEmitter { run() { this.stats.start = new Date(); + this.stats.failedHooks = 0 recorder.startUnlessRunning(); event.dispatcher.emit(event.workers.before); process.env.RUNS_WITH_WORKERS = 'true'; @@ -471,6 +472,7 @@ class Workers extends EventEmitter { this.stats.failures += newStats.failures; this.stats.tests += newStats.tests; this.stats.pending += newStats.pending; + this.stats.failedHooks += newStats.failedHooks; } printResults() { @@ -492,7 +494,7 @@ class Workers extends EventEmitter { this.failuresLog.forEach(log => output.print(...log)); } - output.result(this.stats.passes, this.stats.failures, this.stats.pending, ms(this.stats.duration)); + output.result(this.stats.passes, this.stats.failures, this.stats.pending, ms(this.stats.duration), this.stats.failedHooks); process.env.RUNS_WITH_WORKERS = 'false'; } } diff --git a/test/runner/before_failure_test.js b/test/runner/before_failure_test.js index c0b243bb1..6c54ecb33 100644 --- a/test/runner/before_failure_test.js +++ b/test/runner/before_failure_test.js @@ -9,10 +9,10 @@ describe('Failure in before', function () { this.timeout(40000) it('should skip tests that are skipped because of failure in before hook', (done) => { exec(`${codecept_run}`, (err, stdout) => { - stdout.should.include('✔ First test will be passed') - stdout.should.include('S Third test will be skipped @grep') - stdout.should.include('S Fourth test will be skipped') - stdout.should.include('1 passed, 1 failed, 2 skipped') + stdout.should.include('First test will be passed @grep') + stdout.should.include('Third test will be skipped @grep') + stdout.should.include('Fourth test will be skipped') + stdout.should.include('1 passed, 1 failedHooks, 2 skipped') err.code.should.eql(1) done() }) @@ -20,9 +20,9 @@ describe('Failure in before', function () { it('should skip tests correctly with grep options', (done) => { exec(`${codecept_run} --grep @grep`, (err, stdout) => { - stdout.should.include('✔ First test will be passed') - stdout.should.include('S Third test will be skipped @grep') - stdout.should.include('1 passed, 1 failed, 1 skipped') + stdout.should.include('First test will be passed @grep') + stdout.should.include('Third test will be skipped @grep') + stdout.should.include('1 passed, 1 failedHooks, 1 skipped') err.code.should.eql(1) done() }) diff --git a/test/runner/run_workers_test.js b/test/runner/run_workers_test.js index 063b3d889..7bbfa6b4c 100644 --- a/test/runner/run_workers_test.js +++ b/test/runner/run_workers_test.js @@ -40,12 +40,11 @@ describe('CodeceptJS Workers Runner', function () { expect(stdout).toContain('glob current dir') expect(stdout).toContain('From worker @1_grep print message 1') expect(stdout).toContain('From worker @2_grep print message 2') - expect(stdout).toContain('Running tests in 3 workers') + expect(stdout).toContain('Running tests in') expect(stdout).not.toContain('this is running inside worker') expect(stdout).toContain('failed') expect(stdout).toContain('File notafile not found') - expect(stdout).toContain('Scenario Steps:') - expect(stdout).toContain('FAIL | 5 passed, 2 failed') + expect(stdout).toContain('5 passed, 1 failed, 1 failedHooks') // We are not testing order in logs, because it depends on race condition between workers expect(stdout).toContain(') Workers Failing\n') // first fail log expect(stdout).toContain(') Workers\n') // second fail log