From 1c4d9ed88d102323eac9bc1f5081fd3604f639a7 Mon Sep 17 00:00:00 2001 From: Taisia Pitko Date: Mon, 1 Jul 2024 20:15:21 +0200 Subject: [PATCH] [patch] fixed synchronous logs addition plus added tests for assertions (#164) --- src/common/command-names.ts | 14 ++ src/setup/cypress-events.ts | 36 +++- src/setup/process-tags.ts | 20 +- tests/cy-helper/utils.ts | 85 +++++--- .../assertions/assertions.test.ts | 18 ++ .../data-assertions-one-failed-for-command.ts | 87 +++++++++ .../data-assertions-one-passed-for-command.ts | 77 ++++++++ .../data-assertions-parent-step-status.ts | 145 ++++++++++++++ ...a-assertions-several-failed-for-command.ts | 182 ++++++++++++++++++ ...a-assertions-several-passed-for-command.ts | 94 +++++++++ .../data-assertions-sync-assertion.ts | 179 +++++++++++++++++ .../mocha-events/assertions/visit-html.ts | 67 +++++++ .../before-after--nested-suite.test.ts | 17 ++ .../data-nested-suite-after-fail-simple-04.ts | 0 .../data-nested-suite-after-pass-06.ts | 0 .../data-nested-suite-before-fail-01.ts | 0 ...data-nested-suite-before-fail-simple-03.ts | 0 .../data-nested-suite-before-pass-02.ts | 0 .../data-nested-suite-pass-07.ts | 0 .../data-nested-suite-with-global-hook-05.ts | 0 .../before-after-each--nested-suite.test.ts | 17 ++ ...ta-after-each-fail-nested-suite-several.ts | 0 .../data-after-each-fail-nested-suite.ts | 0 ...a-before-each-fail-nested-suite-several.ts | 0 .../data-before-each-fail-nested-suite.ts | 0 .../before-after-each-retry.test.ts | 0 .../data-before-each-retry-fail.ts | 0 .../data-before-each-retry-pass-after-fail.ts | 0 .../hooks/regression-steps.test.ts | 44 ++--- 29 files changed, 1012 insertions(+), 70 deletions(-) create mode 100644 tests/test-folder/mocha-events/assertions/assertions.test.ts create mode 100644 tests/test-folder/mocha-events/assertions/data-assertions-one-failed-for-command.ts create mode 100644 tests/test-folder/mocha-events/assertions/data-assertions-one-passed-for-command.ts create mode 100644 tests/test-folder/mocha-events/assertions/data-assertions-parent-step-status.ts create mode 100644 tests/test-folder/mocha-events/assertions/data-assertions-several-failed-for-command.ts create mode 100644 tests/test-folder/mocha-events/assertions/data-assertions-several-passed-for-command.ts create mode 100644 tests/test-folder/mocha-events/assertions/data-assertions-sync-assertion.ts create mode 100644 tests/test-folder/mocha-events/assertions/visit-html.ts create mode 100644 tests/test-folder/mocha-events/hooks/before-after--nested-suite/before-after--nested-suite.test.ts rename tests/test-folder/mocha-events/hooks/{before-after => before-after--nested-suite}/data-nested-suite-after-fail-simple-04.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after => before-after--nested-suite}/data-nested-suite-after-pass-06.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after => before-after--nested-suite}/data-nested-suite-before-fail-01.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after => before-after--nested-suite}/data-nested-suite-before-fail-simple-03.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after => before-after--nested-suite}/data-nested-suite-before-pass-02.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after => before-after--nested-suite}/data-nested-suite-pass-07.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after => before-after--nested-suite}/data-nested-suite-with-global-hook-05.ts (100%) create mode 100644 tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/before-after-each--nested-suite.test.ts rename tests/test-folder/mocha-events/hooks/{before-after-each => before-after-each--nested-suite}/data-after-each-fail-nested-suite-several.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after-each => before-after-each--nested-suite}/data-after-each-fail-nested-suite.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after-each => before-after-each--nested-suite}/data-before-each-fail-nested-suite-several.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after-each => before-after-each--nested-suite}/data-before-each-fail-nested-suite.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after-each-retry => before-after-each--retry}/before-after-each-retry.test.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after-each-retry => before-after-each--retry}/data-before-each-retry-fail.ts (100%) rename tests/test-folder/mocha-events/hooks/{before-after-each-retry => before-after-each--retry}/data-before-each-retry-pass-after-fail.ts (100%) diff --git a/src/common/command-names.ts b/src/common/command-names.ts index 8d13c7da..04d99c49 100644 --- a/src/common/command-names.ts +++ b/src/common/command-names.ts @@ -6,6 +6,20 @@ export const COMMAND_REQUEST = 'request'; export type CommandLog = { attributes?: { name?: string; commandLogId?: string; consoleProps?: () => any; message?: string; error?: any }; }; + +export type CyLog = { + name?: string; + commandLogId?: string; + consoleProps?: () => any; + message?: string; + chainerId?: string; + error?: any; + err?: any; + end?: boolean; + ended?: boolean; + state?: string; +}; + export type CommandT = { state?: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/setup/cypress-events.ts b/src/setup/cypress-events.ts index 6c4ef06e..30ee445c 100644 --- a/src/setup/cypress-events.ts +++ b/src/setup/cypress-events.ts @@ -12,6 +12,7 @@ import { filterCommandLog, ignoreAllCommands, isGherkin, + CyLog, stepMessage, stringify, withTry, @@ -22,6 +23,7 @@ const UNCAUGHT_EXCEPTION_NAME = 'uncaught exception'; const UNCAUGHT_EXCEPTION_STATUS = 'broken' as Status; const failedStatus = 'failed' as Status; const passedStatus = 'passed' as Status; +const brokenStatus = 'broken' as Status; type OneRequestConsoleProp = { 'Request Body': unknown; @@ -255,14 +257,38 @@ export const handleCyLogEvents = ( gherkinLog.current = undefined; }); - Cypress.on('log:added', log => { + Cypress.on('log:added', (log: CyLog) => { if (!allureLogCyCommands()) { return; } withTry('report log:added', () => { - const cmdMessage = stepMessage(log.name, log.message === 'null' ? '' : log.message); - const logName = log.name; + const logName = log.name ?? 'no-log-name'; + const logMessage = log.message; + const chainerId = log.chainerId; + const end = log.end || log.ended; + const logState = log.state; + + const cmdMessage = stepMessage(logName, logMessage === 'null' ? '' : logMessage); + + // console.log(log); + + if (!chainerId && end) { + // synchronous log without commands + Cypress.Allure.startStep(cmdMessage); + + let status = passedStatus; + + if (logName === 'WARNING') { + status = brokenStatus; + } + + if (logState === 'failed') { + status = failedStatus; + } + + Cypress.Allure.endStep(status); + } if (isGherkin(logName)) { if (gherkinLog.current) { @@ -327,6 +353,10 @@ export const handleCyLogEvents = ( details = { message: err?.message, trace: err?.stack }; } + if (logName === 'WARNING') { + state = brokenStatus; + } + Cypress.Allure.endStep(state, details); }); }; diff --git a/src/setup/process-tags.ts b/src/setup/process-tags.ts index 1430a86b..694fdc59 100644 --- a/src/setup/process-tags.ts +++ b/src/setup/process-tags.ts @@ -17,9 +17,8 @@ export const processTagsOnTestStart = (test: Mocha.Test) => { const [urlOrId, name] = t.info ?? []; if (!urlOrId) { - Cypress.log({ message: `WARN: tag @${tagNoAt} tag should have id: @${tagNoAt}("idOrUrl")` }).error( - new Error(), - ); + const message = `tag @${tagNoAt} tag should have id: @${tagNoAt}("idOrUrl")`; + Cypress.log({ name: 'WARNING', message }).error(new Error()); break; } Cypress.Allure[tagNoAt](urlOrId, name); @@ -31,9 +30,8 @@ export const processTagsOnTestStart = (test: Mocha.Test) => { const [urlOrId, name, type] = t.info ?? []; if (!urlOrId) { - Cypress.log({ message: `WARN: Tag @${tagNoAt} should have id or url: @${tagNoAt}("idOrUrl")` }).error( - new Error(), - ); + const message = `tag @${tagNoAt} should have id or url: @${tagNoAt}("idOrUrl")`; + Cypress.log({ name: 'WARNING', message }).error(new Error()); break; } @@ -72,9 +70,8 @@ export const processTagsOnTestStart = (test: Mocha.Test) => { const [singleValue] = t.info ?? []; if (!singleValue) { - Cypress.log({ message: `WARN: tag @${tagNoAt} tag should have value: @${tagNoAt}("value")` }).error( - new Error(), - ); + const message = `tag @${tagNoAt} tag should have value: @${tagNoAt}("value")`; + Cypress.log({ name: 'WARNING', message }).error(new Error()); break; } Cypress.Allure[tagNoAt](singleValue as Severity); @@ -86,9 +83,8 @@ export const processTagsOnTestStart = (test: Mocha.Test) => { const [name, value] = t.info ?? []; if (!name) { - Cypress.log({ - message: `WARN: tag @${tagNoAt} tag should have name and/or value: @${tagNoAt}("myLabel","value")`, - }).error(new Error()); + const message = `tag @${tagNoAt} tag should have name and/or value: @${tagNoAt}("myLabel","value")`; + Cypress.log({ name: 'WARNING', message }).error(new Error()); break; } Cypress.Allure.label(name, value); diff --git a/tests/cy-helper/utils.ts b/tests/cy-helper/utils.ts index 4a31228f..e205146a 100644 --- a/tests/cy-helper/utils.ts +++ b/tests/cy-helper/utils.ts @@ -298,12 +298,22 @@ export const fullStepAttachment = ( export const fullStepMap = ( res: AllureTest, mapStep?: (m: StepResult) => any, + filterStep?: (m: StepResult) => boolean, ) => { const skipItems = ['generatereport', 'coverage']; - return mapSteps(res.steps as StepResult[], mapStep, z => - skipItems.every(y => z.name?.toLowerCase().indexOf(y) === -1), - ); + return mapSteps(res.steps as StepResult[], mapStep, z => { + const includesNoSkippedSteps = skipItems.every( + y => z.name?.toLowerCase().indexOf(y) === -1, + ); + const isFiltered = filterStep?.(z); + + if (isFiltered === undefined) { + return includesNoSkippedSteps; + } + + return includesNoSkippedSteps && isFiltered; + }); }; // eslint-disable-next-line jest/no-export @@ -458,17 +468,23 @@ export const createResTest2 = ( attempt(retries); }); }; + const video = parseBoolean(envConfig?.video ?? `${true}`); + // todo fix video + console.log(`video:${video}`); return cy .run({ - spec, + spec: spec as string, specPattern: 'integration/e2e/**/*.(cy|test|spec).ts', port, browser: 'chrome', - trashAssetsBeforeRuns: true, env, quiet: `${process.env.QUIET}` === 'true', - video: parseBoolean(envConfig?.video ?? `${true}`), + video, + // config: { + // ...config, + // trashAssetsBeforeRuns: true, + // }, }) .catch(e => { err = e as Error; @@ -582,17 +598,17 @@ export const covergeAfterAll = [ start: 1323475200000, status: 'passed', steps: [ - // { - // attachments: [], - // name: 'Coverage: Generating report [@cypress/code-coverage]', - // parameters: [], - // stage: 'finished', - // start: 1323475200000, - // status: 'passed', - // statusDetails: {}, - // steps: [], - // stop: 1323475200011, - // }, + { + attachments: [], + name: 'Coverage: Generating report [@cypress/code-coverage]', + parameters: [], + stage: 'finished', + start: 1323475200000, + status: 'passed', + statusDetails: {}, + steps: [], + stop: 1323475200011, + }, ], stop: 1323475200010, }, @@ -607,17 +623,17 @@ export const covergeBeforeAll = [ start: 1323475200000, status: 'passed', steps: [ - // { - // attachments: [], - // name: 'Coverage: Reset [@cypress/code-coverage]', - // parameters: [], - // stage: 'finished', - // start: 1323475200000, - // status: 'passed', - // statusDetails: {}, - // steps: [], - // stop: 1323475200011, - // }, + { + attachments: [], + name: 'Coverage: Reset [@cypress/code-coverage]', + parameters: [], + stage: 'finished', + start: 1323475200000, + status: 'passed', + statusDetails: {}, + steps: [], + stop: 1323475200011, + }, ], stop: 1323475200010, }, @@ -657,6 +673,7 @@ export type TestData = { testName: string; index?: number; mapStep?: (m: StepResult) => any; + filterStep?: (m: StepResult) => boolean; expected: any[]; }[]; @@ -813,10 +830,14 @@ export const generateChecksTests = (res: Result, testsForRun: TestData[]) => { it(`steps for test ${testItem.testName} ${testItem.index ?? ''}`, () => { const tests = getTest(resFixed, testItem.testName); - const obj = fullStepMap(tests[testItem.index ?? 0]!, m => ({ - name: m.name, - ...(testItem.mapStep?.(m) ?? {}), - })); + const obj = fullStepMap( + tests[testItem.index ?? 0]!, + m => ({ + name: m.name, + ...(testItem.mapStep?.(m) ?? {}), + }), + testItem.filterStep, + ); wrapError(() => expect(obj).toEqual(testItem.expected)); }); diff --git a/tests/test-folder/mocha-events/assertions/assertions.test.ts b/tests/test-folder/mocha-events/assertions/assertions.test.ts new file mode 100644 index 00000000..61298bd2 --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/assertions.test.ts @@ -0,0 +1,18 @@ +import { + createResTest2, + generateChecksTests, + selectTestsToRun, +} from '@test-utils'; +import { basename } from 'path'; + +describe(`suite: ${basename(__dirname)}`, () => { + const testsForOneCyRun = selectTestsToRun(__dirname); + + const res = createResTest2( + testsForOneCyRun.map(x => x.spec), + // video false to speedup + { allureAddVideoOnPass: 'false', video: 'false' /* DEBUG: 'true'*/ }, + ); + + generateChecksTests(res, testsForOneCyRun); +}); diff --git a/tests/test-folder/mocha-events/assertions/data-assertions-one-failed-for-command.ts b/tests/test-folder/mocha-events/assertions/data-assertions-one-failed-for-command.ts new file mode 100644 index 00000000..2a374083 --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/data-assertions-one-failed-for-command.ts @@ -0,0 +1,87 @@ +import { TestData } from '@test-utils'; +import { basename } from 'path'; +import { visitHtmlCode } from './visit-html'; + +const rootSuite = `${basename(__filename)}`; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` +describe('${rootSuite}', { defaultCommandTimeout: 300 },() => { + ${visitHtmlCode} + + it('test 1', () => { + cy.get('[data-test-id="item"]').should('contain', 'NonExistent'); + }); +}); + `, + + expect: { + testsNames: [`${rootSuite} test 1`], + + testStatuses: [ + { + testName: 'test 1', + index: 0, + status: 'failed', + statusDetails: { + message: [ + "Timed out retrying after 300ms: expected '[
, 4 more... ]' to contain 'NonExistent'", + ], + }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should have no attachments', + testName: 'test 1', + index: 0, + attachments: [ + { + name: 'data-assertions-one-failed-for-command.ts -- test 1 (failed).png', + source: 'source.png', + type: 'image/png', + }, + ], + }, + ], + + testSteps: [ + { + testName: 'test 1', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + expected: [ + { + attachments: [], + name: 'get: [data-test-id="item"]', + status: 'failed', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'assert: expected **[
, 4 more... ]** to contain **NonExistent**', + status: 'failed', + statusDetails: {}, + steps: [], + }, + ], + }, + ], + }, + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/assertions/data-assertions-one-passed-for-command.ts b/tests/test-folder/mocha-events/assertions/data-assertions-one-passed-for-command.ts new file mode 100644 index 00000000..2947a6a4 --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/data-assertions-one-passed-for-command.ts @@ -0,0 +1,77 @@ +import { TestData } from '@test-utils'; +import { basename } from 'path'; +import { visitHtmlCode } from './visit-html'; + +const rootSuite = `${basename(__filename)}`; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` +describe('${rootSuite}', { defaultCommandTimeout: 1000 },() => { + ${visitHtmlCode} + + it('test 1', () => { + cy.get('div').should('contain', 'Tropical Fruit'); + }); +}); + `, + + expect: { + testsNames: [`${rootSuite} test 1`], + + testStatuses: [ + { + testName: 'test 1', + index: 0, + status: 'passed', + statusDetails: { message: undefined }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should have no attachments', + testName: 'test 1', + index: 0, + attachments: [], + }, + ], + + testSteps: [ + { + testName: 'test 1', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + expected: [ + { + attachments: [], + name: 'get: div', + status: 'passed', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'assert: expected **[
, 16 more... ]** to contain **Tropical Fruit**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + ], + }, + ], + }, + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/assertions/data-assertions-parent-step-status.ts b/tests/test-folder/mocha-events/assertions/data-assertions-parent-step-status.ts new file mode 100644 index 00000000..bebbb543 --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/data-assertions-parent-step-status.ts @@ -0,0 +1,145 @@ +import { TestData } from '@test-utils'; +import { basename } from 'path'; + +const rootSuite = `${basename(__filename)}`; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` +describe('${rootSuite}', { defaultCommandTimeout: 300 },() => { + + it('test 1', () => { + cy.allure().startStep('step P0'); + cy.allure().endStep(); + + cy.allure().startStep('step P'); + + cy.allure().startStep('step C 1'); + cy.allure().startStep('step CC 1'); + cy.allure().endStep(); + cy.allure().endStep(); + + cy.allure().startStep('step C 2'); + cy.allure().startStep('step CC 2'); + cy.allure().endStep('failed', { message: "Sub step failed" }); + cy.allure().endStep(); + + + cy.allure().startStep('step C 3'); + cy.allure().endStep(); + + cy.allure().endStep(); + cy.allure().startStep('step P2'); + cy.allure().endStep(); + }); +}); + `, + + expect: { + testsNames: [`${rootSuite} test 1`], + + testStatuses: [ + { + testName: 'test 1', + index: 0, + status: 'passed', + statusDetails: { + message: undefined, + }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should have no attachments', + testName: 'test 1', + index: 0, + attachments: [], + }, + ], + + testSteps: [ + { + testName: 'test 1', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + expected: [ + { + attachments: [], + name: 'step P0', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'step P', + // should be broken when children have non-success + status: 'broken', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'step C 1', + status: 'passed', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'step CC 1', + status: 'passed', + statusDetails: {}, + steps: [], + }, + ], + }, + { + attachments: [], + name: 'step C 2', + status: 'broken', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'step CC 2', + status: 'failed', + statusDetails: { + message: 'Sub step failed', + }, + steps: [], + }, + ], + }, + { + attachments: [], + name: 'step C 3', + status: 'passed', + statusDetails: {}, + steps: [], + }, + ], + }, + { + attachments: [], + name: 'step P2', + status: 'passed', + statusDetails: {}, + steps: [], + }, + ], + }, + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/assertions/data-assertions-several-failed-for-command.ts b/tests/test-folder/mocha-events/assertions/data-assertions-several-failed-for-command.ts new file mode 100644 index 00000000..d775a2ef --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/data-assertions-several-failed-for-command.ts @@ -0,0 +1,182 @@ +import { TestData } from '@test-utils'; +import { basename } from 'path'; +import { visitHtmlCode } from './visit-html'; + +const rootSuite = `${basename(__filename)}`; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` +describe('${rootSuite}', { defaultCommandTimeout: 1000 },() => { + ${visitHtmlCode} + + it('test 1', () => { + cy.get('div') + .should('contain', 'Orange') + .should('contain', 'Tropical Fruit') + .should('not.contain', 'Lichi'); // first pass, then start to fail when Lichi appears + }); + + it('test 2', { defaultCommandTimeout: 300 }, () => { + let i = 0; + cy.get('div').should(() => { + i++; + + expect(i < 10 ? 1 : 0).eq(0); + expect(1).eq(1); + expect(1, 'always fail').eq(2); + }); + }); +}); + `, + + expect: { + testsNames: [`${rootSuite} test 1`, `${rootSuite} test 2`], + + testStatuses: [ + { + testName: 'test 1', + index: 0, + status: 'failed', + statusDetails: { + message: [ + "Timed out retrying after 1000ms: expected '[
, 18 more... ]' not to contain 'Lichi'", + ], + }, + }, + { + testName: 'test 2', + index: 0, + status: 'failed', + statusDetails: { + message: [ + 'Timed out retrying after 300ms: always fail: expected 1 to equal 2', + ], + }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should have attachments', + testName: 'test 1', + index: 0, + attachments: [ + { + name: 'data-assertions-several-failed-for-command.ts -- test 1 (failed).png', + source: 'source.png', + type: 'image/png', + }, + ], + }, + { + expectMessage: 'should have attachments', + testName: 'test 2', + index: 0, + attachments: [ + { + name: 'data-assertions-several-failed-for-command.ts -- test 2 (failed).png', + source: 'source.png', + type: 'image/png', + }, + ], + }, + ], + + testSteps: [ + { + testName: 'test 1', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + expected: [ + { + attachments: [], + name: 'get: div', + status: 'failed', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'assert: expected **[
, 18 more... ]** to contain **Orange**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'assert: expected **[
, 18 more... ]** to contain **Tropical Fruit**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'assert: expected **[
, 18 more... ]** not to contain **Lichi**', + status: 'failed', + statusDetails: {}, + steps: [], + }, + ], + }, + ], + }, + + { + testName: 'test 2', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + expected: [ + { + attachments: [], + name: 'get: div', + status: 'failed', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'assert: expected **0** to equal **0**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'assert: expected **1** to equal **1**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'assert: always fail: expected **1** to equal **2**', + status: 'failed', + statusDetails: {}, + steps: [], + }, + ], + }, + ], + }, + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/assertions/data-assertions-several-passed-for-command.ts b/tests/test-folder/mocha-events/assertions/data-assertions-several-passed-for-command.ts new file mode 100644 index 00000000..19ddf8a3 --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/data-assertions-several-passed-for-command.ts @@ -0,0 +1,94 @@ +import { TestData } from '@test-utils'; +import { basename } from 'path'; +import { visitHtmlCode } from './visit-html'; + +const rootSuite = `${basename(__filename)}`; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` +describe('${rootSuite}', { defaultCommandTimeout: 1000 },() => { + ${visitHtmlCode} + + it('test 1', () => { + cy.get('div') + .should('contain', 'Tropical Fruit') + .should('contain', 'Lichi') + .should('contain', 'Task Card 2'); + }); +}); + `, + + expect: { + testsNames: [`${rootSuite} test 1`], + + testStatuses: [ + { + testName: 'test 1', + index: 0, + status: 'passed', + statusDetails: { message: undefined }, + }, + ], + + testAttachments: [ + { + expectMessage: 'should have no attachments', + testName: 'test 1', + index: 0, + attachments: [], + }, + ], + + testSteps: [ + { + testName: 'test 1', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + expected: [ + { + attachments: [], + name: 'get: div', + status: 'passed', + statusDetails: {}, + steps: [ + { + attachments: [], + name: 'assert: expected **[
, 18 more... ]** to contain **Tropical Fruit**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'assert: expected **[
, 18 more... ]** to contain **Lichi**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'assert: expected **[
, 18 more... ]** to contain **Task Card 2**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + ], + }, + ], + }, + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/assertions/data-assertions-sync-assertion.ts b/tests/test-folder/mocha-events/assertions/data-assertions-sync-assertion.ts new file mode 100644 index 00000000..74b464e0 --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/data-assertions-sync-assertion.ts @@ -0,0 +1,179 @@ +import { TestData } from '@test-utils'; +import { basename } from 'path'; + +const rootSuite = `${basename(__filename)}`; + +const data: TestData = { + name: rootSuite, + rootSuite, + fileName: __filename, + spec: ` +describe('${rootSuite}', { defaultCommandTimeout: 300 },() => { + + it('test 1', () => { + expect(0).eq(0); + }); + + it('test 2 - warning', () => { + Cypress.log({name: 'WARNING', message: 'some warn'}); + }); + + it('test 3 - log', () => { + Cypress.log({name: 'some log', message: 'some message'}); + }); + + it('test 4 - several', () => { + expect(0).eq(0); + expect(0).eq(1); + }); +}); + `, + + expect: { + testsNames: [ + `${rootSuite} test 1`, + `${rootSuite} test 2 - warning`, + `${rootSuite} test 3 - log`, + `${rootSuite} test 4 - several`, + ], + + testStatuses: [ + { + testName: 'test 1', + index: 0, + status: 'passed', + statusDetails: { + message: undefined, + }, + }, + { + testName: 'test 2 - warning', + index: 0, + status: 'passed', + statusDetails: { + message: undefined, + }, + }, + { + testName: 'test 3 - log', + index: 0, + status: 'passed', + statusDetails: { + message: undefined, + }, + }, + { + testName: 'test 4 - several', + index: 0, + status: 'failed', + statusDetails: { + message: ['expected 0 to equal 1'], + }, + }, + ], + + testSteps: [ + { + testName: 'test 1', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + expected: [ + { + attachments: [], + name: 'assert: expected **0** to equal **0**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + ], + }, + + { + testName: 'test 2 - warning', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + + expected: [ + { + attachments: [], + name: 'WARNING: some warn', + status: 'broken', + statusDetails: {}, + steps: [], + }, + ], + }, + { + testName: 'test 3 - log', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + + expected: [ + { + attachments: [], + name: 'some log: some message', + status: 'passed', + statusDetails: {}, + steps: [], + }, + ], + }, + { + testName: 'test 4 - several', + index: 0, + mapStep: m => ({ + status: m.status, + attachments: m.attachments, + statusDetails: m.statusDetails, + }), + filterStep: m => + ['before each', 'after each'].every( + x => m.name && m.name.indexOf(x) === -1, + ), + + expected: [ + { + attachments: [], + name: 'assert: expected **0** to equal **0**', + status: 'passed', + statusDetails: {}, + steps: [], + }, + { + attachments: [], + name: 'assert: expected **0** to equal **1**', + status: 'failed', + statusDetails: {}, + steps: [], + }, + ], + }, + ], + }, +}; + +export default data; diff --git a/tests/test-folder/mocha-events/assertions/visit-html.ts b/tests/test-folder/mocha-events/assertions/visit-html.ts new file mode 100644 index 00000000..1bf4b50f --- /dev/null +++ b/tests/test-folder/mocha-events/assertions/visit-html.ts @@ -0,0 +1,67 @@ +export const visitHtmlCode = ` +const visitHtml = (opts) => { + const html = \` + + \$\{opts.body\} + + \`; + + cy.intercept('mytest.com**', { + body: html + }); + cy.visit('mytest.com'); + } + + beforeEach(() => { + visitHtml({ + body: \` + +
+
Apple
+
Hello
+
+
+
+
Banana
+
Buy
+
+
+
+
Orange
+
Is Round
+
+ +
+
Task card
+
+ +\`, + script: \` + + // add element after some time + setTimeout(()=> { + var child = document.createElement("div"); + child.setAttribute('data-test-id','item'); + child.innerHTML = '
Lichi
Fruit
'; + document.body.appendChild(child); + }, 100); + + setTimeout(()=> { + + var child2 = document.createElement("div"); + child2.setAttribute('data-test-id','item'); + child2.innerHTML = '
Lichi
Tropical Fruit
'; + document.body.appendChild(child2); + }, 200); + + setTimeout(()=> { + + var child2 = document.createElement("div"); + child2.setAttribute('data-qa-id','task-card-title'); + child2.innerHTML = '
Task Card 2
'; + document.body.appendChild(child2); + }, 300); + \`, + }); + }); +`; diff --git a/tests/test-folder/mocha-events/hooks/before-after--nested-suite/before-after--nested-suite.test.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/before-after--nested-suite.test.ts new file mode 100644 index 00000000..ec2675b4 --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/before-after--nested-suite.test.ts @@ -0,0 +1,17 @@ +import { + createResTest2, + generateChecksTests, + selectTestsToRun, +} from '@test-utils'; +import { basename } from 'path'; + +describe(`suite: ${basename(__dirname)}`, () => { + const testsForOneCyRun = selectTestsToRun(__dirname); + + const res = createResTest2( + testsForOneCyRun.map(x => x.spec), + { allureAddVideoOnPass: 'true' /* DEBUG: 'true'*/ }, + ); + + generateChecksTests(res, testsForOneCyRun); +}); diff --git a/tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-after-fail-simple-04.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-after-fail-simple-04.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-after-fail-simple-04.ts rename to tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-after-fail-simple-04.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-after-pass-06.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-after-pass-06.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-after-pass-06.ts rename to tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-after-pass-06.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-before-fail-01.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-before-fail-01.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-before-fail-01.ts rename to tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-before-fail-01.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-before-fail-simple-03.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-before-fail-simple-03.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-before-fail-simple-03.ts rename to tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-before-fail-simple-03.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-before-pass-02.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-before-pass-02.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-before-pass-02.ts rename to tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-before-pass-02.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-pass-07.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-pass-07.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-pass-07.ts rename to tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-pass-07.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-with-global-hook-05.ts b/tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-with-global-hook-05.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after/data-nested-suite-with-global-hook-05.ts rename to tests/test-folder/mocha-events/hooks/before-after--nested-suite/data-nested-suite-with-global-hook-05.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/before-after-each--nested-suite.test.ts b/tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/before-after-each--nested-suite.test.ts new file mode 100644 index 00000000..7bcc14e2 --- /dev/null +++ b/tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/before-after-each--nested-suite.test.ts @@ -0,0 +1,17 @@ +import { + createResTest2, + generateChecksTests, + selectTestsToRun, +} from '@test-utils'; +import { basename } from 'path'; + +describe(`suite: ${basename(__dirname)}`, () => { + const testsForOneCyRun = selectTestsToRun(__dirname); + + const res = createResTest2( + testsForOneCyRun.map(x => x.spec), + { allureAddVideoOnPass: 'false' /*DEBUG: 'true'*/ }, + ); + + generateChecksTests(res, testsForOneCyRun); +}); diff --git a/tests/test-folder/mocha-events/hooks/before-after-each/data-after-each-fail-nested-suite-several.ts b/tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-after-each-fail-nested-suite-several.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after-each/data-after-each-fail-nested-suite-several.ts rename to tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-after-each-fail-nested-suite-several.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after-each/data-after-each-fail-nested-suite.ts b/tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-after-each-fail-nested-suite.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after-each/data-after-each-fail-nested-suite.ts rename to tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-after-each-fail-nested-suite.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after-each/data-before-each-fail-nested-suite-several.ts b/tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-before-each-fail-nested-suite-several.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after-each/data-before-each-fail-nested-suite-several.ts rename to tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-before-each-fail-nested-suite-several.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after-each/data-before-each-fail-nested-suite.ts b/tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-before-each-fail-nested-suite.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after-each/data-before-each-fail-nested-suite.ts rename to tests/test-folder/mocha-events/hooks/before-after-each--nested-suite/data-before-each-fail-nested-suite.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after-each-retry/before-after-each-retry.test.ts b/tests/test-folder/mocha-events/hooks/before-after-each--retry/before-after-each-retry.test.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after-each-retry/before-after-each-retry.test.ts rename to tests/test-folder/mocha-events/hooks/before-after-each--retry/before-after-each-retry.test.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after-each-retry/data-before-each-retry-fail.ts b/tests/test-folder/mocha-events/hooks/before-after-each--retry/data-before-each-retry-fail.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after-each-retry/data-before-each-retry-fail.ts rename to tests/test-folder/mocha-events/hooks/before-after-each--retry/data-before-each-retry-fail.ts diff --git a/tests/test-folder/mocha-events/hooks/before-after-each-retry/data-before-each-retry-pass-after-fail.ts b/tests/test-folder/mocha-events/hooks/before-after-each--retry/data-before-each-retry-pass-after-fail.ts similarity index 100% rename from tests/test-folder/mocha-events/hooks/before-after-each-retry/data-before-each-retry-pass-after-fail.ts rename to tests/test-folder/mocha-events/hooks/before-after-each--retry/data-before-each-retry-pass-after-fail.ts diff --git a/tests/test-folder/mocha-events/hooks/regression-steps.test.ts b/tests/test-folder/mocha-events/hooks/regression-steps.test.ts index 866b2457..46ea4a89 100644 --- a/tests/test-folder/mocha-events/hooks/regression-steps.test.ts +++ b/tests/test-folder/mocha-events/hooks/regression-steps.test.ts @@ -227,7 +227,13 @@ describe('hooks test - failed global hook step', () => { it('check first test befores', async () => { const parents = resFixed.map(t => getParentsArray(t)); expect( - parents[0].map(t => t.befores?.map(x => mapSteps(x.steps))), + parents[0].map(t => + t.befores?.map(x => + mapSteps(x.steps, undefined, y => + ['coverage'].every(t => y.name?.indexOf(t) === -1), + ), + ), + ), ).toEqual([ [ [], @@ -255,7 +261,13 @@ describe('hooks test - failed global hook step', () => { it('check second test befores', async () => { const parents = resFixed.map(t => getParentsArray(t)); expect( - parents[1].map(t => t.befores?.map(x => mapSteps(x.steps))), + parents[1].map(t => + t.befores?.map(x => + mapSteps(x.steps, undefined, y => + ['coverage'].every(t => y.name?.indexOf(t) === -1), + ), + ), + ), ).toEqual([ [ [], @@ -283,28 +295,14 @@ describe('hooks test - failed global hook step', () => { it('check first test afters', async () => { const parents = resFixed.map(t => getParentsArray(t)); expect( - parents[0].map(t => t.afters?.map(x => mapSteps(x.steps))), - ).toEqual([ - [ - ...whenCoverage( - [], - [ - { - name: 'log: Saving code coverage for **unit** `[@cypress/code-coverage]`', - steps: [], - }, - ], - [], + parents[0].map(t => + t.afters?.map(x => + mapSteps(x.steps, undefined, y => + ['coverage'].every(t => y.name?.indexOf(t) === -1), + ), ), - [ - { - name: 'global teardown', - steps: [], - }, - ], - [], - ], - ]); + ), + ).toEqual([[[], [], [], [{ name: 'global teardown', steps: [] }], []]]); }); it('check tests parent steps', async () => {