Skip to content

Commit

Permalink
[minor] mark parent step as broken when children have errors and unca…
Browse files Browse the repository at this point in the history
…ught exception support (#157)
  • Loading branch information
mmisty authored Jul 1, 2024
1 parent b3445d7 commit b33d3a3
Show file tree
Hide file tree
Showing 8 changed files with 332 additions and 22 deletions.
5 changes: 0 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@

> **Full Changelog**: https://github.com/mmisty/cypress-allure-adapter/compare/v2.0.8...v2.0.9
### 2.0.9
* [#120] [patch] Fix: screenshots are not being added for tests with failed global hooks (i.e. before hook used without describe) by @mmisty in https://github.com/mmisty/cypress-allure-adapter/pull/150

> **Full Changelog**: https://github.com/mmisty/cypress-allure-adapter/compare/v2.0.8...v2.0.9
### 2.0.8
* More test fixes by @mmisty in https://github.com/mmisty/cypress-allure-adapter/pull/148

Expand Down
12 changes: 6 additions & 6 deletions README.dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ Some of these is under construction.
- [ ] tests for plugins

#### Defects / enhancements
- [ ] #41 - Do not attach files with long arguments to child commands - only for parent enhancement
- [ ] #77 - Mark parent step non-success when some steps have non-success status enhancement
- [ ] #64 - Uncaught:exception step is marked as passed step and all its parents as well bug minor
- [ ] #152 - Global hook doesn't have steps for tests in nested suites bug minor
- [ ] #119 - Global After hooks are not being added to test when it has more than one parent suite bug minor
- [ ] #156 - Before/after each are not marked as failed for failed attempts of test when retries >0
- [ ] #41 - Do not attach files with long arguments to child commands - only for parent - enhancement
- [ ] #152 - Global hook doesn't have steps for tests in nested suites - bug minor
- [ ] #119 - Global After hooks are not being added to test when it has more than one parent suite - bug minor
- [ ] #156 - Before/after each are not marked as failed for failed attempts of test when retries >0 - bug minor
- [x] #77 - Mark parent step non-success when some steps have non-success status - enhancement
- [x] #64 - Uncaught:exception step is marked as passed step and all its parents as well - bug minor

### Contribution
Feel free to create a PRs.
Expand Down
75 changes: 75 additions & 0 deletions integration/e2e/assertions/uncaught-error.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { visitHtml } from '../../common/helper';

describe('uncaught error', () => {
it('#1 test pass', function () {
cy.on('uncaught:exception', () => {
// returning false here prevents Cypress from
// failing the test
return false;
});

visitHtml({
script: `
throw new Error('UNCAUGHT 1');
`,
});

cy.get('div').should('exist');
});

it('#1 test pass with parent', function () {
cy.on('uncaught:exception', () => {
// returning false here prevents Cypress from
// failing the test
return false;
});

cy.allure().startStep('VISITING');
visitHtml({
script: `
throw new Error('UNCAUGHT 1');
`,
});

cy.allure().endStep();
cy.get('div').should('exist');
});

it('#2 test fail', function () {
cy.on('uncaught:exception', () => {
// returning false here prevents Cypress from
// failing the test
return false;
});
cy.allure().startStep('VISITING');
visitHtml({
script: `
throw new Error('UNCAUGHT 1');
`,
});
cy.get('div').should('not.exist');
cy.allure().endStep();
});

it('#3 test fail', function () {
cy.allure().startStep('VISITING');
visitHtml({
script: `
throw new Error('UNCAUGHT 1');
`,
});
cy.get('div').should('not.exist');
cy.allure().endStep();
});

it('#5 test fail', function () {
cy.allure().startStep('VISITING');

cy.allure().endStep();
cy.allure().startStep('VISITING2');
cy.allure().startStep('CHILD');
cy.allure().endStep('failed');

cy.allure().endStep();
});
});
47 changes: 42 additions & 5 deletions src/plugins/allure-reporter-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ export class AllureReporter {
executableItem.statusDetails.message = dtls?.message;
}

// unknown
if (res !== Status.FAILED && res !== Status.BROKEN && res !== Status.PASSED && res !== Status.SKIPPED) {
executableItem.statusDetails.message = dtls?.message;
}
Expand Down Expand Up @@ -1037,14 +1038,37 @@ export class AllureReporter {
}
}

// set status to last step recursively
// set status to last step recursively when unknown or passed statuses
setLastStepStatus(steps: ExecutableItem[], status: Status, details?: StatusDetails) {
const stepsCount = steps.length;
const step = steps[stepsCount - 1];
const stepStatus = step?.status;

if (stepsCount > 0) {
this.setLastStepStatus(steps[stepsCount - 1].steps, status, details);
this.setExecutableItemStatus(steps[stepsCount - 1], status, details);
this.setLastStepStatus(step.steps, status, details);
}

if (!stepStatus || ![Status.FAILED, Status.SKIPPED, Status.BROKEN].includes(stepStatus)) {
this.setExecutableItemStatus(step, status, details);
}
}

hasChildrenWith(steps: ExecutableItem[], statuses: Status[]) {
const stepsCount = steps.length;
let hasError = false;
steps.forEach(step => {
const stepStatus = step.status as Status;

if (stepStatus && stepsCount > 0 && statuses.includes(stepStatus)) {
hasError = true;
}

if (stepsCount > 0) {
return this.hasChildrenWith(step.steps, statuses);
}
});

return hasError;
}

endStep(arg: AllureTaskArgs<'stepEnded'>) {
Expand All @@ -1063,9 +1087,22 @@ export class AllureReporter {
return;
}

const markBrokenStatuses = ['failed' as Status, 'broken' as Status];
const passedStatuses = ['passed' as Status];

// when unknown or passed
this.setLastStepStatus(this.currentStep.wrappedItem.steps, status, details);
this.setExecutableStatus(this.currentStep, status, details);
this.currentStep.endStep(date);

if (
passedStatuses.includes(status as Status) &&
this.hasChildrenWith(this.currentStep.wrappedItem.steps, markBrokenStatuses)
) {
this.setExecutableStatus(this.currentStep, Status.BROKEN);
} else {
this.setExecutableStatus(this.currentStep, status, details);
}

this.currentStep.endStep(date ?? Date.now());

this.steps.pop();
}
Expand Down
24 changes: 20 additions & 4 deletions src/setup/cypress-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
} from '../common/command-names';

