From 43c6603743fb30bba3b8c9d4703ff6daffb52f7b Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 11:35:38 +0200 Subject: [PATCH 01/14] added tests - current behavior --- tests/cy-helper/utils.ts | 39 +- .../nested-suite-before-fail-01.cy.ts | 28 + .../nested-suite-before-pass-02.cy.ts | 27 + .../mocha-events/hooks/nested-suites.test.ts | 617 ++++++++++++++++++ 4 files changed, 704 insertions(+), 7 deletions(-) create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites.test.ts diff --git a/tests/cy-helper/utils.ts b/tests/cy-helper/utils.ts index aa9d0cfb..41af0bdf 100644 --- a/tests/cy-helper/utils.ts +++ b/tests/cy-helper/utils.ts @@ -172,6 +172,19 @@ export const sortAttachments = (res: AllureTest[]) => { }); }; +// eslint-disable-next-line jest/no-export +export const labelsForTest = (res: AllureTest[], filterLabels: string[]) => { + return res + .map(t => ({ labels: t.labels, name: t.name })) + .sort((a, b) => ((a as any).name < (b as any).name ? -1 : 1)) + .map(t => ({ + ...t, + labels: t.labels.filter(x => + filterLabels.length > 0 ? filterLabels.includes(x.name) : true, + ), + })); +}; + // eslint-disable-next-line jest/no-export export const fullStepAttachment = ( res: AllureTest[], @@ -263,11 +276,14 @@ export const readWithRetry = (path: string, attempt = 0) => { }; // eslint-disable-next-line jest/no-export -export const createResTest2 = ( - specTexts: string[], - envConfig?: Record, - shouldBeResults?: boolean, -): { +export const eventsForFile = (res: Result, fileName: string): string[] => { + return readWithRetry(res.specs.filter(x => x.indexOf(fileName) !== -1)[0]) + ?.toString() + .split('\n') + .filter(t => t !== ''); +}; + +type Result = { watch: string; specs: string[]; result: { @@ -276,7 +292,14 @@ export const createResTest2 = ( | CypressCommandLine.CypressFailedRunResult | undefined; }; -} => { +}; + +// eslint-disable-next-line jest/no-export +export const createResTest2 = ( + specTexts: string[], + envConfig?: Record, + shouldBeResults?: boolean, +): Result => { const result: { res: | CypressCommandLine.CypressRunResult @@ -343,6 +366,8 @@ export const createResTest2 = ( }; it('create results jest', async () => { + jest.retryTimes(1); + // eslint-disable-next-line @typescript-eslint/no-var-requires const cy = require('cypress'); @@ -405,7 +430,7 @@ export const createResTest2 = ( } }) .then(() => { - if (shouldBeResults) { + if (shouldBeResults !== false) { return checkFilesExist(10); } }); diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts new file mode 100644 index 00000000..052b0f9f --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts @@ -0,0 +1,28 @@ +/** + * When hook in child suite fails + * - result should have proper suite structure + * - attachments + * - steps + * - video in tear down + */ +describe('Suite01 failure in nested suite before hook', () => { + it('test 0', () => { + cy.log('test 1'); + }); + + describe('hooks test - child', () => { + describe('hooks test - sub child', () => { + before(' in suite', () => { + throw new Error('Failure in hook'); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); + }); +}); diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts new file mode 100644 index 00000000..c9213f0e --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts @@ -0,0 +1,27 @@ +/** + * When hook in child suite passed + * - result should have proper suite structure + * - attachments + * - steps + */ +describe('Suite02 before hook passes in nested suite', () => { + it('test 0', () => { + cy.log('test 1'); + }); + + describe('hooks test - child', () => { + describe('hooks test - sub child', () => { + before('in suite', () => { + cy.log('before'); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); + }); +}); diff --git a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts new file mode 100644 index 00000000..78874022 --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts @@ -0,0 +1,617 @@ +import { + covergeAfterAllEvent, + createResTest2, + eventsForFile, + fixResult, + fullStepAttachment, + labelsForTest, + whenCoverage, + whenNoCoverage, +} from '../../../cy-helper/utils'; +import { AllureTest, parseAllure } from 'allure-js-parser'; +import { readFileSync } from 'fs'; +import { basename } from 'path'; + +describe('nested suites', () => { + const testsForRun = [ + { path: `${__dirname}/nested-suites-cy/nested-suite-before-fail-01.cy.ts` }, + { path: `${__dirname}/nested-suites-cy/nested-suite-before-pass-02.cy.ts` }, + ]; + + const res = createResTest2( + testsForRun.map(x => readFileSync(x.path).toString()), + { allureAddVideoOnPass: 'true', DEBUG: 'true' }, + ); + + describe(`Check results for ${basename(testsForRun[0].path)}`, () => { + let resFixed: AllureTest[]; + + beforeAll(() => { + const results = parseAllure(res.watch).filter( + t => t.fullName?.indexOf('Suite01') !== -1, + ); + resFixed = fixResult(results); + }); + + it('check tests names', async () => { + expect(resFixed.map(t => t.fullName).sort()).toEqual([ + 'Suite01 failure in nested suite before hook hooks test - child hooks test - sub child test 1', + 'Suite01 failure in nested suite before hook hooks test - child hooks test - sub child test 2', + 'Suite01 failure in nested suite before hook test 0', + ]); + }); + + it('should have correct events for spec', async () => { + const events = eventsForFile(res, basename(res.specs[0])); + + expect(events).toEqual([ + 'mocha: start', + 'mocha: suite: , ', + ...whenCoverage( + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 0', + 'mocha: hook end: "before all" hook', + ), + 'mocha: suite: Suite01 failure in nested suite before hook, Suite01 failure in nested suite before hook', + 'mocha: test: test 0', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 0', + 'mocha: test end: test 0', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'cypress: test:after:run: test 0', + 'plugin test:ended', + 'mocha: suite: hooks test - child, Suite01 failure in nested suite before hook hooks test - child', + 'mocha: suite: hooks test - sub child, Suite01 failure in nested suite before hook hooks test - child hooks test - sub child', + 'mocha: hook: "before all" hook: in suite', + ...whenNoCoverage('cypress: test:before:run: test 1'), + 'cypress: test:before:run: test 1', + 'cypress:screenshot:test:Suite01 failure in nested suite before hook -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in suite (failed).png', + 'mocha: fail: "before all" hook: in suite for "test 1"', + 'mocha: suite end: hooks test - sub child', + 'mocha: suite end: hooks test - child', + 'mocha: suite end: Suite01 failure in nested suite before hook', + + ...whenCoverage(...covergeAfterAllEvent), + 'cypress: test:after:run: test 1', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'mocha: suite end: ', + 'mocha: end', + ]); + }); + + it('check suite labels', async () => { + expect( + labelsForTest(resFixed, ['suite', 'parentSuite', 'subSuite']), + ).toEqual([ + { + name: 'test 0', + labels: [ + { + name: 'parentSuite', + value: 'Suite01 failure in nested suite before hook', + }, + //{ name: 'suite', value: 'hooks test - child' }, + ], + }, + { + name: 'test 1', + labels: [ + { + name: 'parentSuite', + value: 'Suite01 failure in nested suite before hook', + }, + ], + }, + { + name: 'test 2', + labels: [ + { + name: 'parentSuite', + value: 'Suite01 failure in nested suite before hook', + }, + ], + }, + ]); + }); + + it('check test with screenshot', async () => { + const obj = fullStepAttachment(resFixed, m => ({ + name: m.name, + attachments: m.attachments, + })); + + obj[0].steps = obj[0].steps.filter( + t => + t.name.indexOf('after each') === -1 && + t.name.indexOf('before each') === -1, + ); + + expect(obj).toEqual([ + { + attachments: [], + name: 'test 0', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite01 failure in nested suite before hook', + }, + ], + status: 'passed', + steps: [ + { + attachments: [], + name: 'log: test 1', + steps: [], + }, + ], + }, + { + attachments: [], + name: 'test 1', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite01 failure in nested suite before hook', + }, + ], + status: 'failed', + steps: [], + }, + { + attachments: [], + name: 'test 2', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite01 failure in nested suite before hook', + }, + ], + status: 'unknown', + steps: [], + }, + ]); + }); + }); + + describe(`Check results for ${basename(testsForRun[1].path)}`, () => { + let resFixed: AllureTest[]; + + beforeAll(() => { + const results = parseAllure(res.watch).filter( + t => t.fullName?.indexOf('Suite02') !== -1, + ); + resFixed = fixResult(results); + }); + + it('check tests names', async () => { + expect(resFixed.map(t => t.fullName).sort()).toEqual([ + 'Suite02 before hook passes in nested suite hooks test - child hooks test - sub child test 1', + 'Suite02 before hook passes in nested suite hooks test - child hooks test - sub child test 2', + 'Suite02 before hook passes in nested suite test 0', + ]); + }); + + it('should have correct events for spec', async () => { + const events = eventsForFile(res, basename(res.specs[0])); + + expect(events).toEqual([ + 'mocha: start', + 'mocha: suite: , ', + ...whenCoverage( + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 0', + 'mocha: hook end: "before all" hook', + ), + 'mocha: suite: Suite01 failure in nested suite before hook, Suite01 failure in nested suite before hook', + 'mocha: test: test 0', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 0', + 'mocha: test end: test 0', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'cypress: test:after:run: test 0', + 'plugin test:ended', + 'mocha: suite: hooks test - child, Suite01 failure in nested suite before hook hooks test - child', + 'mocha: suite: hooks test - sub child, Suite01 failure in nested suite before hook hooks test - child hooks test - sub child', + 'mocha: hook: "before all" hook: in suite', + ...whenNoCoverage('cypress: test:before:run: test 1'), + 'cypress: test:before:run: test 1', + 'cypress:screenshot:test:Suite01 failure in nested suite before hook -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in suite (failed).png', + 'mocha: fail: "before all" hook: in suite for "test 1"', + 'mocha: suite end: hooks test - sub child', + 'mocha: suite end: hooks test - child', + 'mocha: suite end: Suite01 failure in nested suite before hook', + + ...whenCoverage(...covergeAfterAllEvent), + 'cypress: test:after:run: test 1', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'mocha: suite end: ', + 'mocha: end', + ]); + }); + + it('check suite labels', async () => { + expect( + labelsForTest(resFixed, ['suite', 'parentSuite', 'subSuite']), + ).toEqual([ + { + name: 'test 0', + labels: [ + { + name: 'parentSuite', + value: 'Suite02 before hook passes in nested suite', + }, + //{ name: 'suite', value: 'hooks test - child' }, + ], + }, + { + name: 'test 1', + labels: [ + { + name: 'parentSuite', + value: 'Suite02 before hook passes in nested suite', + }, + { name: 'suite', value: 'hooks test - child' }, + { name: 'subSuite', value: 'hooks test - sub child' }, + ], + }, + { + name: 'test 2', + labels: [ + { + name: 'parentSuite', + value: 'Suite02 before hook passes in nested suite', + }, + { + name: 'suite', + value: 'hooks test - child', + }, + { + name: 'subSuite', + value: 'hooks test - sub child', + }, + ], + }, + ]); + }); + + it('check test with screenshot', async () => { + const obj = fullStepAttachment(resFixed, m => ({ + name: m.name, + attachments: m.attachments, + })); + + obj[0].steps = obj[0].steps.filter( + t => + t.name.indexOf('after each') === -1 && + t.name.indexOf('before each') === -1, + ); + + expect(obj).toEqual([ + { + attachments: [], + name: 'test 0', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_1_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite02 before hook passes in nested suite', + }, + ], + status: 'passed', + steps: [ + { + attachments: [], + name: 'log: test 1', + steps: [], + }, + ], + }, + { + attachments: [], + name: 'test 1', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_1_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + { + attachments: [], + name: '"before all" hook: in suite', + status: 'passed', + steps: [ + { + attachments: [], + name: 'log: before', + steps: [], + }, + ], + }, + ], + suiteName: 'hooks test - sub child', + }, + { + afters: [], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'hooks test - child', + }, + { + afters: [ + { + attachments: [ + { + name: 'test_1_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite02 before hook passes in nested suite', + }, + ], + status: 'passed', + steps: [ + { + attachments: [], + name: '"before each" hook', + steps: [], + }, + { + attachments: [], + name: 'log: test 1', + steps: [], + }, + { + attachments: [], + name: '"after each" hook', + steps: [ + { + attachments: [], + name: 'log: 👉 Only found unit test code coverage. `[@cypress/code-coverage]`', + steps: [], + }, + ], + }, + ], + }, + { + attachments: [], + name: 'test 2', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_1_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + { + attachments: [], + name: '"before all" hook: in suite', + status: 'passed', + steps: [ + { + attachments: [], + name: 'log: before', + steps: [], + }, + ], + }, + ], + suiteName: 'hooks test - sub child', + }, + { + afters: [], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'hooks test - child', + }, + { + afters: [ + { + attachments: [ + { + name: 'test_1_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite02 before hook passes in nested suite', + }, + ], + status: 'passed', + steps: [ + { + attachments: [], + name: '"before each" hook', + steps: [], + }, + { + attachments: [], + name: 'log: test 2', + steps: [], + }, + { + attachments: [], + name: '"after each" hook', + steps: [ + { + attachments: [], + name: 'log: 👉 Only found unit test code coverage. `[@cypress/code-coverage]`', + steps: [], + }, + ], + }, + ], + }, + ]); + }); + }); +}); From b1b2202f2f459dadafe7c767711660a82297f271 Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 11:57:10 +0200 Subject: [PATCH 02/14] fix --- .../mocha-events/hooks/nested-suites.test.ts | 207 ++++++++++++++++-- 1 file changed, 193 insertions(+), 14 deletions(-) diff --git a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts index 78874022..de6c47d1 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts @@ -16,6 +16,9 @@ describe('nested suites', () => { const testsForRun = [ { path: `${__dirname}/nested-suites-cy/nested-suite-before-fail-01.cy.ts` }, { path: `${__dirname}/nested-suites-cy/nested-suite-before-pass-02.cy.ts` }, + { + path: `${__dirname}/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts`, + }, ]; const res = createResTest2( @@ -25,6 +28,7 @@ describe('nested suites', () => { describe(`Check results for ${basename(testsForRun[0].path)}`, () => { let resFixed: AllureTest[]; + const specName = basename(res.specs[0]); beforeAll(() => { const results = parseAllure(res.watch).filter( @@ -42,7 +46,7 @@ describe('nested suites', () => { }); it('should have correct events for spec', async () => { - const events = eventsForFile(res, basename(res.specs[0])); + const events = eventsForFile(res, specName); expect(events).toEqual([ 'mocha: start', @@ -245,6 +249,7 @@ describe('nested suites', () => { describe(`Check results for ${basename(testsForRun[1].path)}`, () => { let resFixed: AllureTest[]; + const specName = basename(res.specs[1]); beforeAll(() => { const results = parseAllure(res.watch).filter( @@ -262,7 +267,7 @@ describe('nested suites', () => { }); it('should have correct events for spec', async () => { - const events = eventsForFile(res, basename(res.specs[0])); + const events = eventsForFile(res, specName); expect(events).toEqual([ 'mocha: start', @@ -272,7 +277,7 @@ describe('nested suites', () => { 'cypress: test:before:run: test 0', 'mocha: hook end: "before all" hook', ), - 'mocha: suite: Suite01 failure in nested suite before hook, Suite01 failure in nested suite before hook', + 'mocha: suite: Suite02 before hook passes in nested suite, Suite02 before hook passes in nested suite', 'mocha: test: test 0', 'plugin test:started', 'mocha: hook: "before each" hook', @@ -283,23 +288,38 @@ describe('nested suites', () => { 'mocha: hook end: "after each" hook', 'cypress: test:after:run: test 0', 'plugin test:ended', - 'mocha: suite: hooks test - child, Suite01 failure in nested suite before hook hooks test - child', - 'mocha: suite: hooks test - sub child, Suite01 failure in nested suite before hook hooks test - child hooks test - sub child', - 'mocha: hook: "before all" hook: in suite', + 'mocha: suite: hooks test - child, Suite02 before hook passes in nested suite hooks test - child', + 'mocha: suite: hooks test - sub child, Suite02 before hook passes in nested suite hooks test - child hooks test - sub child', + 'mocha: hook: "before all" hook: in suite', ...whenNoCoverage('cypress: test:before:run: test 1'), 'cypress: test:before:run: test 1', - 'cypress:screenshot:test:Suite01 failure in nested suite before hook -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in suite (failed).png', - 'mocha: fail: "before all" hook: in suite for "test 1"', + 'mocha: hook end: "before all" hook: in suite', + 'mocha: test: test 1', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 1', + 'mocha: test end: test 1', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'cypress: test:after:run: test 1', + 'plugin test:ended', + 'mocha: test: test 2', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'cypress: test:before:run: test 2', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 2', + 'mocha: test end: test 2', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', 'mocha: suite end: hooks test - sub child', 'mocha: suite end: hooks test - child', - 'mocha: suite end: Suite01 failure in nested suite before hook', + 'mocha: suite end: Suite02 before hook passes in nested suite', ...whenCoverage(...covergeAfterAllEvent), - 'cypress: test:after:run: test 1', - 'plugin test:ended', - 'plugin test:started', - 'plugin test:ended', - 'plugin test:started', + + 'cypress: test:after:run: test 2', 'plugin test:ended', 'mocha: suite end: ', 'mocha: end', @@ -614,4 +634,163 @@ describe('nested suites', () => { ]); }); }); + + describe('Check results for Suite03', () => { + let resFixed: AllureTest[]; + const specName = basename(res.specs[2]); + + beforeAll(() => { + const results = parseAllure(res.watch).filter( + t => t.fullName?.indexOf('Suite03') !== -1, + ); + resFixed = fixResult(results); + }); + + it('check tests names', async () => { + expect(resFixed.map(t => t.fullName).sort()).toEqual([ + 'Suite03 failure in nested suite before hook hooks test - child test 1', + 'Suite03 failure in nested suite before hook hooks test - child test 2', + ]); + }); + + it('should have correct events for spec', async () => { + const events = eventsForFile(res, specName); + + expect(events).toEqual([ + 'mocha: start', + 'mocha: suite: , ', + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 1', + 'mocha: hook end: "before all" hook', + 'mocha: suite: Suite03 failure in nested suite before hook, Suite03 failure in nested suite before hook', + 'mocha: suite: hooks test - child, Suite03 failure in nested suite before hook hooks test - child', + 'mocha: hook: "before all" hook: in suite', + 'cypress:screenshot:test:Suite03 failure in nested suite before hook -- hooks test - child -- test 1 -- before all hook in suite (failed).png', + 'mocha: fail: "before all" hook: in suite for "test 1"', + 'mocha: suite end: hooks test - child', + 'mocha: suite end: Suite03 failure in nested suite before hook', + 'mocha: hook: "after all" hook: collectBackendCoverage', + 'mocha: hook end: "after all" hook: collectBackendCoverage', + 'mocha: hook: "after all" hook: mergeUnitTestCoverage', + 'mocha: hook end: "after all" hook: mergeUnitTestCoverage', + 'mocha: hook: "after all" hook: generateReport', + 'mocha: hook end: "after all" hook: generateReport', + 'cypress: test:after:run: test 1', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'mocha: suite end: ', + 'mocha: end', + ]); + }); + + it('check suite labels', async () => { + expect( + labelsForTest(resFixed, ['suite', 'parentSuite', 'subSuite']), + ).toEqual([ + { + labels: [ + { + name: 'parentSuite', + value: 'Suite03 failure in nested suite before hook', + }, + ], + name: 'test 1', + }, + { + labels: [ + { + name: 'parentSuite', + value: 'Suite03 failure in nested suite before hook', + }, + ], + name: 'test 2', + }, + ]); + }); + + it('check test with screenshot', async () => { + const obj = fullStepAttachment(resFixed, m => ({ + name: m.name, + attachments: m.attachments, + })); + + obj[0].steps = obj[0].steps.filter( + t => + t.name.indexOf('after each') === -1 && + t.name.indexOf('before each') === -1, + ); + + expect(obj).toEqual([ + { + attachments: [], + name: 'test 1', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_2_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite03 failure in nested suite before hook', + }, + ], + status: 'failed', + steps: [], + }, + { + attachments: [], + name: 'test 2', + parents: [ + { + afters: [ + { + attachments: [ + { + name: 'test_2_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + name: 'video', + status: 'passed', + steps: [], + }, + ], + befores: [ + { + attachments: [], + name: '"before all" hook', + status: 'passed', + steps: [], + }, + ], + suiteName: 'Suite03 failure in nested suite before hook', + }, + ], + status: 'unknown', + steps: [], + }, + ]); + }); + }); }); From 55ef7f5ce817cdad364bcac78e0abacfee715133 Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 11:57:26 +0200 Subject: [PATCH 03/14] fix 2 --- .../nested-suite-before-fail-simple-03.cy.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts new file mode 100644 index 00000000..b9de1edf --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts @@ -0,0 +1,22 @@ +/** + * When hook in child suite fails + * - result should have proper suite structure + * - attachments + * - steps + * - video in tear down + */ +describe('Suite03 failure in nested suite before hook', () => { + describe('hooks test - child', () => { + before(' in suite', () => { + throw new Error('Failure in hook'); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); +}); From b666fd5bfa933a3f81a53358c019ea94a6ae0758 Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 16:17:14 +0200 Subject: [PATCH 04/14] tests version --- .eslintrc.js | 1 + jest.config.ts | 3 + tests/.eslintrc.js | 2 + tests/cy-helper/utils.ts | 274 +++++- .../nested-suite-before-fail-01.cy.ts | 28 - .../nested-suite-before-fail-01.ts | 238 ++++++ .../nested-suite-before-fail-simple-03.cy.ts | 22 - .../nested-suite-before-fail-simple-03.ts | 215 +++++ .../nested-suite-before-pass-02.cy.ts | 27 - .../nested-suite-before-pass-02.ts | 184 ++++ .../mocha-events/hooks/nested-suites.test.ts | 798 +----------------- tests/tsconfig.json | 6 +- 12 files changed, 926 insertions(+), 872 deletions(-) delete mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts delete mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts delete mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts diff --git a/.eslintrc.js b/.eslintrc.js index 89db4bba..078858dc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -12,6 +12,7 @@ module.exports = { ignorePatterns: ['*.yaml', '*.yml', '*.csv'], rules: { + 'jest/no-export': 'off', '@typescript-eslint/no-explicit-any': 'warn', 'prefer-template': 'error', quotes: ['error', 'single', { avoidEscape: true }], diff --git a/jest.config.ts b/jest.config.ts index dc258a8d..9b66925d 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -42,6 +42,9 @@ export default { '!**/tests/test-folder/allure-plugin/**/?(*.)+(spec|test).[tj]s?(x)', '!**/lib/**/*.*', ], + moduleNameMapper: { + '^@test-utils$': '/tests/cy-helper/utils.ts', + }, transform: { '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tests/tsconfig.json' }], diff --git a/tests/.eslintrc.js b/tests/.eslintrc.js index e8b46668..36c7dae9 100644 --- a/tests/.eslintrc.js +++ b/tests/.eslintrc.js @@ -6,6 +6,8 @@ module.exports = { extends: [...original.extends, 'plugin:jest/recommended'], rules: { ...original.rules, + + '@typescript-eslint/no-var-requires': 'off', '@typescript-eslint/no-explicit-any': 'off', 'jest/no-standalone-expect': 'off', '@typescript-eslint/no-non-null-assertion': 'off', diff --git a/tests/cy-helper/utils.ts b/tests/cy-helper/utils.ts index 41af0bdf..209b57db 100644 --- a/tests/cy-helper/utils.ts +++ b/tests/cy-helper/utils.ts @@ -1,11 +1,11 @@ import { execSync } from 'child_process'; import path, { basename } from 'path'; import { delay } from 'jest-test-each/dist/tests/utils/utils'; -import { AllureTest, getParentsArray } from 'allure-js-parser'; +import { AllureTest, getParentsArray, parseAllure } from 'allure-js-parser'; import { StepResult } from 'allure-js-commons'; import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'; import { parseBoolean } from 'cypress-redirect-browser-log/utils/functions'; -import { AllureHook } from 'allure-js-parser/types'; +import { AllureHook, Parent } from 'allure-js-parser/types'; jest.setTimeout(120000); @@ -173,14 +173,16 @@ export const sortAttachments = (res: AllureTest[]) => { }; // eslint-disable-next-line jest/no-export -export const labelsForTest = (res: AllureTest[], filterLabels: string[]) => { +export const labelsForTest = (res: AllureTest[], filterLabels?: string[]) => { return res .map(t => ({ labels: t.labels, name: t.name })) .sort((a, b) => ((a as any).name < (b as any).name ? -1 : 1)) .map(t => ({ ...t, labels: t.labels.filter(x => - filterLabels.length > 0 ? filterLabels.includes(x.name) : true, + filterLabels && filterLabels.length > 0 + ? filterLabels.includes(x.name) + : true, ), })); }; @@ -566,3 +568,267 @@ export const covergeBeforeAll = [ stop: 1323475200010, }, ]; + +export type TestData = { + name: string; + rootSuite: string; + spec: string; + fileName: string; + expect: { + labels?: { filter: string[]; expected: any[] }; + events?: string[]; + testsNames: string[]; + + testStatuses?: { + testName: string; + status: string; + statusDetails?: { message: string[] | undefined }; + }[]; + + testAttachments?: { + expectMessage?: string; // message to show in test title + testName: string; + attachments: any[]; + }[]; + + testParents?: { + testName: string; + parents: { name: string; parent: string | undefined }[]; + }[]; + + steps?: { + filter: string[]; + expected: any[]; + }; + + parents?: { + testName: string; + containers: { + name: string; + befores?: { + name?: string; + attachments?: any[]; + }[]; + afters?: { + name?: string; + attachments?: any[]; + }[]; + }[]; + }[]; + }; +}; + +const wrapExpectCreate = (addition: string) => (fn: () => any) => { + try { + fn(); + } catch (e) { + const err = e as Error; + err.message = addition + err.message; + throw err; + } +}; + +export const generateChecksTests = (res: Result, testsForRun: TestData[]) => { + testsForRun.forEach((testData, i) => { + // path.relative(process.cwd(), testData.fileName) + const wrapError = wrapExpectCreate( + `Failed test file: ${basename(testData.fileName)}\nRoot suite: ${testData.name}\n\n`, + ); + + describe(`${testData.name}`, () => { + let resFixed: AllureTest[]; + + beforeAll(() => { + const results = parseAllure(res.watch).filter( + t => t.fullName?.indexOf(testData.rootSuite) !== -1, + ); + resFixed = fixResult(results); + }); + + if (testData.expect.testsNames) { + it('check test full names', () => { + wrapError(() => + expect(resFixed.map(t => t.fullName).sort()).toEqual( + testData.expect.testsNames, + ), + ); + }); + } + + if (testData.expect.testStatuses) { + testData.expect.testStatuses.forEach(t => { + it(`should have test '${t.testName}' status - ${t.status}`, () => { + expect(resFixed.find(x => t.testName === x.name)?.status).toEqual( + t.status, + ); + }); + + if (t.statusDetails) { + it(`should have test '${t.testName}' statusDetails`, () => { + wrapError(() => + expect( + resFixed + .find(x => t.testName === x.name) + ?.statusDetails?.message?.split('\n'), + ).toEqual(t.statusDetails?.message), + ); + }); + } + }); + } + + if (testData.expect.labels) { + it(`check ${testData.expect.labels?.filter?.join(',') ?? ' all'} labels`, () => { + wrapError(() => + expect( + labelsForTest(resFixed, testData.expect.labels?.filter), + ).toEqual(testData.expect.labels?.expected), + ); + }); + } + + if (testData.expect.events) { + it('should have correct events for spec', () => { + const specName = basename(res.specs[i]); + const events = eventsForFile(res, specName); + + const skipItems = [ + 'collectBackendCoverage', + 'mergeUnitTestCoverage', + 'generateReport', + ]; + + wrapError(() => + expect( + events.filter(x => skipItems.every(z => x.indexOf(z) === -1)), + ).toEqual(testData.expect.events), + ); + }); + } + + if (testData.expect.testAttachments) { + testData.expect.testAttachments.forEach(t => { + it(`check '${t.testName}' attachments${t.expectMessage ? `: ${t.expectMessage}` : ''}`, () => { + wrapError(() => + expect( + resFixed.find(x => t.testName === x.name)?.attachments, + ).toEqual(t.attachments), + ); + }); + }); + } + + if (testData.expect.testParents) { + testData.expect.testParents.forEach(testItem => { + it(`parents for test ${testItem.testName}`, () => { + const test = resFixed.find(x => testItem.testName === x.name); + const parents = getParentsArray(test); + + wrapError(() => + expect( + parents.map(x => ({ name: x.name, parent: x.parent?.name })), + ).toEqual(testItem.parents), + ); + }); + }); + } + + if (testData.expect.parents) { + testData.expect.parents.forEach(testData => { + describe(`parents for ${testData.testName}`, () => { + let test; + let parents: Parent[]; + const skipItems = ['generatereport', 'coverage']; + + beforeAll(() => { + test = resFixed.find(x => testData.testName === x.name); + parents = getParentsArray(test); + }); + + // it('check parent names', () => { + // + // wrapError(() =>expect(parents.map(x => x.name)).toEqual( + // testData.containers.map(x => x.name), + // )); + // }); + + describe('before and after hooks', () => { + testData.containers.forEach(container => { + if (container.befores) { + it(`check befores for '${testData.testName}' parent '${container.name}'`, () => { + const actualParent = parents.find( + pp => pp.name === container.name, + ); + + const actualBefores = ( + actualParent?.befores as AllureHook[] + ) + ?.filter(z => + skipItems.every( + y => z.name.toLowerCase().indexOf(y) === -1, + ), + ) + ?.filter(z => { + return !z.steps.some( + s => s.name?.indexOf('code-coverage') !== -1, + ); + }) + .sort((z1, z2) => + z1.name && z2.name && z1.name < z2.name ? -1 : 1, + ); + + wrapError(() => + expect(actualBefores?.map(x => x.name)).toEqual( + container.befores?.map(x => x.name), + ), + ); + + if (container.befores?.some(t => t.attachments)) { + wrapError(() => + // eslint-disable-next-line jest/no-conditional-expect + expect(actualBefores?.map(x => x.attachments)).toEqual( + container.befores?.map(x => x.attachments), + ), + ); + } + }); + } + + if (container.afters) { + it(`check afters for '${testData.testName}' parent '${container.name}'`, () => { + const actualParent = parents.find( + pp => pp.name === container.name, + ); + + const actualAfters = (actualParent?.afters as AllureHook[]) + ?.filter(z => + skipItems.every( + y => z.name.toLowerCase().indexOf(y) === -1, + ), + ) + .sort((z1, z2) => + z1.name && z2.name && z1.name < z2.name ? -1 : 1, + ); + + expect(actualAfters?.map(x => x.name)).toEqual( + container.afters?.map(x => x.name), + ); + + if (container.afters?.some(t => t.attachments)) { + wrapError(() => + // eslint-disable-next-line jest/no-conditional-expect + expect(actualAfters?.map(x => x.attachments)).toEqual( + container.afters?.map(x => x.attachments), + ), + ); + } + }); + } + }); + }); + }); + }); + } + }); + }); +}; diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts deleted file mode 100644 index 052b0f9f..00000000 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.cy.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * When hook in child suite fails - * - result should have proper suite structure - * - attachments - * - steps - * - video in tear down - */ -describe('Suite01 failure in nested suite before hook', () => { - it('test 0', () => { - cy.log('test 1'); - }); - - describe('hooks test - child', () => { - describe('hooks test - sub child', () => { - before(' in suite', () => { - throw new Error('Failure in hook'); - }); - - it('test 1', () => { - cy.log('test 1'); - }); - - it('test 2', () => { - cy.log('test 2'); - }); - }); - }); -}); diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts new file mode 100644 index 00000000..da461300 --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts @@ -0,0 +1,238 @@ +import { TestData } from '@test-utils'; + +const rootSuite = 'Failed before hook in nested suite (complex)'; + +const data: TestData = { + /** + * When hook in child suite fails + * - result should have proper suite structure + * - attachments + * - steps + * - video in tear down + */ + name: rootSuite, + rootSuite, + fileName: __filename, + spec: `describe('${rootSuite}', () => { + it('test 0', () => { + cy.log('test 1'); + }); + + describe('hooks test - child', () => { + describe('hooks test - sub child', () => { + before('in sub suite', () => { + throw new Error('Failure in hook'); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); + }); + }); + `, + + expect: { + testsNames: [ + `${rootSuite} hooks test - child hooks test - sub child test 1`, + `${rootSuite} hooks test - child hooks test - sub child test 2`, + `${rootSuite} test 0`, + ], + + testStatuses: [ + { + testName: 'test 0', + status: 'passed', + statusDetails: { + message: undefined, + }, + }, + { + testName: 'test 1', + status: 'failed', + statusDetails: { + message: [ + 'Failure in hook', + '', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `hooks test - sub child`', + ], + }, + }, + { + testName: 'test 2', + status: 'unknown', + statusDetails: { + message: [ + 'Failure in hook', + '', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `hooks test - sub child`', + ], + }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should have no attachments', + testName: 'test 0', + attachments: [], + }, + { + expectMessage: 'todo check later', + testName: 'test 1', + attachments: [], + }, // todo check later + { expectMessage: '', testName: 'test 2', attachments: [] }, // todo check later + ], + + labels: { + filter: ['suite', 'parentSuite', 'subSuite'], + expected: [ + { + name: 'test 0', + labels: [ + { + name: 'parentSuite', + value: rootSuite, + }, + //{ name: 'suite', value: 'hooks test - child' }, + ], + }, + { + name: 'test 1', + labels: [ + { + name: 'parentSuite', + value: rootSuite, + }, + { name: 'suite', value: 'hooks test - child' }, + { name: 'subSuite', value: 'hooks test - sub child' }, + ], + }, + { + name: 'test 2', + labels: [ + { + name: 'parentSuite', + value: rootSuite, + }, + { name: 'suite', value: 'hooks test - child' }, + { name: 'subSuite', value: 'hooks test - sub child' }, + ], + }, + ], + }, + + parents: [ + { + testName: 'test 0', + containers: [ + { + name: rootSuite, + befores: [], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + ], + }, + { + testName: 'test 1', + containers: [ + { + name: rootSuite, + befores: [], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + { name: 'hooks test - child', befores: [], afters: [] }, + { name: 'hooks test - sub child', befores: [], afters: [] }, + ], + }, + { + testName: 'test 2', + containers: [ + { + name: rootSuite, + befores: [], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + { name: 'hooks test - child', befores: [], afters: [] }, + { name: 'hooks test - sub child', befores: [], afters: [] }, + ], + }, + ], + + events: [ + 'mocha: start', + 'mocha: suite: , ', + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 0', + 'mocha: hook end: "before all" hook', + `mocha: suite: ${rootSuite}, ${rootSuite}`, + 'mocha: test: test 0', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 0', + 'mocha: test end: test 0', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'cypress: test:after:run: test 0', + 'plugin test:ended', + `mocha: suite: hooks test - child, ${rootSuite} hooks test - child`, + `mocha: suite: hooks test - sub child, ${rootSuite} hooks test - child hooks test - sub child`, + 'mocha: hook: "before all" hook: in sub suite', + 'cypress: test:before:run: test 1', + `cypress:screenshot:test:${rootSuite} -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in sub suite (failed).png`, + 'mocha: fail: "before all" hook: in sub suite for "test 1"', + 'mocha: suite end: hooks test - sub child', + 'mocha: suite end: hooks test - child', + `mocha: suite end: ${rootSuite}`, + 'cypress: test:after:run: test 1', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'mocha: suite end: ', + 'mocha: end', + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts deleted file mode 100644 index b9de1edf..00000000 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * When hook in child suite fails - * - result should have proper suite structure - * - attachments - * - steps - * - video in tear down - */ -describe('Suite03 failure in nested suite before hook', () => { - describe('hooks test - child', () => { - before(' in suite', () => { - throw new Error('Failure in hook'); - }); - - it('test 1', () => { - cy.log('test 1'); - }); - - it('test 2', () => { - cy.log('test 2'); - }); - }); -}); diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts new file mode 100644 index 00000000..4c4dbea0 --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts @@ -0,0 +1,215 @@ +import { TestData } from '@test-utils'; + +const rootSuite = 'Failed before hook in nested suite (simple)'; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` + describe('${rootSuite}', () => { + describe('child suite', () => { + before('in sub suite', () => { + cy.log('hook pass'); + cy.wrap(null).then(() => { + throw new Error('Failure in hook'); + }); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); + }); + `, + + expect: { + testsNames: [ + `${rootSuite} child suite test 1`, + `${rootSuite} child suite test 2`, + ], + + testStatuses: [ + { + testName: 'test 1', + status: 'failed', + statusDetails: { + message: [ + 'Failure in hook', + '', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `child suite`', + ], + }, + }, + { + testName: 'test 2', + status: 'unknown', + statusDetails: { + message: [ + 'Failure in hook', + '', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `child suite`', + ], + }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should be no', + testName: 'test 1', + attachments: [], + }, + { expectMessage: 'should be no', testName: 'test 2', attachments: [] }, + ], + + testParents: [ + { + testName: 'test 1', + parents: [ + { name: 'child suite', parent: rootSuite }, + { name: rootSuite, parent: undefined }, + ], + }, + { + testName: 'test 2', + parents: [ + { name: 'child suite', parent: rootSuite }, + { name: rootSuite, parent: undefined }, + ], + }, + ], + + labels: { + filter: ['suite', 'parentSuite', 'subSuite'], + expected: [ + { + name: 'test 1', + labels: [ + { name: 'parentSuite', value: rootSuite }, + { name: 'suite', value: 'child suite' }, + ], + }, + { + name: 'test 2', + labels: [ + { name: 'parentSuite', value: rootSuite }, + { name: 'suite', value: 'child suite' }, + ], + }, + ], + }, + + parents: [ + { + testName: 'test 1', + containers: [ + { + name: rootSuite, + befores: [], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_2_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + { + name: 'child suite', + befores: [ + { name: '"before all" hook', attachments: [] }, + { name: '"before all" hook: in sub suite', attachments: [] }, + ], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_2_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + ], + }, + { + testName: 'test 2', + containers: [ + { + name: rootSuite, + befores: [], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_2_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + { + name: 'child suite', + befores: [ + { name: '"before all" hook', attachments: [] }, + { name: '"before all" hook: in sub suite', attachments: [] }, + ], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_2_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + ], + }, + ], + + events: [ + 'mocha: start', + 'mocha: suite: , ', + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 1', + 'mocha: hook end: "before all" hook', + `mocha: suite: ${rootSuite}, ${rootSuite}`, + `mocha: suite: child suite, ${rootSuite} child suite`, + 'mocha: hook: "before all" hook: in sub suite', + `cypress:screenshot:test:${rootSuite} -- child suite -- test 1 -- before all hook in sub suite (failed).png`, + 'mocha: fail: "before all" hook: in sub suite for "test 1"', + 'mocha: suite end: child suite', + `mocha: suite end: ${rootSuite}`, + 'cypress: test:after:run: test 1', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'mocha: suite end: ', + 'mocha: end', + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts deleted file mode 100644 index c9213f0e..00000000 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.cy.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * When hook in child suite passed - * - result should have proper suite structure - * - attachments - * - steps - */ -describe('Suite02 before hook passes in nested suite', () => { - it('test 0', () => { - cy.log('test 1'); - }); - - describe('hooks test - child', () => { - describe('hooks test - sub child', () => { - before('in suite', () => { - cy.log('before'); - }); - - it('test 1', () => { - cy.log('test 1'); - }); - - it('test 2', () => { - cy.log('test 2'); - }); - }); - }); -}); diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts new file mode 100644 index 00000000..8358da6f --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts @@ -0,0 +1,184 @@ +import { TestData } from '@test-utils'; + +const rootSuite = 'Passed before hook in nested suite'; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` + describe('${rootSuite}', () => { + describe('child suite', () => { + before('in sub suite', () => { + cy.log('hook pass'); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); + }); + `, + + expect: { + testsNames: [ + `${rootSuite} child suite test 1`, + `${rootSuite} child suite test 2`, + ], + + testStatuses: [ + { + testName: 'test 1', + status: 'passed', + statusDetails: { message: undefined }, + }, + { + testName: 'test 2', + status: 'passed', + statusDetails: { message: undefined }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should be no', + testName: 'test 1', + attachments: [], + }, + { expectMessage: 'should be no', testName: 'test 2', attachments: [] }, + ], + + testParents: [ + { + testName: 'test 1', + parents: [ + { name: 'child suite', parent: rootSuite }, + { name: rootSuite, parent: undefined }, + ], + }, + { + testName: 'test 2', + parents: [ + { name: 'child suite', parent: rootSuite }, + { name: rootSuite, parent: undefined }, + ], + }, + ], + + labels: { + filter: ['suite', 'parentSuite', 'subSuite'], + expected: [ + { + name: 'test 1', + labels: [ + { name: 'parentSuite', value: rootSuite }, + { name: 'suite', value: 'child suite' }, + ], + }, + { + name: 'test 2', + labels: [ + { name: 'parentSuite', value: rootSuite }, + { name: 'suite', value: 'child suite' }, + ], + }, + ], + }, + + parents: [ + { + testName: 'test 1', + containers: [ + { name: rootSuite, befores: [], afters: [] }, + { + name: 'child suite', + befores: [ + { name: '"before all" hook', attachments: [] }, + { name: '"before all" hook: in sub suite', attachments: [] }, + ], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_1_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + ], + }, + { + testName: 'test 2', + containers: [ + { name: rootSuite, befores: [], afters: [] }, + { + name: 'child suite', + befores: [ + { name: '"before all" hook', attachments: [] }, + { name: '"before all" hook: in sub suite', attachments: [] }, + ], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_1_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + ], + }, + ], + + events: [ + 'mocha: start', + 'mocha: suite: , ', + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 1', + 'mocha: hook end: "before all" hook', + `mocha: suite: ${rootSuite}, ${rootSuite}`, + `mocha: suite: child suite, ${rootSuite} child suite`, + 'mocha: hook: "before all" hook: in sub suite', + 'mocha: hook end: "before all" hook: in sub suite', + 'mocha: test: test 1', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 1', + 'mocha: test end: test 1', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'cypress: test:after:run: test 1', + 'plugin test:ended', + 'mocha: test: test 2', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'cypress: test:before:run: test 2', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 2', + 'mocha: test end: test 2', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'mocha: suite end: child suite', + `mocha: suite end: ${rootSuite}`, + 'cypress: test:after:run: test 2', + 'plugin test:ended', + 'mocha: suite end: ', + 'mocha: end', + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts index de6c47d1..0f079818 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts @@ -1,796 +1,16 @@ -import { - covergeAfterAllEvent, - createResTest2, - eventsForFile, - fixResult, - fullStepAttachment, - labelsForTest, - whenCoverage, - whenNoCoverage, -} from '../../../cy-helper/utils'; -import { AllureTest, parseAllure } from 'allure-js-parser'; -import { readFileSync } from 'fs'; -import { basename } from 'path'; +import { createResTest2, generateChecksTests, TestData } from '@test-utils'; describe('nested suites', () => { - const testsForRun = [ - { path: `${__dirname}/nested-suites-cy/nested-suite-before-fail-01.cy.ts` }, - { path: `${__dirname}/nested-suites-cy/nested-suite-before-pass-02.cy.ts` }, - { - path: `${__dirname}/nested-suites-cy/nested-suite-before-fail-simple-03.cy.ts`, - }, - ]; + const testsForOneCyRun: TestData[] = [ + 'nested-suites-cy/nested-suite-before-fail-01.ts', + 'nested-suites-cy/nested-suite-before-pass-02.ts', + 'nested-suites-cy/nested-suite-before-fail-simple-03.ts', + ].map(x => require(`${__dirname}/${x}`).default); const res = createResTest2( - testsForRun.map(x => readFileSync(x.path).toString()), - { allureAddVideoOnPass: 'true', DEBUG: 'true' }, + testsForOneCyRun.map(x => x.spec), + { allureAddVideoOnPass: 'true' /* DEBUG: 'true'*/ }, ); - describe(`Check results for ${basename(testsForRun[0].path)}`, () => { - let resFixed: AllureTest[]; - const specName = basename(res.specs[0]); - - beforeAll(() => { - const results = parseAllure(res.watch).filter( - t => t.fullName?.indexOf('Suite01') !== -1, - ); - resFixed = fixResult(results); - }); - - it('check tests names', async () => { - expect(resFixed.map(t => t.fullName).sort()).toEqual([ - 'Suite01 failure in nested suite before hook hooks test - child hooks test - sub child test 1', - 'Suite01 failure in nested suite before hook hooks test - child hooks test - sub child test 2', - 'Suite01 failure in nested suite before hook test 0', - ]); - }); - - it('should have correct events for spec', async () => { - const events = eventsForFile(res, specName); - - expect(events).toEqual([ - 'mocha: start', - 'mocha: suite: , ', - ...whenCoverage( - 'mocha: hook: "before all" hook', - 'cypress: test:before:run: test 0', - 'mocha: hook end: "before all" hook', - ), - 'mocha: suite: Suite01 failure in nested suite before hook, Suite01 failure in nested suite before hook', - 'mocha: test: test 0', - 'plugin test:started', - 'mocha: hook: "before each" hook', - 'mocha: hook end: "before each" hook', - 'mocha: pass: test 0', - 'mocha: test end: test 0', - 'mocha: hook: "after each" hook', - 'mocha: hook end: "after each" hook', - 'cypress: test:after:run: test 0', - 'plugin test:ended', - 'mocha: suite: hooks test - child, Suite01 failure in nested suite before hook hooks test - child', - 'mocha: suite: hooks test - sub child, Suite01 failure in nested suite before hook hooks test - child hooks test - sub child', - 'mocha: hook: "before all" hook: in suite', - ...whenNoCoverage('cypress: test:before:run: test 1'), - 'cypress: test:before:run: test 1', - 'cypress:screenshot:test:Suite01 failure in nested suite before hook -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in suite (failed).png', - 'mocha: fail: "before all" hook: in suite for "test 1"', - 'mocha: suite end: hooks test - sub child', - 'mocha: suite end: hooks test - child', - 'mocha: suite end: Suite01 failure in nested suite before hook', - - ...whenCoverage(...covergeAfterAllEvent), - 'cypress: test:after:run: test 1', - 'plugin test:ended', - 'plugin test:started', - 'plugin test:ended', - 'plugin test:started', - 'plugin test:ended', - 'mocha: suite end: ', - 'mocha: end', - ]); - }); - - it('check suite labels', async () => { - expect( - labelsForTest(resFixed, ['suite', 'parentSuite', 'subSuite']), - ).toEqual([ - { - name: 'test 0', - labels: [ - { - name: 'parentSuite', - value: 'Suite01 failure in nested suite before hook', - }, - //{ name: 'suite', value: 'hooks test - child' }, - ], - }, - { - name: 'test 1', - labels: [ - { - name: 'parentSuite', - value: 'Suite01 failure in nested suite before hook', - }, - ], - }, - { - name: 'test 2', - labels: [ - { - name: 'parentSuite', - value: 'Suite01 failure in nested suite before hook', - }, - ], - }, - ]); - }); - - it('check test with screenshot', async () => { - const obj = fullStepAttachment(resFixed, m => ({ - name: m.name, - attachments: m.attachments, - })); - - obj[0].steps = obj[0].steps.filter( - t => - t.name.indexOf('after each') === -1 && - t.name.indexOf('before each') === -1, - ); - - expect(obj).toEqual([ - { - attachments: [], - name: 'test 0', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_0_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite01 failure in nested suite before hook', - }, - ], - status: 'passed', - steps: [ - { - attachments: [], - name: 'log: test 1', - steps: [], - }, - ], - }, - { - attachments: [], - name: 'test 1', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_0_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite01 failure in nested suite before hook', - }, - ], - status: 'failed', - steps: [], - }, - { - attachments: [], - name: 'test 2', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_0_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite01 failure in nested suite before hook', - }, - ], - status: 'unknown', - steps: [], - }, - ]); - }); - }); - - describe(`Check results for ${basename(testsForRun[1].path)}`, () => { - let resFixed: AllureTest[]; - const specName = basename(res.specs[1]); - - beforeAll(() => { - const results = parseAllure(res.watch).filter( - t => t.fullName?.indexOf('Suite02') !== -1, - ); - resFixed = fixResult(results); - }); - - it('check tests names', async () => { - expect(resFixed.map(t => t.fullName).sort()).toEqual([ - 'Suite02 before hook passes in nested suite hooks test - child hooks test - sub child test 1', - 'Suite02 before hook passes in nested suite hooks test - child hooks test - sub child test 2', - 'Suite02 before hook passes in nested suite test 0', - ]); - }); - - it('should have correct events for spec', async () => { - const events = eventsForFile(res, specName); - - expect(events).toEqual([ - 'mocha: start', - 'mocha: suite: , ', - ...whenCoverage( - 'mocha: hook: "before all" hook', - 'cypress: test:before:run: test 0', - 'mocha: hook end: "before all" hook', - ), - 'mocha: suite: Suite02 before hook passes in nested suite, Suite02 before hook passes in nested suite', - 'mocha: test: test 0', - 'plugin test:started', - 'mocha: hook: "before each" hook', - 'mocha: hook end: "before each" hook', - 'mocha: pass: test 0', - 'mocha: test end: test 0', - 'mocha: hook: "after each" hook', - 'mocha: hook end: "after each" hook', - 'cypress: test:after:run: test 0', - 'plugin test:ended', - 'mocha: suite: hooks test - child, Suite02 before hook passes in nested suite hooks test - child', - 'mocha: suite: hooks test - sub child, Suite02 before hook passes in nested suite hooks test - child hooks test - sub child', - 'mocha: hook: "before all" hook: in suite', - ...whenNoCoverage('cypress: test:before:run: test 1'), - 'cypress: test:before:run: test 1', - 'mocha: hook end: "before all" hook: in suite', - 'mocha: test: test 1', - 'plugin test:started', - 'mocha: hook: "before each" hook', - 'mocha: hook end: "before each" hook', - 'mocha: pass: test 1', - 'mocha: test end: test 1', - 'mocha: hook: "after each" hook', - 'mocha: hook end: "after each" hook', - 'cypress: test:after:run: test 1', - 'plugin test:ended', - 'mocha: test: test 2', - 'plugin test:started', - 'mocha: hook: "before each" hook', - 'cypress: test:before:run: test 2', - 'mocha: hook end: "before each" hook', - 'mocha: pass: test 2', - 'mocha: test end: test 2', - 'mocha: hook: "after each" hook', - 'mocha: hook end: "after each" hook', - 'mocha: suite end: hooks test - sub child', - 'mocha: suite end: hooks test - child', - 'mocha: suite end: Suite02 before hook passes in nested suite', - - ...whenCoverage(...covergeAfterAllEvent), - - 'cypress: test:after:run: test 2', - 'plugin test:ended', - 'mocha: suite end: ', - 'mocha: end', - ]); - }); - - it('check suite labels', async () => { - expect( - labelsForTest(resFixed, ['suite', 'parentSuite', 'subSuite']), - ).toEqual([ - { - name: 'test 0', - labels: [ - { - name: 'parentSuite', - value: 'Suite02 before hook passes in nested suite', - }, - //{ name: 'suite', value: 'hooks test - child' }, - ], - }, - { - name: 'test 1', - labels: [ - { - name: 'parentSuite', - value: 'Suite02 before hook passes in nested suite', - }, - { name: 'suite', value: 'hooks test - child' }, - { name: 'subSuite', value: 'hooks test - sub child' }, - ], - }, - { - name: 'test 2', - labels: [ - { - name: 'parentSuite', - value: 'Suite02 before hook passes in nested suite', - }, - { - name: 'suite', - value: 'hooks test - child', - }, - { - name: 'subSuite', - value: 'hooks test - sub child', - }, - ], - }, - ]); - }); - - it('check test with screenshot', async () => { - const obj = fullStepAttachment(resFixed, m => ({ - name: m.name, - attachments: m.attachments, - })); - - obj[0].steps = obj[0].steps.filter( - t => - t.name.indexOf('after each') === -1 && - t.name.indexOf('before each') === -1, - ); - - expect(obj).toEqual([ - { - attachments: [], - name: 'test 0', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_1_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite02 before hook passes in nested suite', - }, - ], - status: 'passed', - steps: [ - { - attachments: [], - name: 'log: test 1', - steps: [], - }, - ], - }, - { - attachments: [], - name: 'test 1', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_1_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - { - attachments: [], - name: '"before all" hook: in suite', - status: 'passed', - steps: [ - { - attachments: [], - name: 'log: before', - steps: [], - }, - ], - }, - ], - suiteName: 'hooks test - sub child', - }, - { - afters: [], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'hooks test - child', - }, - { - afters: [ - { - attachments: [ - { - name: 'test_1_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite02 before hook passes in nested suite', - }, - ], - status: 'passed', - steps: [ - { - attachments: [], - name: '"before each" hook', - steps: [], - }, - { - attachments: [], - name: 'log: test 1', - steps: [], - }, - { - attachments: [], - name: '"after each" hook', - steps: [ - { - attachments: [], - name: 'log: 👉 Only found unit test code coverage. `[@cypress/code-coverage]`', - steps: [], - }, - ], - }, - ], - }, - { - attachments: [], - name: 'test 2', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_1_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - { - attachments: [], - name: '"before all" hook: in suite', - status: 'passed', - steps: [ - { - attachments: [], - name: 'log: before', - steps: [], - }, - ], - }, - ], - suiteName: 'hooks test - sub child', - }, - { - afters: [], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'hooks test - child', - }, - { - afters: [ - { - attachments: [ - { - name: 'test_1_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite02 before hook passes in nested suite', - }, - ], - status: 'passed', - steps: [ - { - attachments: [], - name: '"before each" hook', - steps: [], - }, - { - attachments: [], - name: 'log: test 2', - steps: [], - }, - { - attachments: [], - name: '"after each" hook', - steps: [ - { - attachments: [], - name: 'log: 👉 Only found unit test code coverage. `[@cypress/code-coverage]`', - steps: [], - }, - ], - }, - ], - }, - ]); - }); - }); - - describe('Check results for Suite03', () => { - let resFixed: AllureTest[]; - const specName = basename(res.specs[2]); - - beforeAll(() => { - const results = parseAllure(res.watch).filter( - t => t.fullName?.indexOf('Suite03') !== -1, - ); - resFixed = fixResult(results); - }); - - it('check tests names', async () => { - expect(resFixed.map(t => t.fullName).sort()).toEqual([ - 'Suite03 failure in nested suite before hook hooks test - child test 1', - 'Suite03 failure in nested suite before hook hooks test - child test 2', - ]); - }); - - it('should have correct events for spec', async () => { - const events = eventsForFile(res, specName); - - expect(events).toEqual([ - 'mocha: start', - 'mocha: suite: , ', - 'mocha: hook: "before all" hook', - 'cypress: test:before:run: test 1', - 'mocha: hook end: "before all" hook', - 'mocha: suite: Suite03 failure in nested suite before hook, Suite03 failure in nested suite before hook', - 'mocha: suite: hooks test - child, Suite03 failure in nested suite before hook hooks test - child', - 'mocha: hook: "before all" hook: in suite', - 'cypress:screenshot:test:Suite03 failure in nested suite before hook -- hooks test - child -- test 1 -- before all hook in suite (failed).png', - 'mocha: fail: "before all" hook: in suite for "test 1"', - 'mocha: suite end: hooks test - child', - 'mocha: suite end: Suite03 failure in nested suite before hook', - 'mocha: hook: "after all" hook: collectBackendCoverage', - 'mocha: hook end: "after all" hook: collectBackendCoverage', - 'mocha: hook: "after all" hook: mergeUnitTestCoverage', - 'mocha: hook end: "after all" hook: mergeUnitTestCoverage', - 'mocha: hook: "after all" hook: generateReport', - 'mocha: hook end: "after all" hook: generateReport', - 'cypress: test:after:run: test 1', - 'plugin test:ended', - 'plugin test:started', - 'plugin test:ended', - 'plugin test:started', - 'plugin test:ended', - 'mocha: suite end: ', - 'mocha: end', - ]); - }); - - it('check suite labels', async () => { - expect( - labelsForTest(resFixed, ['suite', 'parentSuite', 'subSuite']), - ).toEqual([ - { - labels: [ - { - name: 'parentSuite', - value: 'Suite03 failure in nested suite before hook', - }, - ], - name: 'test 1', - }, - { - labels: [ - { - name: 'parentSuite', - value: 'Suite03 failure in nested suite before hook', - }, - ], - name: 'test 2', - }, - ]); - }); - - it('check test with screenshot', async () => { - const obj = fullStepAttachment(resFixed, m => ({ - name: m.name, - attachments: m.attachments, - })); - - obj[0].steps = obj[0].steps.filter( - t => - t.name.indexOf('after each') === -1 && - t.name.indexOf('before each') === -1, - ); - - expect(obj).toEqual([ - { - attachments: [], - name: 'test 1', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_2_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite03 failure in nested suite before hook', - }, - ], - status: 'failed', - steps: [], - }, - { - attachments: [], - name: 'test 2', - parents: [ - { - afters: [ - { - attachments: [ - { - name: 'test_2_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', - }, - ], - name: 'video', - status: 'passed', - steps: [], - }, - ], - befores: [ - { - attachments: [], - name: '"before all" hook', - status: 'passed', - steps: [], - }, - ], - suiteName: 'Suite03 failure in nested suite before hook', - }, - ], - status: 'unknown', - steps: [], - }, - ]); - }); - }); + generateChecksTests(res, testsForOneCyRun); }); diff --git a/tests/tsconfig.json b/tests/tsconfig.json index aed55f3e..30e83576 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -6,9 +6,11 @@ "baseUrl": "../src", "paths": { "@src": ["./index.ts"], - "@src/*": ["./*"] + "@src/*": ["./*"], + + "@test-utils": ["../tests/cy-helper/utils.ts"], } }, - "include": ["./", "../jest.setup.ts"], + "include": ["./", "../tests", "../jest.setup.ts"], } From 62fbdc6f3aee890522f05a14ec9c69fe89010ae5 Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 20:13:09 +0200 Subject: [PATCH 05/14] fix defect --- src/plugins/allure-types.ts | 7 ++++-- src/setup/allure-mocha-reporter.ts | 34 ++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/plugins/allure-types.ts b/src/plugins/allure-types.ts index 41dc3964..bce8e212 100644 --- a/src/plugins/allure-types.ts +++ b/src/plugins/allure-types.ts @@ -1,6 +1,9 @@ -import type { StatusDetails } from 'allure-js-commons'; import type { ContentType } from '../common/types'; +export type StatusDetails = { + message?: string; + trace?: string; +}; export interface AutoScreen { screenshotId?: string; specName?: string; @@ -61,7 +64,7 @@ type AllureTask = { screenshotOne: { name: string | undefined; forStep?: boolean }; screenshotAttachment: AutoScreen; testResult: { - title: string; + title?: string; id: string; result: Status; details?: StatusDetails; diff --git a/src/setup/allure-mocha-reporter.ts b/src/setup/allure-mocha-reporter.ts index 6a9ef040..624444ca 100644 --- a/src/setup/allure-mocha-reporter.ts +++ b/src/setup/allure-mocha-reporter.ts @@ -8,11 +8,12 @@ import { Status, Category, LabelName, + LinkType, } from '../plugins/allure-types'; // todo import { registerScreenshotHandler } from './screenshots'; import StatusDetails = Cypress.StatusDetails; import { logClient } from './helper'; -import { tmsIssueUrl } from '../common'; +import { packageLog, tmsIssueUrl } from '../common'; import { EventEmitter } from 'events'; import AllureEvents = Cypress.AllureEvents; @@ -126,10 +127,22 @@ export const allureInterface = ( }, link: (url: string, name?: string, type?: 'issue' | 'tms') => fn({ task: 'link', arg: { url, name, type } }), - tms: (url: string, name?: string) => - fn({ task: 'link', arg: { url: tmsIssueUrl(env, url, 'tms'), name: name ?? url, type: 'tms' } }), - issue: (url: string, name?: string) => - fn({ task: 'link', arg: { url: tmsIssueUrl(env, url, 'issue'), name: name ?? url, type: 'issue' } }), + tms: (url: string, name?: string) => { + const type: LinkType = 'tms'; + const fullUrl = tmsIssueUrl(env, url, type); + const linkName = name ?? url; + + return fn({ task: 'link', arg: { url: fullUrl, name: linkName, type } }); + }, + + issue: (url: string, name?: string) => { + const type: LinkType = 'issue'; + const fullUrl = tmsIssueUrl(env, url, type); + const linkName = name ?? url; + + return fn({ task: 'link', arg: { url: fullUrl, name: linkName, type } }); + }, + label: (name: string, value: string) => fn({ task: 'label', arg: { name, value } }), suite: (name: string) => fn({ task: 'suite', arg: { name } }), parentSuite: (name: string) => fn({ task: 'parentSuite', arg: { name } }), @@ -176,7 +189,7 @@ const isHook = (test: Mocha.Test) => { return (test as any).type === 'hook'; }; -const createTests = (runner: Mocha.Runner, test: Mocha.Test) => { +const createTestsForFailedBeforeHook = (runner: Mocha.Runner, test: Mocha.Test) => { let index = 0; test.parent?.eachTest(ts => { ts.err = test.err; @@ -186,6 +199,12 @@ const createTests = (runner: Mocha.Runner, test: Mocha.Test) => { if (ts) { if (index === 1) { ts.state = 'failed'; + + if (ts.err) { + ts.err.message = + `${ts.err.message}\n\n` + + `Because this error occurred during a \`before all\` hook we are skipping the remaining tests in the current suite: \`${ts.parent?.title}\` (added by ${packageLog})`; + } } runner.emit(CUSTOM_EVENTS.TEST_BEGIN, ts); runner.emit(CUSTOM_EVENTS.TEST_FAIL, ts); @@ -393,7 +412,8 @@ export const registerMochaReporter = (ws: WebSocket) => { return; } - createTestsCallb = () => createTests(runner, test); + runner.emit(CUSTOM_EVENTS.TEST_END, test); + createTestsForFailedBeforeHook(runner, test); return; } From 6ce4839361ad497af815161250284599ae292b79 Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 20:32:48 +0200 Subject: [PATCH 06/14] fix --- .../nested-suite-before-fail-01.ts | 72 ++++++++++++++++--- .../nested-suite-before-fail-simple-03.ts | 33 +++++---- 2 files changed, 77 insertions(+), 28 deletions(-) diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts index da461300..3255060c 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts @@ -58,7 +58,7 @@ const data: TestData = { message: [ 'Failure in hook', '', - 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `hooks test - sub child`', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `hooks test - sub child` (added by [cypress-allure-adapter])', ], }, }, @@ -69,7 +69,7 @@ const data: TestData = { message: [ 'Failure in hook', '', - 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `hooks test - sub child`', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `hooks test - sub child` (added by [cypress-allure-adapter])', ], }, }, @@ -160,7 +160,34 @@ const data: TestData = { name: 'video', attachments: [ { - name: 'test_0_number.cy.ts.mp4', + name: 'test_0_number.cy.ts.mp4', // video check + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + { + name: 'hooks test - child', + befores: [{ name: '"before all" hook', attachments: [] }], + afters: [], + }, + { + name: 'hooks test - sub child', + befores: [ + { + name: '"before all" hook', + attachments: [], + }, + { name: '"before all" hook: in sub suite', attachments: [] }, + ], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', // video check source: 'source.mp4', type: 'video/mp4', }, @@ -168,8 +195,6 @@ const data: TestData = { }, ], }, - { name: 'hooks test - child', befores: [], afters: [] }, - { name: 'hooks test - sub child', befores: [], afters: [] }, ], }, { @@ -191,8 +216,33 @@ const data: TestData = { }, ], }, - { name: 'hooks test - child', befores: [], afters: [] }, - { name: 'hooks test - sub child', befores: [], afters: [] }, + { + name: 'hooks test - child', + befores: [{ name: '"before all" hook', attachments: [] }], + afters: [], + }, + { + name: 'hooks test - sub child', + befores: [ + { + name: '"before all" hook', + attachments: [], + }, + { name: '"before all" hook: in sub suite', attachments: [] }, + ], + afters: [ + { + name: 'video', + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', // video check + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, ], }, ], @@ -220,15 +270,15 @@ const data: TestData = { 'cypress: test:before:run: test 1', `cypress:screenshot:test:${rootSuite} -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in sub suite (failed).png`, 'mocha: fail: "before all" hook: in sub suite for "test 1"', - 'mocha: suite end: hooks test - sub child', - 'mocha: suite end: hooks test - child', - `mocha: suite end: ${rootSuite}`, - 'cypress: test:after:run: test 1', 'plugin test:ended', 'plugin test:started', 'plugin test:ended', 'plugin test:started', 'plugin test:ended', + 'mocha: suite end: hooks test - sub child', + 'mocha: suite end: hooks test - child', + `mocha: suite end: ${rootSuite}`, + 'cypress: test:after:run: test 1', 'mocha: suite end: ', 'mocha: end', ], diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts index 4c4dbea0..79469fa6 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts @@ -41,7 +41,7 @@ const data: TestData = { message: [ 'Failure in hook', '', - 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `child suite`', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `child suite` (added by [cypress-allure-adapter])', ], }, }, @@ -52,7 +52,7 @@ const data: TestData = { message: [ 'Failure in hook', '', - 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `child suite`', + 'Because this error occurred during a `before all` hook we are skipping the remaining tests in the current suite: `child suite` (added by [cypress-allure-adapter])', ], }, }, @@ -111,25 +111,24 @@ const data: TestData = { { name: rootSuite, befores: [], - afters: [ + afters: [], + }, + { + name: 'child suite', + befores: [ + { name: '"before all" hook', attachments: [] }, { - name: 'video', + name: '"before all" hook: in sub suite', attachments: [ { - name: 'test_2_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', + name: 'Failed before hook in nested suite (simple) -- child suite -- test 1 -- before all hook in sub suite (failed).png', + source: + '9b219b91-a644-47f0-8464-eb0342ded735-attachment.png', + type: 'image/png', }, ], }, ], - }, - { - name: 'child suite', - befores: [ - { name: '"before all" hook', attachments: [] }, - { name: '"before all" hook: in sub suite', attachments: [] }, - ], afters: [ { name: 'video', @@ -198,14 +197,14 @@ const data: TestData = { 'mocha: hook: "before all" hook: in sub suite', `cypress:screenshot:test:${rootSuite} -- child suite -- test 1 -- before all hook in sub suite (failed).png`, 'mocha: fail: "before all" hook: in sub suite for "test 1"', - 'mocha: suite end: child suite', - `mocha: suite end: ${rootSuite}`, - 'cypress: test:after:run: test 1', 'plugin test:ended', 'plugin test:started', 'plugin test:ended', 'plugin test:started', 'plugin test:ended', + 'mocha: suite end: child suite', + `mocha: suite end: ${rootSuite}`, + 'cypress: test:after:run: test 1', 'mocha: suite end: ', 'mocha: end', ], From 4c993c7e2cc8dc7e803d9b38afea704ca9517d75 Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 21:08:50 +0200 Subject: [PATCH 07/14] trigger --- tests/test-folder/mocha-events/hooks/nested-suites.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts index 0f079818..bfb4ea10 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts @@ -1,6 +1,7 @@ import { createResTest2, generateChecksTests, TestData } from '@test-utils'; describe('nested suites', () => { + // test const testsForOneCyRun: TestData[] = [ 'nested-suites-cy/nested-suite-before-fail-01.ts', 'nested-suites-cy/nested-suite-before-pass-02.ts', From 60d4081da75bcf4ba04cfd17c59ea33fe76e8daf Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 21:29:16 +0200 Subject: [PATCH 08/14] fix tests --- tests/cy-helper/utils.ts | 38 +++++++++++++------ .../nested-suite-before-fail-01.ts | 25 ++++++++++-- .../nested-suite-before-fail-simple-03.ts | 28 +++++++------- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/tests/cy-helper/utils.ts b/tests/cy-helper/utils.ts index 209b57db..8779ed40 100644 --- a/tests/cy-helper/utils.ts +++ b/tests/cy-helper/utils.ts @@ -47,21 +47,22 @@ export const fixResult = (results: AllureTest[]): AllureTest[] => { })); }; - return results.map(r => { - return { - ...r, - historyId: 'no', - uuid: 'no', - start: date, - stop: date + 10, - parent: { - ...r.parent, + const fixParent = (parent: Parent | undefined) => { + if (parent) { + return { + ...parent, + parent: fixParent(parent.parent), uuid: 'no', - befores: r.parent?.befores?.map(b => ({ + befores: parent?.befores?.map(b => ({ ...b, steps: replaceSteps(b.steps), start: date, stop: date + 10, + attachments: b.attachments.map(t => ({ + ...t, + name: t.name.replace(/\d{5,}/g, 'number'), + source: `source${path.extname(t.source)}`, + })), statusDetails: b.statusDetails?.message ? { message: b.statusDetails.message, @@ -69,7 +70,7 @@ export const fixResult = (results: AllureTest[]): AllureTest[] => { } : undefined, })), - afters: r.parent?.afters?.map(b => ({ + afters: parent?.afters?.map(b => ({ ...b, steps: replaceSteps(b.steps), start: date, @@ -86,7 +87,20 @@ export const fixResult = (results: AllureTest[]): AllureTest[] => { } : undefined, })), - }, + }; + } + + return undefined; + }; + + return results.map(r => { + return { + ...r, + historyId: 'no', + uuid: 'no', + start: date, + stop: date + 10, + parent: fixParent(r.parent), labels: r.labels.map(l => ({ name: l.name, value: l.value.replace(/\d{5,}/g, 'number'), diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts index 3255060c..e0928b28 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts @@ -180,7 +180,16 @@ const data: TestData = { name: '"before all" hook', attachments: [], }, - { name: '"before all" hook: in sub suite', attachments: [] }, + { + name: '"before all" hook: in sub suite', + attachments: [ + { + name: `${rootSuite} -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in sub suite (failed).png`, + source: 'source.png', + type: 'image/png', + }, + ], + }, ], afters: [ { @@ -208,7 +217,7 @@ const data: TestData = { name: 'video', attachments: [ { - name: 'test_0_number.cy.ts.mp4', + name: 'test_0_number.cy.ts.mp4', // change source: 'source.mp4', type: 'video/mp4', }, @@ -228,7 +237,16 @@ const data: TestData = { name: '"before all" hook', attachments: [], }, - { name: '"before all" hook: in sub suite', attachments: [] }, + { + name: '"before all" hook: in sub suite', + attachments: [ + { + name: `${rootSuite} -- hooks test - child -- hooks test - sub child -- test 1 -- before all hook in sub suite (failed).png`, + source: 'source.png', + type: 'image/png', + }, + ], + }, ], afters: [ { @@ -279,6 +297,7 @@ const data: TestData = { 'mocha: suite end: hooks test - child', `mocha: suite end: ${rootSuite}`, 'cypress: test:after:run: test 1', + 'plugin test:ended', // does nothing 'mocha: suite end: ', 'mocha: end', ], diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts index 79469fa6..7788bcf1 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts @@ -121,9 +121,8 @@ const data: TestData = { name: '"before all" hook: in sub suite', attachments: [ { - name: 'Failed before hook in nested suite (simple) -- child suite -- test 1 -- before all hook in sub suite (failed).png', - source: - '9b219b91-a644-47f0-8464-eb0342ded735-attachment.png', + name: `${rootSuite} -- child suite -- test 1 -- before all hook in sub suite (failed).png`, + source: 'source.png', type: 'image/png', }, ], @@ -150,25 +149,23 @@ const data: TestData = { { name: rootSuite, befores: [], - afters: [ + afters: [], + }, + { + name: 'child suite', + befores: [ + { name: '"before all" hook', attachments: [] }, { - name: 'video', + name: '"before all" hook: in sub suite', attachments: [ { - name: 'test_2_number.cy.ts.mp4', - source: 'source.mp4', - type: 'video/mp4', + name: `${rootSuite} -- child suite -- test 1 -- before all hook in sub suite (failed).png`, + source: 'source.png', + type: 'image/png', }, ], }, ], - }, - { - name: 'child suite', - befores: [ - { name: '"before all" hook', attachments: [] }, - { name: '"before all" hook: in sub suite', attachments: [] }, - ], afters: [ { name: 'video', @@ -205,6 +202,7 @@ const data: TestData = { 'mocha: suite end: child suite', `mocha: suite end: ${rootSuite}`, 'cypress: test:after:run: test 1', + 'plugin test:ended', // does nothing 'mocha: suite end: ', 'mocha: end', ], From 7b29ef62ac6134fe918cda784d53ba840c44a2f2 Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 22:16:44 +0200 Subject: [PATCH 09/14] fix tests --- .../fail-one-test-before-all-fail.test.ts | 8 +++---- ...es-nested-with-global-hooks-parent.test.ts | 21 +++++++++++-------- .../suites-nested-with-hooks-parent.test.ts | 15 ++++++------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/test-folder/mocha-events/failures/before-all-hook/fail-one-test-before-all-fail.test.ts b/tests/test-folder/mocha-events/failures/before-all-hook/fail-one-test-before-all-fail.test.ts index 06f1ca42..43d6bcec 100644 --- a/tests/test-folder/mocha-events/failures/before-all-hook/fail-one-test-before-all-fail.test.ts +++ b/tests/test-folder/mocha-events/failures/before-all-hook/fail-one-test-before-all-fail.test.ts @@ -4,7 +4,7 @@ import { readWithRetry, whenCoverage, whenNoCoverage, -} from '../../../../cy-helper/utils'; +} from '@test-utils'; describe('before all hook from suite should be have correct events', () => { const res = createResTest2([ @@ -49,13 +49,13 @@ describe('hello suite', () => { ...whenNoCoverage('cypress: test:before:run: hello test'), 'cypress:screenshot:test:hello suite -- hello test -- before all hook (failed).png', 'mocha: fail: "before all" hook for "hello test"', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', 'mocha: suite end: hello suite', ...whenCoverage(...covergeAfterAllEvent), 'cypress: test:after:run: hello test', 'plugin test:ended', // doesn't do anything - - 'plugin test:started', - 'plugin test:ended', 'mocha: suite end: ', 'mocha: end', ]); diff --git a/tests/test-folder/mocha-events/suites/suites-nested-with-global-hooks-parent.test.ts b/tests/test-folder/mocha-events/suites/suites-nested-with-global-hooks-parent.test.ts index 313f344f..30832331 100644 --- a/tests/test-folder/mocha-events/suites/suites-nested-with-global-hooks-parent.test.ts +++ b/tests/test-folder/mocha-events/suites/suites-nested-with-global-hooks-parent.test.ts @@ -1,10 +1,7 @@ -import { - createResTest2, - fixResult, - readWithRetry, -} from '../../../cy-helper/utils'; +import { createResTest2, fixResult, readWithRetry } from '@test-utils'; import { getParentsArray, parseAllure } from 'allure-js-parser'; import { extname } from '../../../../src/common'; +import { AllureHook } from 'allure-js-parser/types'; // issue https://github.com/mmisty/cypress-allure-adapter/issues/95 describe('several nested suites with global hook - hook should be added to all children', () => { @@ -41,9 +38,10 @@ describe('hello suite', () => { describe('check results', () => { let resFixed; + let results; beforeAll(() => { - const results = parseAllure(res.watch); + results = parseAllure(res.watch); resFixed = fixResult(results); }); @@ -60,14 +58,14 @@ describe('hello suite', () => { it('suites parents', () => { expect( - resFixed + results .sort((a, b) => (a.name < b.name ? -1 : 1)) .map(t => ({ name: t.name, status: t.status, parents: getParentsArray(t).map(t => ({ name: t.name, - befores: t.befores + befores: (t.befores as AllureHook[]) ?.filter(x => (x as any).name !== '"before all" hook') .map(x => ({ name: (x as any).name, @@ -77,7 +75,7 @@ describe('hello suite', () => { ...t, source: `source${extname(t.source)}`, sourceContentMoreThanZero: - readWithRetry(`${res.watch}/${t.source}`).toString() + readWithRetry(`${res.watch}/${t.source}`)?.toString() .length > 0, })), })), @@ -92,6 +90,7 @@ describe('hello suite', () => { { name: '"before all" hook: glob hook', status: 'passed', + statusDetails: {}, attachments: [], }, { @@ -105,11 +104,13 @@ describe('hello suite', () => { ], name: '"before all" hook: parent hook', status: 'passed', + statusDetails: {}, }, { attachments: [], name: '"before all" hook: child hook', status: 'passed', + statusDetails: {}, }, ], name: 'sub sub suite', @@ -180,6 +181,7 @@ describe('hello suite', () => { attachments: [], name: '"before all" hook: glob hook', status: 'passed', + statusDetails: {}, }, { attachments: [ @@ -192,6 +194,7 @@ describe('hello suite', () => { ], name: '"before all" hook: parent hook', status: 'passed', + statusDetails: {}, }, ], name: 'hello suite', diff --git a/tests/test-folder/mocha-events/suites/suites-nested-with-hooks-parent.test.ts b/tests/test-folder/mocha-events/suites/suites-nested-with-hooks-parent.test.ts index 9ca08cbf..28d1233b 100644 --- a/tests/test-folder/mocha-events/suites/suites-nested-with-hooks-parent.test.ts +++ b/tests/test-folder/mocha-events/suites/suites-nested-with-hooks-parent.test.ts @@ -1,8 +1,4 @@ -import { - createResTest2, - fixResult, - readWithRetry, -} from '../../../cy-helper/utils'; +import { createResTest2, fixResult, readWithRetry } from '@test-utils'; import { getParentsArray, parseAllure } from 'allure-js-parser'; import { extname } from '../../../../src/common'; import { AllureHook, Parent } from 'allure-js-parser/types'; @@ -44,9 +40,10 @@ describe('hello suite', () => { describe('check results', () => { let resFixed; + let results; beforeAll(() => { - const results = parseAllure(res.watch); + results = parseAllure(res.watch); resFixed = fixResult(results); }); @@ -62,7 +59,7 @@ describe('hello suite', () => { it('suites parents', () => { expect( - resFixed.map(t => ({ + results.map(t => ({ name: t.name, status: t.status, parents: getParentsArray(t).map((y: Parent) => ({ @@ -76,8 +73,8 @@ describe('hello suite', () => { ...z, source: `source${extname(z.source)}`, sourceContentMoreThanZero: - readWithRetry(`${res.watch}/${z.source}`).toString() - .length > 0, + readWithRetry(`${res.watch}/${z.source}`)?.toString() + ?.length > 0, })), })), afters: (y.afters as AllureHook[]) From fa4966e89549f90ac8db4a11ace9e2a8f2ca3c3d Mon Sep 17 00:00:00 2001 From: mmisty Date: Fri, 28 Jun 2024 22:34:47 +0200 Subject: [PATCH 10/14] added test --- tests/cy-helper/utils.ts | 145 +++++--- .../nested-suite-after-fail-simple-04.ts | 310 ++++++++++++++++++ .../nested-suite-before-fail-01.ts | 13 + .../nested-suite-before-fail-simple-03.ts | 65 +++- .../nested-suite-before-pass-02.ts | 51 +++ .../mocha-events/hooks/nested-suites.test.ts | 1 + 6 files changed, 545 insertions(+), 40 deletions(-) create mode 100644 tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-after-fail-simple-04.ts diff --git a/tests/cy-helper/utils.ts b/tests/cy-helper/utils.ts index 8779ed40..0425e85c 100644 --- a/tests/cy-helper/utils.ts +++ b/tests/cy-helper/utils.ts @@ -5,7 +5,7 @@ import { AllureTest, getParentsArray, parseAllure } from 'allure-js-parser'; import { StepResult } from 'allure-js-commons'; import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'; import { parseBoolean } from 'cypress-redirect-browser-log/utils/functions'; -import { AllureHook, Parent } from 'allure-js-parser/types'; +import { AllureHook, AllureStep, Parent } from 'allure-js-parser/types'; jest.setTimeout(120000); @@ -13,16 +13,21 @@ jest.setTimeout(120000); export const mapSteps = ( steps: StepResult[], map?: (m: StepResult) => T, + filter?: (m: StepResult) => boolean, ): (T & any)[] => { if (steps?.length === 0) { return []; } - return steps.map(s => { - const obj = map ? map(s) : { name: s.name }; + return steps + .filter(s => { + return filter ? filter(s) : true; + }) + .map(s => { + const obj = map ? map(s) : { name: s.name }; - return { ...obj, steps: mapSteps(s.steps, map) }; - }); + return { ...obj, steps: mapSteps(s.steps, map, filter) }; + }); }; // eslint-disable-next-line jest/no-export @@ -205,6 +210,7 @@ export const labelsForTest = (res: AllureTest[], filterLabels?: string[]) => { export const fullStepAttachment = ( res: AllureTest[], mapStep?: (m: StepResult) => any, + options?: { noAddParents?: boolean }, ) => { const parents = res .map(x => ({ @@ -234,38 +240,63 @@ export const fullStepAttachment = ( skipItems.every(y => x.name?.toLowerCase().indexOf(y) === -1), ), })) + .filter(x => + skipItems.every(y => x.name?.toLowerCase().indexOf(y) === -1), + ) .sort((z1, z2) => (z1.name && z2.name && z1.name < z2.name ? -1 : 1)) ?? [] ); }; - const full = parents.map(t => ({ - name: t.name, - status: t.status, - attachments: t.attachments.sort((z1, z2) => - z1.name && z2.name && z1.name < z2.name ? -1 : 1, - ), - steps: mapSteps(t.steps, mapStep).filter(x => - skipItems.every(y => x.name?.toLowerCase().indexOf(y) === -1), - ), - parents: t.parents?.map(x => ({ - suiteName: x.name, - befores: mapItem(x.befores) - .filter(z => - skipItems.every(y => z.name.toLowerCase().indexOf(y) === -1), - ) - .sort((z1, z2) => (z1.name && z2.name && z1.name < z2.name ? -1 : 1)), - afters: mapItem(x.afters) - .filter(z => - skipItems.every(y => z.name.toLowerCase().indexOf(y) === -1), - ) - .sort((z1, z2) => (z1.name && z2.name && z1.name < z2.name ? -1 : 1)), - })), - })); + const full = parents + .map(t => ({ + name: t.name, + status: t.status, + attachments: t.attachments.sort((z1, z2) => + z1.name && z2.name && z1.name < z2.name ? -1 : 1, + ), + steps: mapSteps(t.steps, mapStep).filter(x => + skipItems.every(y => x.name?.toLowerCase().indexOf(y) === -1), + ), + ...(!options?.noAddParents + ? { + parents: t.parents?.map(x => ({ + suiteName: x.name, + befores: mapItem(x.befores) + .filter(z => + skipItems.every(y => z.name.toLowerCase().indexOf(y) === -1), + ) + .sort((z1, z2) => + z1.name && z2.name && z1.name < z2.name ? -1 : 1, + ), + afters: mapItem(x.afters) + .filter(z => + skipItems.every(y => z.name.toLowerCase().indexOf(y) === -1), + ) + .sort((z1, z2) => + z1.name && z2.name && z1.name < z2.name ? -1 : 1, + ), + })), + } + : {}), + })) + .filter(x => skipItems.every(y => x.name?.toLowerCase().indexOf(y) === -1)); return full; }; +// eslint-disable-next-line jest/no-export +export const fullStepMap = ( + res: AllureTest, + mapStep?: (m: StepResult) => any, +) => { + const skipItems = ['generatereport', 'coverage']; + + return mapSteps(res.steps as StepResult[], mapStep, z => + skipItems.every(y => z.name?.toLowerCase().indexOf(y) === -1), + ); +}; + // eslint-disable-next-line jest/no-export export const checkCyResults = ( res: @@ -610,22 +641,26 @@ export type TestData = { parents: { name: string; parent: string | undefined }[]; }[]; - steps?: { - filter: string[]; + testSteps?: { + testName: string; + mapStep?: (m: StepResult) => any; expected: any[]; - }; + }[]; parents?: { testName: string; containers: { name: string; + stepMap?: (x: StepResult) => any; befores?: { name?: string; attachments?: any[]; + steps?: any[]; }[]; afters?: { name?: string; attachments?: any[]; + steps?: any[]; }[]; }[]; }[]; @@ -747,6 +782,21 @@ export const generateChecksTests = (res: Result, testsForRun: TestData[]) => { }); } + if (testData.expect.testSteps) { + testData.expect.testSteps.forEach(testItem => { + it(`steps for test ${testItem.testName}`, () => { + const test = resFixed.find(x => testItem.testName === x.name); + + const obj = fullStepMap(test!, m => ({ + name: m.name, + ...(testItem.mapStep?.(m) ?? {}), + })); + + wrapError(() => expect(obj).toEqual(testItem.expected)); + }); + }); + } + if (testData.expect.parents) { testData.expect.parents.forEach(testData => { describe(`parents for ${testData.testName}`, () => { @@ -759,13 +809,6 @@ export const generateChecksTests = (res: Result, testsForRun: TestData[]) => { parents = getParentsArray(test); }); - // it('check parent names', () => { - // - // wrapError(() =>expect(parents.map(x => x.name)).toEqual( - // testData.containers.map(x => x.name), - // )); - // }); - describe('before and after hooks', () => { testData.containers.forEach(container => { if (container.befores) { @@ -805,6 +848,19 @@ export const generateChecksTests = (res: Result, testsForRun: TestData[]) => { ), ); } + + if (container.befores?.some(t => t.steps)) { + const beforesSteps = actualBefores?.map(x => + mapSteps(x.steps, container.stepMap), + ); + + wrapError(() => + // eslint-disable-next-line jest/no-conditional-expect + expect(beforesSteps).toEqual( + container.befores?.map(x => x.steps), + ), + ); + } }); } @@ -836,6 +892,19 @@ export const generateChecksTests = (res: Result, testsForRun: TestData[]) => { ), ); } + + if (container.afters?.some(t => t.steps)) { + const aftersSteps = actualAfters?.map(x => + mapSteps(x.steps, container.stepMap), + ); + + wrapError(() => + // eslint-disable-next-line jest/no-conditional-expect + expect(aftersSteps).toEqual( + container.afters?.map(x => x.steps), + ), + ); + } }); } }); diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-after-fail-simple-04.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-after-fail-simple-04.ts new file mode 100644 index 00000000..2f7358f2 --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-after-fail-simple-04.ts @@ -0,0 +1,310 @@ +import { TestData } from '@test-utils'; + +const rootSuite = 'Failed after hook in nested suite (simple)'; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` + describe('${rootSuite}', () => { + describe('child suite', () => { + after('in sub suite', () => { + cy.log('hook pass'); + cy.wrap(null).then(() => { + throw new Error('Failure in hook'); + }); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); + }); + `, + + expect: { + testsNames: [ + `${rootSuite} child suite test 1`, + `${rootSuite} child suite test 2`, + ], + + testStatuses: [ + { + testName: 'test 1', + status: 'passed', + statusDetails: { message: undefined }, + }, + { + testName: 'test 2', + status: 'failed', + statusDetails: { + message: [ + 'Failure in hook', + '', + 'Because this error occurred during a `after all` hook we are skipping the remaining tests in the current suite: `child suite`', + ], + }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should be no', + testName: 'test 1', + attachments: [], + }, + { + expectMessage: 'should be screenshot of failure', + testName: 'test 2', + attachments: [ + { + name: `${rootSuite} -- child suite -- test 2 -- after all hook in sub suite (failed).png`, + source: 'source.png', + type: 'image/png', + }, + ], + }, + ], + + testSteps: [ + { + testName: 'test 1', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [ + { + name: '"before each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: 'log: test 1', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: '"after each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + ], + }, + { + testName: 'test 2', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [ + { + name: '"before each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: 'log: test 2', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: '"after each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + ], + }, + ], + + testParents: [ + { + testName: 'test 1', + parents: [ + { name: 'child suite', parent: rootSuite }, + { name: rootSuite, parent: undefined }, + ], + }, + { + testName: 'test 2', + parents: [ + { name: 'child suite', parent: rootSuite }, + { name: rootSuite, parent: undefined }, + ], + }, + ], + + labels: { + filter: ['suite', 'parentSuite', 'subSuite'], + expected: [ + { + name: 'test 1', + labels: [ + { name: 'parentSuite', value: rootSuite }, + { name: 'suite', value: 'child suite' }, + ], + }, + { + name: 'test 2', + labels: [ + { name: 'parentSuite', value: rootSuite }, + { name: 'suite', value: 'child suite' }, + ], + }, + ], + }, + + parents: [ + { + testName: 'test 1', + containers: [ + { + name: rootSuite, + befores: [], + afters: [], + }, + { + name: 'child suite', + stepMap: x => ({ + name: x.name, + status: x.status, + attachments: x.attachments, + }), + befores: [ + { name: '"before all" hook', attachments: [], steps: [] }, + ], + afters: [ + { + name: '"after all" hook: in sub suite', + attachments: [], + steps: [ + { + name: 'log: hook pass', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: 'wrap', + status: 'passed', + steps: [], + attachments: [], + }, + ], + }, + { + name: 'video', + attachments: [ + { + name: 'test_3_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + steps: [], + }, + ], + }, + ], + }, + { + testName: 'test 2', + containers: [ + { + name: rootSuite, + befores: [], + afters: [], + }, + { + name: 'child suite', + stepMap: x => ({ + name: x.name, + status: x.status, + attachments: x.attachments, + }), + befores: [ + { name: '"before all" hook', attachments: [], steps: [] }, + ], + afters: [ + { + name: '"after all" hook: in sub suite', + attachments: [], + steps: [ + { + name: 'log: hook pass', + steps: [], + status: 'passed', + attachments: [], + }, + { + name: 'wrap', + status: 'passed', + steps: [], + attachments: [], + }, + ], + }, + { + name: 'video', + attachments: [ + { + name: 'test_3_number.cy.ts.mp4', + source: 'source.mp4', + type: 'video/mp4', + }, + ], + steps: [], + }, + ], + }, + ], + }, + ], + + events: [ + 'mocha: start', + 'mocha: suite: , ', + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 1', + 'mocha: hook end: "before all" hook', + `mocha: suite: ${rootSuite}, ${rootSuite}`, + `mocha: suite: child suite, ${rootSuite} child suite`, + 'mocha: test: test 1', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 1', + 'mocha: test end: test 1', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'cypress: test:after:run: test 1', + 'plugin test:ended', + + 'mocha: test: test 2', + 'plugin test:started', + 'mocha: hook: "before each" hook', + 'cypress: test:before:run: test 2', + 'mocha: hook end: "before each" hook', + 'mocha: pass: test 2', + 'mocha: test end: test 2', + 'mocha: hook: "after each" hook', + 'mocha: hook end: "after each" hook', + 'mocha: hook: "after all" hook: in sub suite', + `cypress:screenshot:test:${rootSuite} -- child suite -- test 2 -- after all hook in sub suite (failed).png`, + 'mocha: fail: "after all" hook: in sub suite for "test 2"', + 'mocha: suite end: child suite', + `mocha: suite end: ${rootSuite}`, + 'cypress: test:after:run: test 2', + 'plugin test:ended', // does nothing + 'mocha: suite end: ', + 'mocha: end', + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts index e0928b28..c3057cd4 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-01.ts @@ -127,6 +127,19 @@ const data: TestData = { ], }, + testSteps: [ + { + testName: 'test 1', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [], + }, + { + testName: 'test 2', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [], + }, + ], + parents: [ { testName: 'test 0', diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts index 7788bcf1..62f936b5 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-fail-simple-03.ts @@ -104,6 +104,19 @@ const data: TestData = { ], }, + testSteps: [ + { + testName: 'test 1', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [], + }, + { + testName: 'test 2', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [], + }, + ], + parents: [ { testName: 'test 1', @@ -115,8 +128,17 @@ const data: TestData = { }, { name: 'child suite', + stepMap: x => ({ + name: x.name, + status: x.status, + attachments: x.attachments, + }), befores: [ - { name: '"before all" hook', attachments: [] }, + { + name: '"before all" hook', + attachments: [], + steps: [], + }, { name: '"before all" hook: in sub suite', attachments: [ @@ -126,11 +148,26 @@ const data: TestData = { type: 'image/png', }, ], + steps: [ + { + attachments: [], + name: 'log: hook pass', + status: 'passed', + steps: [], + }, + { + attachments: [], + name: 'wrap', + status: 'passed', + steps: [], + }, + ], }, ], afters: [ { name: 'video', + steps: [], attachments: [ { name: 'test_2_number.cy.ts.mp4', @@ -153,10 +190,33 @@ const data: TestData = { }, { name: 'child suite', + stepMap: x => ({ + name: x.name, + status: x.status, + attachments: x.attachments, + }), befores: [ - { name: '"before all" hook', attachments: [] }, + { + name: '"before all" hook', + attachments: [], + steps: [], + }, { name: '"before all" hook: in sub suite', + steps: [ + { + attachments: [], + name: 'log: hook pass', + status: 'passed', + steps: [], + }, + { + attachments: [], + name: 'wrap', + status: 'passed', + steps: [], + }, + ], attachments: [ { name: `${rootSuite} -- child suite -- test 1 -- before all hook in sub suite (failed).png`, @@ -169,6 +229,7 @@ const data: TestData = { afters: [ { name: 'video', + steps: [], attachments: [ { name: 'test_2_number.cy.ts.mp4', diff --git a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts index 8358da6f..f2d24a52 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suite-before-pass-02.ts @@ -43,6 +43,57 @@ const data: TestData = { }, ], + testSteps: [ + { + testName: 'test 1', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [ + { + name: '"before each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: 'log: test 1', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: '"after each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + ], + }, + { + testName: 'test 2', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [ + { + name: '"before each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: 'log: test 2', + status: 'passed', + steps: [], + attachments: [], + }, + { + name: '"after each" hook', + status: 'passed', + steps: [], + attachments: [], + }, + ], + }, + ], + testAttachments: [ { expectMessage: 'should be no', diff --git a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts index bfb4ea10..1761d432 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites.test.ts @@ -6,6 +6,7 @@ describe('nested suites', () => { 'nested-suites-cy/nested-suite-before-fail-01.ts', 'nested-suites-cy/nested-suite-before-pass-02.ts', 'nested-suites-cy/nested-suite-before-fail-simple-03.ts', + 'nested-suites-cy/nested-suite-after-fail-simple-04.ts', ].map(x => require(`${__dirname}/${x}`).default); const res = createResTest2( From aa44c410bce7f083263cfd00ebf30dbc9065c6fd Mon Sep 17 00:00:00 2001 From: mmisty Date: Sat, 29 Jun 2024 00:20:23 +0200 Subject: [PATCH 11/14] added test - issue 149 fixed --- .../nested-suites.test.ts | 8 +- .../suites/before-and-after-failure.test.ts | 230 ++++++++++++++++++ .../mocha-events/hooks/suites/suites.test.ts | 15 ++ 3 files changed, 249 insertions(+), 4 deletions(-) rename tests/test-folder/mocha-events/hooks/{ => nested-suites-cy}/nested-suites.test.ts (63%) create mode 100644 tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts create mode 100644 tests/test-folder/mocha-events/hooks/suites/suites.test.ts diff --git a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suites.test.ts similarity index 63% rename from tests/test-folder/mocha-events/hooks/nested-suites.test.ts rename to tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suites.test.ts index 1761d432..3f384c9a 100644 --- a/tests/test-folder/mocha-events/hooks/nested-suites.test.ts +++ b/tests/test-folder/mocha-events/hooks/nested-suites-cy/nested-suites.test.ts @@ -3,10 +3,10 @@ import { createResTest2, generateChecksTests, TestData } from '@test-utils'; describe('nested suites', () => { // test const testsForOneCyRun: TestData[] = [ - 'nested-suites-cy/nested-suite-before-fail-01.ts', - 'nested-suites-cy/nested-suite-before-pass-02.ts', - 'nested-suites-cy/nested-suite-before-fail-simple-03.ts', - 'nested-suites-cy/nested-suite-after-fail-simple-04.ts', + 'nested-suite-before-fail-01.ts', + 'nested-suite-before-pass-02.ts', + 'nested-suite-before-fail-simple-03.ts', + 'nested-suite-after-fail-simple-04.ts', ].map(x => require(`${__dirname}/${x}`).default); const res = createResTest2( diff --git a/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts b/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts new file mode 100644 index 00000000..4e50f9e0 --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts @@ -0,0 +1,230 @@ +import { TestData } from '@test-utils'; + +const rootSuite = 'Failed before and after hook'; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: `describe('${rootSuite}', () => { + before('in suite', () => { + throw new Error('Failure in before hook'); + }); + + after('after in suite', () => { + throw new Error('Failure in after hook'); + }); + + it('test 1', () => { + cy.log('test 1'); + }); + + it('test 2', () => { + cy.log('test 2'); + }); + }); + `, + + expect: { + testsNames: [`${rootSuite} test 1`, `${rootSuite} test 2`], + + testStatuses: [ + { + testName: 'test 1', + status: 'failed', + statusDetails: { + message: [ + 'Failure in before hook', + '', + `Because this error occurred during a \`before all\` hook we are skipping the remaining tests in the current suite: \`${rootSuite}\` (added by [cypress-allure-adapter])`, + ], + }, + }, + { + testName: 'test 2', + status: 'unknown', + statusDetails: { + message: [ + 'Failure in before hook', + '', + `Because this error occurred during a \`before all\` hook we are skipping the remaining tests in the current suite: \`${rootSuite}\` (added by [cypress-allure-adapter])`, + ], + }, + }, + ], + + testAttachments: [ + { + expectMessage: 'todo check later', + testName: 'test 1', + attachments: [], + }, + { expectMessage: '', testName: 'test 2', attachments: [] }, + ], + + labels: { + filter: ['suite', 'parentSuite', 'subSuite'], + expected: [ + { + name: 'test 1', + labels: [ + { + name: 'parentSuite', + value: rootSuite, + }, + ], + }, + { + name: 'test 2', + labels: [ + { + name: 'parentSuite', + value: rootSuite, + }, + ], + }, + ], + }, + + testSteps: [ + { + testName: 'test 1', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [], + }, + { + testName: 'test 2', + mapStep: m => ({ status: m.status, attachments: m.attachments }), + expected: [], + }, + ], + + parents: [ + { + testName: 'test 1', + containers: [ + { + name: rootSuite, + stepMap: x => ({ + name: x.name, + status: x.status, + attachments: x.attachments, + }), + befores: [ + { + name: '"before all" hook: in suite', + steps: [], + attachments: [ + { + name: `${rootSuite} -- test 1 -- before all hook in suite (failed).png`, + source: 'source.png', + type: 'image/png', + }, + ], + }, + ], + afters: [ + { + name: '"after all" hook: after in suite', + steps: [], + attachments: [ + { + name: `${rootSuite} -- test 1 -- after all hook after in suite (failed).png`, + source: 'source.png', + type: 'image/png', + }, + ], + }, + { + name: 'video', + steps: [], + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', // video check + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + ], + }, + { + testName: 'test 2', + containers: [ + { + name: rootSuite, + stepMap: x => ({ + name: x.name, + status: x.status, + attachments: x.attachments, + }), + befores: [ + { + name: '"before all" hook: in suite', + steps: [], + attachments: [ + { + name: `${rootSuite} -- test 1 -- before all hook in suite (failed).png`, + source: 'source.png', + type: 'image/png', + }, + ], + }, + ], + afters: [ + { + name: '"after all" hook: after in suite', + steps: [], + attachments: [ + { + name: `${rootSuite} -- test 1 -- after all hook after in suite (failed).png`, + source: 'source.png', + type: 'image/png', + }, + ], + }, + { + name: 'video', + steps: [], + attachments: [ + { + name: 'test_0_number.cy.ts.mp4', // change + source: 'source.mp4', + type: 'video/mp4', + }, + ], + }, + ], + }, + ], + }, + ], + + events: [ + 'mocha: start', + 'mocha: suite: , ', + 'mocha: hook: "before all" hook', + 'cypress: test:before:run: test 1', + 'mocha: hook end: "before all" hook', + `mocha: suite: ${rootSuite}, ${rootSuite}`, + 'mocha: hook: "before all" hook: in suite', + `cypress:screenshot:test:${rootSuite} -- test 1 -- before all hook in suite (failed).png`, + 'mocha: fail: "before all" hook: in suite for "test 1"', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'plugin test:started', + 'plugin test:ended', + 'mocha: hook: "after all" hook: after in suite', + `cypress:screenshot:test:${rootSuite} -- test 1 -- after all hook after in suite (failed).png`, + 'mocha: fail: "after all" hook: after in suite for "test 1"', + `mocha: suite end: ${rootSuite}`, + 'mocha: suite end: ', + 'mocha: end', + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/hooks/suites/suites.test.ts b/tests/test-folder/mocha-events/hooks/suites/suites.test.ts new file mode 100644 index 00000000..2b8fc70e --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/suites/suites.test.ts @@ -0,0 +1,15 @@ +import { createResTest2, generateChecksTests, TestData } from '@test-utils'; + +describe('suites diff tests', () => { + // test + const testsForOneCyRun: TestData[] = ['before-and-after-failure.test.ts'].map( + x => require(`${__dirname}/${x}`).default, + ); + + const res = createResTest2( + testsForOneCyRun.map(x => x.spec), + { allureAddVideoOnPass: 'false' /* DEBUG: 'true'*/ }, + ); + + generateChecksTests(res, testsForOneCyRun); +}); From 4539386af5051d5fadbd222e7c0ca3ded3ffda3f Mon Sep 17 00:00:00 2001 From: mmisty Date: Sat, 29 Jun 2024 00:21:20 +0200 Subject: [PATCH 12/14] fix --- tests/cy-helper/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cy-helper/utils.ts b/tests/cy-helper/utils.ts index 0425e85c..1cb55842 100644 --- a/tests/cy-helper/utils.ts +++ b/tests/cy-helper/utils.ts @@ -5,7 +5,7 @@ import { AllureTest, getParentsArray, parseAllure } from 'allure-js-parser'; import { StepResult } from 'allure-js-commons'; import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'; import { parseBoolean } from 'cypress-redirect-browser-log/utils/functions'; -import { AllureHook, AllureStep, Parent } from 'allure-js-parser/types'; +import { AllureHook, Parent } from 'allure-js-parser/types'; jest.setTimeout(120000); From 1631182fce44356c8d934dd3ae19ffee7977fe4f Mon Sep 17 00:00:00 2001 From: mmisty Date: Sat, 29 Jun 2024 00:29:48 +0200 Subject: [PATCH 13/14] update message and comment --- src/setup/allure-mocha-reporter.ts | 3 +++ .../hooks/suites/before-and-after-failure.test.ts | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/setup/allure-mocha-reporter.ts b/src/setup/allure-mocha-reporter.ts index 624444ca..adc3b24e 100644 --- a/src/setup/allure-mocha-reporter.ts +++ b/src/setup/allure-mocha-reporter.ts @@ -201,6 +201,9 @@ const createTestsForFailedBeforeHook = (runner: Mocha.Runner, test: Mocha.Test) ts.state = 'failed'; if (ts.err) { + // Cypress error cannot be taken here - it will be updated only on 'test:after:run' event + // so to simplify events chain creating own error message + // need to watch cypress error text message when it changes - and update it here ts.err.message = `${ts.err.message}\n\n` + `Because this error occurred during a \`before all\` hook we are skipping the remaining tests in the current suite: \`${ts.parent?.title}\` (added by ${packageLog})`; diff --git a/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts b/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts index 4e50f9e0..4e393c26 100644 --- a/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts +++ b/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts @@ -6,7 +6,8 @@ const data: TestData = { name: rootSuite, rootSuite, fileName: __filename, - spec: `describe('${rootSuite}', () => { + spec: ` + describe('${rootSuite}', () => { before('in suite', () => { throw new Error('Failure in before hook'); }); @@ -22,8 +23,8 @@ const data: TestData = { it('test 2', () => { cy.log('test 2'); }); - }); - `, + }); + `, expect: { testsNames: [`${rootSuite} test 1`, `${rootSuite} test 2`], From 6dd67b8ceb0df9a8b8d4154814c30f45f3d8b9e6 Mon Sep 17 00:00:00 2001 From: mmisty Date: Sat, 29 Jun 2024 00:40:19 +0200 Subject: [PATCH 14/14] fix problem --- ...re-and-after-failure.test.ts => before-and-after-failure.ts} | 0 tests/test-folder/mocha-events/hooks/suites/suites.test.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/test-folder/mocha-events/hooks/suites/{before-and-after-failure.test.ts => before-and-after-failure.ts} (100%) diff --git a/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts b/tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.test.ts rename to tests/test-folder/mocha-events/hooks/suites/before-and-after-failure.ts diff --git a/tests/test-folder/mocha-events/hooks/suites/suites.test.ts b/tests/test-folder/mocha-events/hooks/suites/suites.test.ts index 2b8fc70e..475b3ef4 100644 --- a/tests/test-folder/mocha-events/hooks/suites/suites.test.ts +++ b/tests/test-folder/mocha-events/hooks/suites/suites.test.ts @@ -2,7 +2,7 @@ import { createResTest2, generateChecksTests, TestData } from '@test-utils'; describe('suites diff tests', () => { // test - const testsForOneCyRun: TestData[] = ['before-and-after-failure.test.ts'].map( + const testsForOneCyRun: TestData[] = ['before-and-after-failure.ts'].map( x => require(`${__dirname}/${x}`).default, );