Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EPMRPP-75498 || add nested steps reporting #23

Merged
merged 2 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
chivekrodis marked this conversation as resolved.
Show resolved Hide resolved
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