Skip to content

Commit

Permalink
EPMRPP-89645 || TestCaseId, attributes, description reporting (#19)
Browse files Browse the repository at this point in the history
* add attributes method

* add testCaseId method

* add description method

* update README.md

* update description method

* add unit tests

* fix bindGlobalReportingApi

* add task data
  • Loading branch information
artsiomBandarenka authored May 30, 2024
1 parent 45af22c commit 9280c59
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 5 deletions.
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,47 @@ test('should contain logs with attachments',({ task }) => {
expect(true).toBe(true);
});
```

##### testCaseId
Add testCaseId to ReportPortal for the current test. Should be called inside of corresponding test.<br/>
`ReportingApi.testCaseId(task: vitest.Task, data: string);`<br/>
**required**: `task`, `data`<br/>
Example:
```javascript
test('should contain testCaseId',({ task }) => {
ReportingApi.testCaseId(task, 'C123456');
expect(true).toBe(true);
});
```

##### description
Add description to ReportPortal for the current test. In case the user call the method more than one time, the existing description will be extended. Should be called inside of corresponding test.<br/>
`ReportingApi.description(task: vitest.Task, data: string);`<br/>
**required**: `task`, `data`<br/>
Example:
```javascript
test('should contain description',({ task }) => {
ReportingApi.description(task, 'Test Description');
expect(true).toBe(true);
});
```

##### attributes
Send file to ReportPortal for the current test. Should be called inside of corresponding test.<br/>
`ReportingApi.attributes(task: vitest.Task, data: Attribute[]);`<br/>
**required**: `task`, `data`<br/>
where `Attribute` type is `{ value: string; key?: string; system?: boolean; }`<br/>
Example:
```javascript
test('should contain attributes',({ task }) => {
ReportingApi.attributes(task,
[
{ key: 'attrKey1', value: 'attrValue1'},
{ value: 'attrValue2'}
]);
expect(true).toBe(true);
});
```
42 changes: 42 additions & 0 deletions src/__tests__/attributesReporting.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { ReportingApi } from '../reportingApi';
import * as vitest from 'vitest';
import { getTask } from './mocks/data';
import { RPTaskMeta } from '../models';

describe('test attributes reporting', () => {
let task: vitest.Task;

beforeEach(() => {
task = getTask();
});

test('should add attributes to task meta', () => {
const data = [
{ key: 'key1', value: 'value1' },
{ key: 'key2', value: 'value2' },
];
ReportingApi.attributes(task, data);

expect((task.meta as RPTaskMeta).rpMeta.test.attributes).toEqual(data);
});

test('should append attributes to existing attributes in task meta', () => {
const existingAttributes = [{ key: 'existingKey', value: 'existingValue' }];
const rpMeta: RPTaskMeta = {
rpMeta: {
test: {
logs: [],
attributes: existingAttributes,
},
},
};
task.meta = rpMeta;
const newAttributes = [{ key: 'newKey', value: 'newValue' }];
ReportingApi.attributes(task, newAttributes);

expect((task.meta as RPTaskMeta).rpMeta.test.attributes).toEqual([
...existingAttributes,
...newAttributes,
]);
});
});
39 changes: 39 additions & 0 deletions src/__tests__/descriptionReporting.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ReportingApi } from '../reportingApi';
import * as vitest from 'vitest';
import { getTask } from './mocks/data';
import { RPTaskMeta } from '../models';

describe('test description reporting', () => {
let task: vitest.Task;

beforeEach(() => {
task = getTask();
});

test('should add description to task meta', () => {
const description = 'test description';
ReportingApi.description(task, description);

expect((task.meta as RPTaskMeta).rpMeta.test.description).toEqual(description);
});

test('should append data to existing description in task meta', () => {
const existingDescription = 'test description';
const rpMeta: RPTaskMeta = {
rpMeta: {
test: {
logs: [],
attributes: [],
description: existingDescription,
},
},
};
task.meta = rpMeta;
const newDescription = 'new test description';
ReportingApi.description(task, newDescription);

expect((task.meta as RPTaskMeta).rpMeta.test.description).toEqual(
existingDescription + '\n' + newDescription,
);
});
});
40 changes: 40 additions & 0 deletions src/__tests__/mocks/RPClientMock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { ReportPortalConfig } from '../../models';

const mockedDate = Date.now();
export class RPClientMock {
private config: ReportPortalConfig;

constructor(config?: ReportPortalConfig) {
this.config = config;
}

public startLaunch = jest.fn().mockReturnValue({
promise: Promise.resolve('ok'),
tempId: 'tempLaunchId',
});

public finishLaunch = jest.fn().mockReturnValue({
promise: Promise.resolve('ok'),
});

public startTestItem = jest.fn().mockReturnValue({
promise: Promise.resolve('ok'),
tempId: 'tempTestItemId',
});

public finishTestItem = jest.fn().mockReturnValue({
promise: Promise.resolve('ok'),
});

public sendLog = jest.fn().mockReturnValue({
promise: Promise.resolve('ok'),
});

public helpers = {
now: (): number => mockedDate,
};

public checkConnect = jest.fn().mockReturnValue({
promise: Promise.resolve('ok'),
});
}
10 changes: 10 additions & 0 deletions src/__tests__/mocks/configMock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ReportPortalConfig } from '../../models';

export const config: ReportPortalConfig = {
apiKey: 'reportportalApiKey',
endpoint: 'https://reportportal.server/api/v1',
project: 'ProjectName',
launch: 'LaunchName',
description: 'Launch description',
attributes: [],
};
13 changes: 13 additions & 0 deletions src/__tests__/mocks/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as vitest from 'vitest';

export function getTask(): vitest.Task {
return {
id: 'id',
name: 'task',
type: 'suite',
mode: 'run',
tasks: [],
meta: {},
projectName: 'testProject',
};
}
56 changes: 56 additions & 0 deletions src/__tests__/onTaskUpdate.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { RPReporter } from '../reporter';
import { config } from './mocks/configMock';
import { RPClientMock } from './mocks/RPClientMock';
import * as vitest from 'vitest';
import { RPTaskMeta } from '../models';
import { STATUSES, TASK_STATUS } from '../constants';

describe('onTaskUpdate', () => {
let reporter: RPReporter;
const testTaskId = 'testTaskId';
const testItemId = 'testId';
beforeEach(() => {
reporter = new RPReporter(config);
reporter.client = new RPClientMock(config);
reporter.launchId = 'tempLaunchId';
reporter.testItems.set(testTaskId, {
id: testItemId,
});
});

describe('finishing test with attributes, testCaseId, description in rpMeta ', () => {
it('test with attributes, description, testCaseId', () => {
const attributes = [
{
key: 'key1',
value: 'value1',
},
];
const description = 'test_description';
const testCaseId = 'testCaseId';
const taskMeta: RPTaskMeta = {
rpMeta: {
test: {
logs: [],
attributes,
description,
testCaseId,
},
},
};
const packs: vitest.TaskResultPack[] = [[testTaskId, { state: TASK_STATUS.pass }, taskMeta]];
const finishTestItemRQ = {
status: STATUSES.PASSED,
attributes,
description,
testCaseId,
endTime: reporter.client.helpers.now(),
};

reporter.onTaskUpdate(packs);

expect(reporter.client.finishTestItem).toBeCalledTimes(1);
expect(reporter.client.finishTestItem).toBeCalledWith(testItemId, finishTestItemRQ);
});
});
});
36 changes: 36 additions & 0 deletions src/__tests__/testCaseIdReporting.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ReportingApi } from '../reportingApi';
import * as vitest from 'vitest';
import { getTask } from './mocks/data';
import { RPTaskMeta } from '../models';

describe('test case id reporting', () => {
let task: vitest.Task;

beforeEach(() => {
task = getTask();
});

test('should set test case id to task meta', () => {
const testCaseId = 'test_case_id';
ReportingApi.testCaseId(task, testCaseId);

expect((task.meta as RPTaskMeta).rpMeta.test.testCaseId).toEqual(testCaseId);
});

test('should overwrite test case id in task meta', () => {
const rpMeta: RPTaskMeta = {
rpMeta: {
test: {
logs: [],
attributes: [],
testCaseId: 'old_test_case_id',
},
},
};
task.meta = rpMeta;
const newTestCaseId = 'new_test_case_id';
ReportingApi.testCaseId(task, newTestCaseId);

expect((task.meta as RPTaskMeta).rpMeta.test.testCaseId).toEqual(newTestCaseId);
});
});
9 changes: 9 additions & 0 deletions src/models/reporting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,23 @@ export interface RPTaskMeta extends TaskMeta {
rpMeta: {
test: {
logs: LogRQ[];
attributes: Attribute[];
testCaseId?: string;
description?: string;
};
};
}

export interface ReportingApi {
attachment: (context: Task, data: Attachment, description?: string) => void;
attributes: (context: Task, data: Attribute[]) => void;
testCaseId: (context: Task, data: string) => void;
description: (context: Task, data: string) => void;
}

export interface GlobalReportingApi {
attachment: (data: Attachment, description?: string) => void;
attributes: (data: Attribute[]) => void;
testCaseId: (data: string) => void;
description: (data: string) => void;
}
8 changes: 5 additions & 3 deletions src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,16 @@ export class RPReporter implements Reporter {
continue;
}

const finishTestItemObj = this.getFinishTestItemObj(taskResult);

if (isRPTaskMeta(meta)) {
meta.rpMeta.test.logs.forEach((logRq) => {
const { logs, attributes, testCaseId, description } = meta.rpMeta.test;
logs.forEach((logRq) => {
this.sendLog(testItemId, logRq);
});
Object.assign(finishTestItemObj, { attributes, testCaseId, description });
}

const finishTestItemObj = this.getFinishTestItemObj(taskResult);

if (taskResult?.errors?.length) {
const error = taskResult.errors[0];

Expand Down
31 changes: 29 additions & 2 deletions src/reportingApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const injectRPTaskMeta = (task: vitest.Task) => {
rpMeta: {
test: {
logs: [],
attributes: [],
},
},
};
Expand All @@ -26,11 +27,37 @@ const attachment = (task: vitest.Task, data: Models.Attachment, description?: st
});
};

const attributes = (task: vitest.Task, data: Models.Attribute[]) => {
injectRPTaskMeta(task);
const rpMeta = (task.meta as Models.RPTaskMeta).rpMeta;
rpMeta.test.attributes = [...rpMeta.test.attributes, ...data];
};

const testCaseId = (task: vitest.Task, data: string) => {
injectRPTaskMeta(task);
(task.meta as Models.RPTaskMeta).rpMeta.test.testCaseId = data;
};

const description = (task: vitest.Task, data: string) => {
injectRPTaskMeta(task);
const rpMeta = (task.meta as Models.RPTaskMeta).rpMeta;
if (rpMeta.test.description) {
rpMeta.test.description = `${rpMeta.test.description}\n${data}`;
} else {
rpMeta.test.description = data;
}
};

export const ReportingApi: Models.ReportingApi = {
attachment,
attributes,
testCaseId,
description,
};

export const bindReportingApi = (task: vitest.Task): Models.GlobalReportingApi => ({
attachment: (data: Models.Attachment, description?: string) =>
attachment(task, data, description),
attachment: (data: Models.Attachment, message?: string) => attachment(task, data, message),
attributes: (data: Models.Attribute[]) => attributes(task, data),
testCaseId: (data: string) => testCaseId(task, data),
description: (data: string) => description(task, data),
});

0 comments on commit 9280c59

Please sign in to comment.