Skip to content

Commit

Permalink
EPMRPP-75498 || add nested steps reporting (#23)
Browse files Browse the repository at this point in the history
* EPMRPP-75498 || add nested steps reporting

* EPMRPP-75498 || code review fixes - 1
  • Loading branch information
chivekrodis authored Mar 21, 2022
1 parent f9ee8ea commit bff9b11
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 36 deletions.
42 changes: 30 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const config = {
attributes: [{ key: 'key', value: 'value' }, { value: 'value' }],
attachPicturesToLogs: false,
rerun: false,
rerunOf: 'launchUuid of already existed launch',
rerunOf: 'launchUuid of already existed launch',
cucumberNestedSteps: false,
skippedIssue: true,
};

Expand All @@ -39,19 +40,36 @@ exports.config = {
// ...
};
```
| Parameter | Description |
| --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| token | User's Report Portal token from which you want to send requests. It can be found on the profile page of this user.|
| endpoint | URL of your server. For example 'https://server:8080/api/v1'. |
| launch | Name of launch at creation. |
| project | The name of the project in which the launches will be created. |
| rerun | *Default: false.* Enable [rerun](https://github.com/reportportal/documentation/blob/master/src/md/src/DevGuides/rerun.md)|
| rerunOf | UUID of launch you want to rerun. If not specified, report portal will update the latest launch with the same name|
| mode | Launch mode. Allowable values *DEFAULT* (by default) or *DEBUG*.|
| attachPicturesToLogs | Automatically add screenshots|
| debug | This flag allows seeing the logs of the client-javascript. Useful for debugging.|
| Parameter | Description |
|----------------------|--------------------------------------------------------------------------------------------------------------------------|
| token | User's Report Portal token from which you want to send requests. It can be found on the profile page of this user. |
| endpoint | URL of your server. For example 'https://server:8080/api/v1'. |
| launch | Name of launch at creation. |
| project | The name of the project in which the launches will be created. |
| rerun | *Default: false.* Enable [rerun](https://github.com/reportportal/documentation/blob/master/src/md/src/DevGuides/rerun.md)|
| rerunOf | UUID of launch you want to rerun. If not specified, report portal will update the latest launch with the same name |
| mode | Launch mode. Allowable values *DEFAULT* (by default) or *DEBUG*. |
| attachPicturesToLogs | Automatically add screenshots |
| debug | This flag allows seeing the logs of the client-javascript. Useful for debugging. |
| cucumberNestedSteps | [Report your steps as logs](https://github.com/reportportal/agent-js-webdriverio#step-reporting-configuration) |
| skippedIssue| *Default: true.* ReportPortal provides feature to mark skipped tests as not 'To Investigate' items on WS side.<br> Parameter could be equal boolean values:<br> *TRUE* - skipped tests considered as issues and will be marked as 'To Investigate' on Report Portal.<br> *FALSE* - skipped tests will not be marked as 'To Investigate' on application.|

## Step reporting configuration

By default, this agent reports the following structure:

- feature - SUITE
- scenario - TEST
- step - STEP

You may change this behavior to report steps to the log level by enabling scenario-based reporting:

- feature - TEST
- scenario - STEP
- step - log item

To report your steps as logs, you need to pass an additional parameter to the agent config: `"cucumberNestedSteps": true`

## Reporting

This reporter provides Reporting API to use it directly in tests to send some additional data to the report.
Expand Down
79 changes: 71 additions & 8 deletions src/__tests__/onSuiteEnd.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,81 @@ import { options } from './mocks/optionsMock';
import { RPClientMock } from './mocks/RPClientMock';
import { suiteId, suiteName } from './mocks/data';
import { getClientConfig } from '../utils';
import { CUCUMBER_TYPE, RP_STATUSES } from '../constants';

describe('onSuiteEnd', () => {
const reporter = new Reporter(options);
reporter['client'] = new RPClientMock(getClientConfig(options));
reporter['tempLaunchId'] = 'tempLaunchId';
reporter['storage'].addSuite({ id: suiteId, name: suiteName });

it('client.finishTestItem should be called with corresponding params', () => {
reporter.onSuiteEnd();
beforeEach(() => {
reporter['client'] = new RPClientMock(getClientConfig(options));
reporter['storage'].addSuite({ id: suiteId, name: suiteName });
});

describe('client.finishTestItem should be called with corresponding params', () => {
const suiteStats: any = { tests: [{ state: RP_STATUSES.PASSED }] };

it('test with basic config', () => {
reporter.onSuiteEnd(suiteStats);

expect(reporter['client'].finishTestItem).toBeCalledTimes(1);
expect(reporter['client'].finishTestItem).toBeCalledWith(suiteId, {});
expect(reporter['storage'].getCurrentSuite()).toEqual(null);
});

it('config with cucumberNestedSteps=true, no custom status', () => {
reporter['options'].cucumberNestedSteps = true;

reporter.onSuiteEnd({ ...suiteStats, type: CUCUMBER_TYPE.SCENARIO });

expect(reporter['client'].finishTestItem).toBeCalledTimes(1);
expect(reporter['client'].finishTestItem).toBeCalledWith(suiteId, {
status: RP_STATUSES.PASSED,
});
expect(reporter['storage'].getCurrentSuite()).toEqual(null);
});

it('config with cucumberNestedSteps=true, no custom status, all steps=passed', () => {
reporter['options'].cucumberNestedSteps = true;

reporter.onSuiteEnd({
...suiteStats,
type: CUCUMBER_TYPE.SCENARIO,
});

expect(reporter['client'].finishTestItem).toBeCalledTimes(1);
expect(reporter['client'].finishTestItem).toBeCalledWith(suiteId, {
status: RP_STATUSES.PASSED,
});
expect(reporter['storage'].getCurrentSuite()).toEqual(null);
});

it('config with cucumberNestedSteps=true, no custom status, some tests=failed', () => {
reporter['options'].cucumberNestedSteps = true;

reporter.onSuiteEnd({
...suiteStats,
type: CUCUMBER_TYPE.SCENARIO,
tests: [...suiteStats.tests, { state: RP_STATUSES.FAILED }],
});

expect(reporter['client'].finishTestItem).toBeCalledTimes(1);
expect(reporter['client'].finishTestItem).toBeCalledWith(suiteId, {
status: RP_STATUSES.FAILED,
});
expect(reporter['storage'].getCurrentSuite()).toEqual(null);
});

it('config with cucumberNestedSteps=true, with custom status', () => {
reporter['options'].cucumberNestedSteps = true;
reporter['storage'].addAdditionalSuiteData(suiteName, { status: RP_STATUSES.INFO });

reporter.onSuiteEnd(suiteStats);

expect(reporter['client'].finishTestItem).toBeCalledTimes(1);
expect(reporter['client'].finishTestItem).toBeCalledWith(suiteId, {});
expect(reporter['storage'].getCurrentSuite()).toEqual(null);
expect(reporter['client'].finishTestItem).toBeCalledTimes(1);
expect(reporter['client'].finishTestItem).toBeCalledWith(suiteId, {
status: RP_STATUSES.INFO,
});
expect(reporter['storage'].getCurrentSuite()).toEqual(null);
});
});
});
22 changes: 9 additions & 13 deletions src/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ describe('utils', () => {
});

it('getClientConfig with extended config', () => {
const extendedOptions = {
...options,
const additionalOptions = {
rerun: true,
rerunOf: '00000000-0000-0000-0000-000000000000',
skippedIssue: true,
Expand All @@ -66,21 +65,18 @@ describe('utils', () => {
restClientConfig: {
agent: { keepAlive: true },
},
cucumberNestedSteps: true,
};
const extendedOptions = {
...options,
...additionalOptions,
};
const extendedRes = {
const expectedRes = {
...baseRes,
rerun: true,
rerunOf: '00000000-0000-0000-0000-000000000000',
skippedIssue: true,
mode: 'DEFAULT',
debug: true,
headers: { foo: 'bar' },
restClientConfig: {
agent: { keepAlive: true },
},
...additionalOptions,
};

expect(getClientConfig(extendedOptions)).toEqual(extendedRes);
expect(getClientConfig(extendedOptions)).toEqual(expectedRes);
});
});

Expand Down
19 changes: 16 additions & 3 deletions src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ export class Reporter extends WDIOReporter {
if (isCucumberFeature && suiteStats.description) {
suiteDataRQ.description = suiteStats.description;
}
if (this.options.cucumberNestedSteps) {
suiteDataRQ.type = isCucumberFeature ? TYPES.TEST : TYPES.STEP;
}
const { tempId, promise } = this.client.startTestItem(suiteDataRQ, this.tempLaunchId, parentId);
promiseErrorHandler(promise);
const additionalData = this.storage.getAdditionalSuiteData(name);
Expand All @@ -123,6 +126,7 @@ export class Reporter extends WDIOReporter {
name,
type: TYPES.STEP,
codeRef,
...(this.options.cucumberNestedSteps && { hasStats: false }),
};
const { tempId, promise } = this.client.startTestItem(
testItemDataRQ,
Expand Down Expand Up @@ -181,10 +185,19 @@ export class Reporter extends WDIOReporter {
this.storage.removeTest(id);
}

onSuiteEnd(): void {
onSuiteEnd(suiteStats: SuiteStats): void {
const { id, name } = this.storage.getCurrentSuite();
const { status, attributes, description, testCaseId } =
this.storage.getAdditionalSuiteData(name);
const {
status: customStatus,
attributes,
description,
testCaseId,
} = this.storage.getAdditionalSuiteData(name);
let status = customStatus;
if (this.options.cucumberNestedSteps && suiteStats.type === CUCUMBER_TYPE.SCENARIO) {
const isAllStepsPassed = suiteStats.tests.every((test) => test.state === RP_STATUSES.PASSED);
status = customStatus || (isAllStepsPassed ? RP_STATUSES.PASSED : RP_STATUSES.FAILED);
}
const finishTestItemData = {
...(status && { status }),
...(attributes && { attributes }),
Expand Down
2 changes: 2 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const getClientConfig = (options: Partial<Reporters.Options>): Config =>
debug,
headers,
restClientConfig,
cucumberNestedSteps,
} = options;
return {
token,
Expand All @@ -58,6 +59,7 @@ export const getClientConfig = (options: Partial<Reporters.Options>): Config =>
...(debug && { debug }),
...(headers && { headers }),
...(restClientConfig && { restClientConfig }),
...(cucumberNestedSteps && { cucumberNestedSteps }),
};
};

Expand Down

0 comments on commit bff9b11

Please sign in to comment.