const dbg = 'cypress-allure:cy-events';
const UNCAUGHT_EXCEPTION_NAME = 'uncaught exception';
const UNCAUGHT_EXCEPTION_STATUS = 'broken' as Status;

type OneRequestConsoleProp = {
'Request Body': unknown;
Expand Down Expand Up @@ -282,20 +284,34 @@ export const handleCyLogEvents = (
filterCommandLog(command, ignoreCommands).forEach((log: any) => {
const attr = log.attributes;
const logName = attr.name;
const cmdMessage = stepMessage(attr.name, attr.message === 'null' ? '' : attr.message);
const logMessage = stepMessage(attr.name, attr.message === 'null' ? '' : attr.message);

// console.log('logName');
// console.log(logName);
// console.log('attr');
// console.log(attr);

Cypress.Allure.startStep(cmdMessage);
Cypress.Allure.startStep(logMessage);

if (logName !== 'assert' && log.message && log.message.length > ARGS_TRIM_AT) {
Cypress.Allure.attachment(`${cmdMessage} args`, log.message, 'application/json');
Cypress.Allure.attachment(`${logMessage} args`, log.message, 'application/json');
}

Cypress.Allure.endStep(attr.err ? 'failed' : 'passed');
let state: Status = (attr.err ? 'failed' : 'passed') as Status;
let details: { message?: string; trace?: string } | undefined = undefined;

if (logName.indexOf(UNCAUGHT_EXCEPTION_NAME) !== -1) {
const consoleProps = attr.consoleProps();
const err = consoleProps?.props?.Error as Error | undefined;
const isCommandFailed = command.state === 'failed';
const failedStatus = 'failed' as Status;
// when command failed we mark uncaught exception log as error,
// in other cases it will be marked as broken
state = isCommandFailed ? failedStatus : UNCAUGHT_EXCEPTION_STATUS;
details = { message: err?.message, trace: err?.stack };
}

Cypress.Allure.endStep(state, details);
});
};

Expand Down
Loading

0 comments on commit b33d3a3

Please sign in to comment.