Skip to content

Commit

Permalink
EPMRPP-89644 || Implement attachments support (#14)
Browse files Browse the repository at this point in the history
* EPMRPP-89644 || Implement attachments support

* EPMRPP-89644 || Update changelog

* EPMRPP-89644 || Fix lint errors

* EPMRPP-89644 || Fix lint errors

* EPMRPP-89644 || Add description support for attach log

* EPMRPP-89644 || Fix lint errors

* EPMRPP-89644 || Code Review fixes - 1

* EPMRPP-89644 || Code Review fixes - 1 (fix lint errors)

* EPMRPP-89644 || Code Review fixes - 2
  • Loading branch information
AliakseiLiasnitski authored Mar 20, 2024
1 parent 944e183 commit 2b0e273
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
### Added
- ReportingApi with attachment support

## [5.0.0] - 2024-02-15
### Added
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,38 @@ console.error();
console's `log`, `info`,`dubug` reports as info log.

console's `error`, `warn` reports as error log if message contains _error_ mention, otherwise as warn log.

### Reporting API

This reporter provides Reporting API to use it directly in tests to send some additional data to the report.

To start using the `ReportingApi` in tests, just import it from `'@reportportal/agent-js-vitest'`:
```javascript
import { ReportingApi } from '@reportportal/agent-js-vitest';
```

#### Reporting API methods

The API provide methods for attaching data.<br/>

##### attachment
Send file to ReportPortal for the current test. Should be called inside of corresponding test.<br/>
`ReportingApi.attachment(task: vitest.Task, data: Attachment, description?: string);`<br/>
**required**: `task`, `data`<br/>
**optional**: `description`<br/>
where `Attachment` type is `{name: string; type: string; content: string | Buffer;}`<br/>
Example:
```javascript
test('should contain logs with attachments',({ task }) => {
const fileName = 'test.jpg';
const fileContent = fs.readFileSync(path.resolve(__dirname, './attachments', fileName));

ReportingApi.attachment(task, {
name: fileName,
type: 'image/png',
content: fileContent.toString('base64'),
}, 'Description');

expect(true).toBe(true);
});
```
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

import { RPReporter } from './reporter';
import { ReportingApi } from './reportingApi';

export { RPReporter };

export { RPReporter, ReportingApi };
export default RPReporter;
4 changes: 4 additions & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
FinishTestItemObjType,
LogRQ,
Attachment,
RPTaskMeta,
ReportingApi,
} from './reporting';
import { ReportPortalConfig } from './configs';
import { Attribute } from './common';
Expand All @@ -32,5 +34,7 @@ export {
ReportPortalConfig,
Attachment,
Attribute,
RPTaskMeta,
ReportingApi,
LogRQ,
};
15 changes: 14 additions & 1 deletion src/models/reporting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
* limitations under the License.
*
*/

// eslint-disable-next-line import/named
import { Task, TaskMeta } from 'vitest';
import { Attribute, Issue } from './common';
import { TEST_ITEM_TYPES, LOG_LEVELS, LAUNCH_MODES } from '../constants';

Expand Down Expand Up @@ -61,3 +62,15 @@ export interface LogRQ {
time?: number;
file?: Attachment;
}

export interface RPTaskMeta extends TaskMeta {
rpMeta: {
test: {
logs: LogRQ[];
};
};
}

export interface ReportingApi {
attachment: (context: Task, data: Attachment, description?: string) => void;
}
9 changes: 8 additions & 1 deletion src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
getCodeRef,
getBasePath,
isErrorLog,
isRPTaskMeta,
} from './utils';
import {
LAUNCH_MODES,
Expand Down Expand Up @@ -165,13 +166,19 @@ export class RPReporter implements Reporter {
const packsReversed = [...packs];
packsReversed.reverse();

for (const [id, taskResult] of packsReversed) {
for (const [id, taskResult, meta] of packsReversed) {
const testItem = this.testItems.get(id);
const { id: testItemId, finishSend } = testItem || {};
if (!testItemId || finishSend || !FINISHED_STATES.includes(taskResult?.state)) {
continue;
}

if (isRPTaskMeta(meta)) {
meta.rpMeta.test.logs.forEach((logRq) => {
this.sendLog(testItemId, logRq);
});
}

const finishTestItemObj = this.getFinishTestItemObj(taskResult);

if (taskResult?.errors?.length) {
Expand Down
31 changes: 31 additions & 0 deletions src/reportingApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as vitest from 'vitest';
import * as Models from './models';
import { isRPTaskMeta } from './utils';

const injectRPTaskMeta = (task: vitest.Task) => {
if (isRPTaskMeta(task.meta)) {
return;
}

(task.meta as Models.RPTaskMeta) = {
...task.meta,
rpMeta: {
test: {
logs: [],
},
},
};
};

const attachment = (task: vitest.Task, data: Models.Attachment, description?: string) => {
injectRPTaskMeta(task);
(task.meta as Models.RPTaskMeta).rpMeta.test.logs.push({
file: data,
time: Date.now(),
message: description || data.name,
});
};

export const ReportingApi: Models.ReportingApi = {
attachment,
};
5 changes: 5 additions & 0 deletions src/types/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*
*/
import * as vitest from 'vitest';

declare namespace Interfaces {
interface Attribute {
Expand All @@ -38,4 +39,8 @@ declare namespace Interfaces {
interface ObjUniversal {
[name: string]: string;
}

interface ReportingApi {
attachment: (task: vitest.Task, data: Attachment, description?: string) => void;
}
}
6 changes: 5 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
*/

import { normalize, sep } from 'node:path';
import * as vitest from 'vitest';
// @ts-ignore
import { name as pjsonName, version as pjsonVersion } from '../package.json';
import { Attribute } from './models';
import { Attribute, RPTaskMeta } from './models';

export const isFalse = (value: string | boolean | undefined): boolean =>
[false, 'false'].includes(value);
Expand Down Expand Up @@ -63,3 +64,6 @@ export const getCodeRef = (basePath: string, itemTitle: string): string =>
export const isErrorLog = (message: string): boolean => {
return message.toLowerCase().includes('error');
};

export const isRPTaskMeta = (meta: vitest.TaskMeta | RPTaskMeta): meta is RPTaskMeta =>
'rpMeta' in meta;

0 comments on commit 2b0e273

Please sign in to comment.