From ca79a97052b2a199cac528c6b696b8984ca7a478 Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 23 Sep 2024 17:28:35 +0200 Subject: [PATCH] EPMRPP-94905 || Time with microseconds support (#21) --- .github/workflows/CI-pipeline.yml | 8 +++- .github/workflows/publish.yml | 4 +- CHANGELOG.md | 6 ++- README.md | 11 +++-- jest.config.js | 15 +++--- package-lock.json | 47 +++++++++++++++---- package.json | 24 +++++----- src/__tests__/mocks/RPClientMock.ts | 6 +-- src/__tests__/onTaskUpdate.spec.ts | 9 ++-- src/models/reporting.ts | 8 ++-- src/reporter.ts | 11 +++-- src/reportingApi.ts | 3 +- .../client-javascript/index.d.ts} | 1 - .../client-javascript/lib}/events.d.ts | 0 .../client-javascript/lib/helpers.d.ts | 20 ++++++++ src/types/@reportportal/index.d.ts | 0 16 files changed, 117 insertions(+), 56 deletions(-) rename src/types/{clientJavascript.d.ts => @reportportal/client-javascript/index.d.ts} (97%) rename src/types/{ => @reportportal/client-javascript/lib}/events.d.ts (100%) create mode 100644 src/types/@reportportal/client-javascript/lib/helpers.d.ts create mode 100644 src/types/@reportportal/index.d.ts diff --git a/.github/workflows/CI-pipeline.yml b/.github/workflows/CI-pipeline.yml index c4621ac..949e737 100644 --- a/.github/workflows/CI-pipeline.yml +++ b/.github/workflows/CI-pipeline.yml @@ -22,6 +22,12 @@ on: - README.md - CHANGELOG.md pull_request: + branches: + - develop + - master + paths-ignore: + - README.md + - CHANGELOG.md jobs: test: @@ -33,7 +39,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20 - - name: Install of node dependencies + - name: Install dependencies run: npm install - name: Build the source code run: npm run build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index adda934..5da9c0e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,7 +27,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20 - - name: Install of node dependencies + - name: Install dependencies run: npm install - name: Build the source code run: npm run build @@ -47,7 +47,7 @@ jobs: with: node-version: 20 registry-url: 'https://registry.npmjs.org' - - name: Install of node dependencies + - name: Install dependencies run: npm install - name: Build the source code run: npm run build diff --git a/CHANGELOG.md b/CHANGELOG.md index 1781d12..d4209bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ ### Added -- Test case id, attributes and description providing via Reporting API. +- Test case id, attributes and description providing via [Reporting API](./README.md#reporting-api-methods). ### Changed -- `@reportportal/client-javascript` bumped to version `5.1.4`, new `launchUuidPrintOutput` types introduced: 'FILE', 'ENVIRONMENT'. +- The agent now supports reporting the time for launches, test items and logs with microsecond precision in the ISO string format. + For logs, microsecond precision is available on the UI from ReportPortal version 24.2. +- `@reportportal/client-javascript` bumped to version `5.3.0`, new `launchUuidPrintOutput` types introduced: 'FILE', 'ENVIRONMENT'. ### Security - Updated versions of vulnerable packages (braces). diff --git a/README.md b/README.md index dbe316e..53a6d7b 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ npm install --save-dev @reportportal/agent-js-vitest import RPReporter from '@reportportal/agent-js-vitest'; // or import { RPReporter } from '@reportportal/agent-js-vitest'; const rpConfig = { - apiKey: '00000000-0000-0000-0000-000000000000', - endpoint: 'https://your.reportportal.server/api/v2', + apiKey: '', + endpoint: 'https://your.reportportal.server/api/v1', project: 'Your ReportPortal project name', launch: 'Your launch name', attributes: [ @@ -48,7 +48,7 @@ The full list of available options presented below. | Option | Necessity | Default | Description | |------------------------------------|-----------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | apiKey | Required | | User's ReportPortal token from which you want to send requests. It can be found on the profile page of this user. | -| endpoint | Required | | URL of your server. For example 'https://server:8080/api/v2'. | +| endpoint | Required | | URL of your server. For example 'https://server:8080/api/v1'. | | launch | Required | | Name of launch at creation. | | project | Required | | The name of the project in which the launches will be created. | | attributes | Optional | [] | Launch attributes. | @@ -79,6 +79,11 @@ The following options can be overridden using ENVIRONMENT variables: } ``` +## Asynchronous API + +The client supports an asynchronous reporting (via the ReportPortal asynchronous API). +If you want the client to report through the asynchronous API, change `v1` to `v2` in the `endpoint` address. + ## Reporting When organizing tests, specify titles for `describe` blocks, as this is necessary to build the correct structure of reports. diff --git a/jest.config.js b/jest.config.js index f1a453e..f0b1b41 100644 --- a/jest.config.js +++ b/jest.config.js @@ -17,7 +17,13 @@ module.exports = { roots: ['/src'], - transform: { '.(ts|tsx)': 'ts-jest' }, + transform: { + '.ts': ['ts-jest', { + diagnostics: { + pathRegex: '(/__tests__/.*?\\.(test|spec))\\.(ts|js)$', + }, + }], + }, testEnvironment: 'node', testRegex: '/__tests__/.*\\.(test|spec)?\\.(ts|js)$', moduleFileExtensions: ['ts', 'js'], @@ -31,11 +37,4 @@ module.exports = { statements: 80, }, }, - globals: { - 'ts-jest': { - diagnostics: { - pathRegex: '(/__tests__/.*?\\.(test|spec))\\.(ts|js)$', - }, - }, - }, }; diff --git a/package-lock.json b/package-lock.json index 7477323..4e102a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "5.1.0", "license": "Apache-2.0", "dependencies": { - "@reportportal/client-javascript": "~5.1.4" + "@reportportal/client-javascript": "~5.3.0" }, "devDependencies": { "@types/jest": "^29.5.12", @@ -1605,19 +1605,20 @@ } }, "node_modules/@reportportal/client-javascript": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@reportportal/client-javascript/-/client-javascript-5.1.4.tgz", - "integrity": "sha512-Pk00dSYX8TANmEkg2CN06PxoSW1f83d1mew1M0kw5pDZOif+1cYrjy1E4HNrdLBoYhAH6oQIISvJSKc7K6A8fg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@reportportal/client-javascript/-/client-javascript-5.3.0.tgz", + "integrity": "sha512-328279/aC6rXe6BNEZeCXJ1/b5k05RdC5HSR8GYnr6TFWvYV5DQd4/E33ekhT0+Psenf6sMcccl24lZZdxKOvA==", "dependencies": { - "axios": "^1.6.8", + "axios": "^1.7.7", "axios-retry": "^4.1.0", "glob": "^8.1.0", "ini": "^2.0.0", + "microtime": "^3.1.1", "uniqid": "^5.4.0", "uuid": "^9.0.1" }, "engines": { - "node": ">=12.x" + "node": ">=14.x" } }, "node_modules/@rollup/rollup-android-arm-eabi": { @@ -2560,9 +2561,9 @@ } }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -5959,6 +5960,19 @@ "node": ">=8.6" } }, + "node_modules/microtime": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/microtime/-/microtime-3.1.1.tgz", + "integrity": "sha512-to1r7o24cDsud9IhN6/8wGmMx5R2kT0w2Xwm5okbYI3d1dk6Xv0m+Z+jg2vS9pt+ocgQHTCtgs/YuyJhySzxNg==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.4.0" + }, + "engines": { + "node": ">= 14.13.0" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -6053,6 +6067,21 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node_modules/node-gyp-build": { + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", + "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", diff --git a/package.json b/package.json index 9767a2b..e05428f 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,15 @@ "name": "@reportportal/agent-js-vitest", "version": "5.1.0", "description": "Agent to integrate Vitest with ReportPortal.", + "scripts": { + "build": "npm run clean && tsc", + "clean": "rimraf ./build", + "lint": "eslint \"src/**/*.ts\"", + "format": "npm run lint -- --fix", + "postbuild": "mkdir -p build && cp -R src/scripts build/", + "test": "jest", + "test:coverage": "jest --coverage" + }, "main": "build/index.js", "types": "build/index.d.ts", "exports": { @@ -14,21 +23,12 @@ "require": "./build/scripts/setup.js" } }, - "scripts": { - "build": "npm run clean && tsc", - "clean": "rimraf ./build", - "lint": "eslint \"src/**/*.ts\"", - "format": "npm run lint -- --fix", - "postbuild": "mkdir -p build && cp -R src/scripts build/", - "test": "jest", - "test:coverage": "jest --coverage" - }, - "dependencies": { - "@reportportal/client-javascript": "~5.1.4" - }, "files": [ "/build" ], + "dependencies": { + "@reportportal/client-javascript": "~5.3.0" + }, "devDependencies": { "vitest": "^1.6.0", "@types/jest": "^29.5.12", diff --git a/src/__tests__/mocks/RPClientMock.ts b/src/__tests__/mocks/RPClientMock.ts index 10c2d86..a90c067 100644 --- a/src/__tests__/mocks/RPClientMock.ts +++ b/src/__tests__/mocks/RPClientMock.ts @@ -1,6 +1,6 @@ import { ReportPortalConfig } from '../../models'; -const mockedDate = Date.now(); +export const mockedDate = '2024-09-23T12:20:59.392987Z'; export class RPClientMock { private config: ReportPortalConfig; @@ -30,10 +30,6 @@ export class RPClientMock { promise: Promise.resolve('ok'), }); - public helpers = { - now: (): number => mockedDate, - }; - public checkConnect = jest.fn().mockReturnValue({ promise: Promise.resolve('ok'), }); diff --git a/src/__tests__/onTaskUpdate.spec.ts b/src/__tests__/onTaskUpdate.spec.ts index 43bc520..3f5b825 100644 --- a/src/__tests__/onTaskUpdate.spec.ts +++ b/src/__tests__/onTaskUpdate.spec.ts @@ -1,11 +1,14 @@ +import * as vitest from 'vitest'; +import clientHelpers from '@reportportal/client-javascript/lib/helpers'; import { RPReporter } from '../reporter'; import { config } from './mocks/configMock'; -import { RPClientMock } from './mocks/RPClientMock'; -import * as vitest from 'vitest'; +import { RPClientMock, mockedDate } from './mocks/RPClientMock'; import { RPTaskMeta } from '../models'; import { STATUSES, TASK_STATUS } from '../constants'; describe('onTaskUpdate', () => { + jest.spyOn(clientHelpers, 'now').mockReturnValue(mockedDate); + let reporter: RPReporter; const testTaskId = 'testTaskId'; const testItemId = 'testId'; @@ -44,7 +47,7 @@ describe('onTaskUpdate', () => { attributes, description, testCaseId, - endTime: reporter.client.helpers.now(), + endTime: '2024-09-23T12:20:59.392987Z', }; reporter.onTaskUpdate(packs); diff --git a/src/models/reporting.ts b/src/models/reporting.ts index f2992e7..b20b18c 100644 --- a/src/models/reporting.ts +++ b/src/models/reporting.ts @@ -20,7 +20,7 @@ import { Attribute, Issue } from './common'; import { TEST_ITEM_TYPES, LOG_LEVELS, LAUNCH_MODES } from '../constants'; export interface StartLaunchObjType { - startTime?: number; + startTime?: string | number; attributes?: Array; description?: string; name?: string; @@ -35,14 +35,14 @@ export interface StartTestObjType { type: TEST_ITEM_TYPES; attributes?: Array; description?: string; - startTime?: number; + startTime?: string | number; codeRef?: string; testCaseId?: string; retry?: boolean; } export interface FinishTestItemObjType { - endTime?: number; + endTime?: string | number; status?: string; attributes?: Attribute[]; description?: string; @@ -59,7 +59,7 @@ export interface Attachment { export interface LogRQ { level?: LOG_LEVELS; message?: string; - time?: number; + time?: string | number; file?: Attachment; } diff --git a/src/reporter.ts b/src/reporter.ts index 1b4331e..9ddbedf 100644 --- a/src/reporter.ts +++ b/src/reporter.ts @@ -16,6 +16,7 @@ */ import RPClient from '@reportportal/client-javascript'; +import clientHelpers from '@reportportal/client-javascript/lib/helpers'; // eslint-disable-next-line import/named import { File, Reporter, Task, TaskResult, TaskResultPack, UserConsoleLog, Vitest } from 'vitest'; import { @@ -96,7 +97,7 @@ export class RPReporter implements Reporter { const startLaunchObj: StartLaunchObjType = { name: launch, - startTime: this.client.helpers.now(), + startTime: clientHelpers.now(), description, attributes: attributes && attributes.length ? attributes.concat(systemAttributes) : systemAttributes, @@ -120,7 +121,7 @@ export class RPReporter implements Reporter { startDescendants(descendant: Task, basePath: string, parentId?: string) { const { name, id, type, mode } = descendant; - const startTime = this.client.helpers.now(); + const startTime = clientHelpers.now(); const isSuite = type === 'suite'; const codeRef = getCodeRef(basePath, parentId ? name : ''); @@ -213,7 +214,7 @@ export class RPReporter implements Reporter { getFinishTestItemObj(taskResult?: TaskResult): FinishTestItemObjType { const finishTestItemObj: FinishTestItemObjType = { status: STATUSES.FAILED, - endTime: this.client.helpers.now(), + endTime: clientHelpers.now(), }; if (taskResult) { @@ -244,7 +245,7 @@ export class RPReporter implements Reporter { testItemId, { level: LOG_LEVELS.INFO, - time: this.client.helpers.now(), + time: clientHelpers.now(), ...logRqWithoutFile, }, file, @@ -278,7 +279,7 @@ export class RPReporter implements Reporter { async onFinished() { if (!this.config.launchId) { const { promise } = this.client.finishLaunch(this.launchId, { - endTime: this.client.helpers.now(), + endTime: clientHelpers.now(), }); this.addRequestToPromisesQueue(promise, 'Failed to finish launch.'); } diff --git a/src/reportingApi.ts b/src/reportingApi.ts index 599aa09..e828d48 100644 --- a/src/reportingApi.ts +++ b/src/reportingApi.ts @@ -1,4 +1,5 @@ import * as vitest from 'vitest'; +import clientHelpers from '@reportportal/client-javascript/lib/helpers'; import * as Models from './models'; import { isRPTaskMeta } from './utils'; @@ -22,7 +23,7 @@ const attachment = (task: vitest.Task, data: Models.Attachment, description?: st injectRPTaskMeta(task); (task.meta as Models.RPTaskMeta).rpMeta.test.logs.push({ file: data, - time: Date.now(), + time: clientHelpers.now(), message: description || data.name, }); }; diff --git a/src/types/clientJavascript.d.ts b/src/types/@reportportal/client-javascript/index.d.ts similarity index 97% rename from src/types/clientJavascript.d.ts rename to src/types/@reportportal/client-javascript/index.d.ts index 8512d9e..a38ece6 100644 --- a/src/types/clientJavascript.d.ts +++ b/src/types/@reportportal/client-javascript/index.d.ts @@ -25,6 +25,5 @@ declare module '@reportportal/client-javascript' { public finishTestItem(itemId: string, itemObj: any): any; public sendLog(itemId: string, itemObj: any, fileObj?: any): any; public checkConnect(): any; - public helpers: any; } } diff --git a/src/types/events.d.ts b/src/types/@reportportal/client-javascript/lib/events.d.ts similarity index 100% rename from src/types/events.d.ts rename to src/types/@reportportal/client-javascript/lib/events.d.ts diff --git a/src/types/@reportportal/client-javascript/lib/helpers.d.ts b/src/types/@reportportal/client-javascript/lib/helpers.d.ts new file mode 100644 index 0000000..351a541 --- /dev/null +++ b/src/types/@reportportal/client-javascript/lib/helpers.d.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2024 EPAM Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +declare module '@reportportal/client-javascript/lib/helpers' { + export function now(): string; +} diff --git a/src/types/@reportportal/index.d.ts b/src/types/@reportportal/index.d.ts new file mode 100644 index 0000000..e69de29