diff --git a/.github/workflows/CI-pipeline.yml b/.github/workflows/CI-pipeline.yml index 9cb6ec1..6f5e2a8 100644 --- a/.github/workflows/CI-pipeline.yml +++ b/.github/workflows/CI-pipeline.yml @@ -22,6 +22,9 @@ on: - README.md - CHANGELOG.md pull_request: + paths-ignore: + - README.md + - CHANGELOG.md jobs: test: @@ -33,7 +36,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20 - - name: Install of node dependencies + - name: Install dependencies run: npm install - name: Run lint run: npm run lint diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8ea9786..32edc1b 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: Run lint run: npm run lint @@ -45,7 +45,7 @@ jobs: with: node-version: 20 registry-url: 'https://registry.npmjs.org' - - name: Install of node dependencies + - name: Install dependencies run: npm install - name: Publish to NPM run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 87b8386..b6d9209 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +### Changed +- **Breaking change** Drop support of Node.js 12. The version [5.3.5](https://github.com/reportportal/agent-js-cypress/releases/tag/v5.3.5) is the latest that supports it. +- 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`. + ## [5.3.5] - 2024-09-11 ### Added - `videoCompression` option. Allows compressing Cypress videos before uploading them to the ReportPortal. Check the readme for details. Thanks to [ashvinjaiswal](https://github.com/ashvinjaiswal). diff --git a/VERSION b/VERSION index e61ecd1..c9dbccf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.3.5 +5.3.6-SNAPSHOT diff --git a/lib/reporter.js b/lib/reporter.js index b9d5c64..33b47d2 100644 --- a/lib/reporter.js +++ b/lib/reporter.js @@ -15,6 +15,7 @@ */ const RPClient = require('@reportportal/client-javascript'); +const clientHelpers = require('@reportportal/client-javascript/lib/helpers'); const { entityType, logLevels, testItemStatuses, cucumberKeywordMap } = require('./constants'); const { @@ -91,7 +92,7 @@ class Reporter { this.tempLaunchId, Object.assign( { - endTime: new Date().valueOf(), + endTime: clientHelpers.now(), }, this.launchStatus && { status: this.launchStatus }, ), @@ -209,7 +210,7 @@ class Reporter { { message: `Video: '${title}' (${testFileName}.mp4)`, level: logLevels.INFO, - time: new Date().valueOf(), + time: clientHelpers.now(), }, file, ).promise; @@ -245,7 +246,7 @@ class Reporter { const sendFailedLogPromise = this.client.sendLog(tempTestId, { message: test.err.stack, level: logLevels.ERROR, - time: new Date().valueOf(), + time: clientHelpers.now(), }).promise; promiseErrorHandler(sendFailedLogPromise, 'Fail to save error log'); } @@ -291,7 +292,7 @@ class Reporter { const stepData = { name: keyword ? `${keyword} ${stepName}` : stepName, - startTime: this.client.helpers.now(), + startTime: clientHelpers.now(), type: entityType.STEP, codeRef, hasStats: false, @@ -331,7 +332,7 @@ class Reporter { if (testStepResult.status === testItemStatuses.FAILED) { this.sendLog(step.tempId, { - time: this.client.helpers.now(), + time: clientHelpers.now(), level: logLevels.ERROR, message: testStepResult.message, }); @@ -339,7 +340,7 @@ class Reporter { this.client.finishTestItem(step.tempId, { status: testStepResult.status, - endTime: this.client.helpers.now(), + endTime: clientHelpers.now(), }); this.cucumberSteps.delete(testStepId); @@ -377,7 +378,7 @@ class Reporter { this.sendLogOnFinishFailedItem(hook, tempId); const finishHookPromise = this.client.finishTestItem(tempId, { status: hook.status, - endTime: new Date().valueOf(), + endTime: clientHelpers.now(), }).promise; this.hooks.delete(hook.id); promiseErrorHandler(finishHookPromise, 'Fail to finish hook'); @@ -418,7 +419,7 @@ class Reporter { { message, level, - time: new Date().valueOf(), + time: clientHelpers.now(), }, file, ).promise; diff --git a/lib/utils/objectCreators.js b/lib/utils/objectCreators.js index 6d2209f..f1ada0f 100644 --- a/lib/utils/objectCreators.js +++ b/lib/utils/objectCreators.js @@ -15,6 +15,8 @@ */ const path = require('path'); +const clientHelpers = require('@reportportal/client-javascript/lib/helpers'); + const pjson = require('../../package.json'); const { entityType, hookTypesMap, testItemStatuses } = require('../constants'); const { getCodeRef } = require('./common'); @@ -89,7 +91,7 @@ const getLaunchStartObject = (config) => { rerun: config.reporterOptions.rerun, rerunOf: config.reporterOptions.rerunOf, mode: config.reporterOptions.mode, - startTime: new Date().valueOf(), + startTime: clientHelpers.now(), id: config.reporterOptions.launchId, }; }; @@ -97,7 +99,7 @@ const getLaunchStartObject = (config) => { const getSuiteStartInfo = (suite, testFileName) => ({ id: suite.id, title: suite.title, - startTime: new Date().valueOf(), + startTime: clientHelpers.now(), description: suite.description, codeRef: getCodeRef(suite.titlePath(), testFileName), parentId: !suite.root ? suite.parent.id : undefined, @@ -113,7 +115,7 @@ const getSuiteEndInfo = (suite) => { id: suite.id, status: failed ? testItemStatuses.FAILED : undefined, title: suite.title, - endTime: new Date().valueOf(), + endTime: clientHelpers.now(), }; }; @@ -144,7 +146,7 @@ const getTestInfo = (test, testFileName, status, err) => ({ const getTestStartObject = (test) => ({ type: entityType.STEP, name: test.title.slice(0, 255).toString(), - startTime: new Date().valueOf(), + startTime: clientHelpers.now(), codeRef: test.codeRef, attributes: [], }); @@ -152,7 +154,7 @@ const getTestStartObject = (test) => ({ const getTestEndObject = (testInfo, skippedIssue) => { const testEndObj = Object.assign( { - endTime: new Date().valueOf(), + endTime: clientHelpers.now(), status: testInfo.status, attributes: testInfo.attributes, description: testInfo.description, @@ -190,7 +192,7 @@ const getHookStartObject = (hook) => { const hookName = hook.title.replace(`"${hook.hookName}" hook:`, '').trim(); return { name: hookName, - startTime: new Date().valueOf(), + startTime: clientHelpers.now(), type: hookRPType, codeRef: hook.codeRef, }; diff --git a/package-lock.json b/package-lock.json index 706571f..a90cded 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,11 +6,11 @@ "packages": { "": { "name": "@reportportal/agent-js-cypress", - "version": "5.3.4", + "version": "5.3.5", "license": "Apache-2.0", "dependencies": { "@ffmpeg-installer/ffmpeg": "^1.1.0", - "@reportportal/client-javascript": "~5.1.4", + "@reportportal/client-javascript": "~5.3.0", "ffmpeg": "^0.0.4", "ffprobe-static": "^3.1.0", "fluent-ffmpeg": "^2.1.3", @@ -1394,19 +1394,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/@reportportal/client-javascript/node_modules/brace-expansion": { @@ -5902,6 +5903,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", @@ -6074,6 +6088,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 26fef95..5ab6975 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@reportportal/agent-js-cypress", "version": "5.3.5", - "description": "This agent helps Cypress to communicate with Report Portal", + "description": "This agent helps Cypress to communicate with ReportPortal", "main": "index.js", "scripts": { "lint": "eslint . --quiet", @@ -14,7 +14,7 @@ "url": "https://github.com/reportportal/agent-js-cypress" }, "dependencies": { - "@reportportal/client-javascript": "~5.1.4", + "@reportportal/client-javascript": "~5.3.0", "glob": "^9.3.5", "minimatch": "^3.1.2", "mocha": "^10.2.0", @@ -31,7 +31,7 @@ "/lib" ], "engines": { - "node": ">=12.x" + "node": ">=14.x" }, "license": "Apache-2.0", "devDependencies": { diff --git a/test/mergeLaunches.test.js b/test/mergeLaunches.test.js index 08aacea..39ffd2f 100644 --- a/test/mergeLaunches.test.js +++ b/test/mergeLaunches.test.js @@ -1,3 +1,19 @@ +/* + * 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. + */ + const mergeLaunches = require('./../lib/mergeLaunches'); const mergeLaunchesUtils = require('./../lib/mergeLaunchesUtils'); diff --git a/test/mergeLaunchesUtils.test.js b/test/mergeLaunchesUtils.test.js index 9fc2929..782e6ab 100644 --- a/test/mergeLaunchesUtils.test.js +++ b/test/mergeLaunchesUtils.test.js @@ -1,3 +1,19 @@ +/* + * 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. + */ + const fs = require('fs'); const mockFS = require('mock-fs'); diff --git a/test/mock/mocks.js b/test/mock/mocks.js index c805f24..bb4f891 100644 --- a/test/mock/mocks.js +++ b/test/mock/mocks.js @@ -1,4 +1,20 @@ -const currentDate = new Date().valueOf(); +/* + * 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. + */ + +const currentDate = '2024-09-23T12:20:59.392987Z'; class RPClient { constructor(config) { @@ -27,10 +43,6 @@ class RPClient { this.sendLog = jest.fn().mockReturnValue({ promise: Promise.resolve('ok'), }); - - this.helpers = { - now: jest.fn().mockReturnValue(currentDate), - }; } } diff --git a/test/reporter.test.js b/test/reporter.test.js index e0284e8..9340d17 100644 --- a/test/reporter.test.js +++ b/test/reporter.test.js @@ -1,6 +1,23 @@ +/* + * 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. + */ + const mockFS = require('mock-fs'); const path = require('path'); -const { getDefaultConfig, RPClient, MockedDate, RealDate, currentDate } = require('./mock/mocks'); +const helpers = require('@reportportal/client-javascript/lib/helpers'); +const { getDefaultConfig, RPClient, currentDate } = require('./mock/mocks'); const Reporter = require('./../lib/reporter'); const { entityType } = require('../lib/constants'); @@ -35,6 +52,7 @@ const mockCurrentTestTempInfoWithStep = { }; describe('reporter script', () => { + jest.spyOn(helpers, 'now').mockReturnValue(currentDate); let reporter; beforeAll(() => { @@ -44,15 +62,12 @@ describe('reporter script', () => { }); beforeEach(() => { - global.Date = jest.fn(MockedDate); - Object.assign(Date, RealDate); reporter.config = getDefaultConfig(); }); afterEach(() => { reporter.testItemIds.clear(); reporter.tempLaunchId = undefined; - global.Date = RealDate; jest.clearAllMocks(); }); diff --git a/test/utils/attachments.test.js b/test/utils/attachments.test.js index d50c42b..8a4d418 100644 --- a/test/utils/attachments.test.js +++ b/test/utils/attachments.test.js @@ -1,3 +1,19 @@ +/* + * 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. + */ + const fsPromises = require('fs/promises'); const mockFs = require('mock-fs'); const path = require('path'); diff --git a/test/utils/common.test.js b/test/utils/common.test.js index bb4e63e..fc5213b 100644 --- a/test/utils/common.test.js +++ b/test/utils/common.test.js @@ -1,3 +1,19 @@ +/* + * 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. + */ + const { getCodeRef } = require('../../lib/utils/common'); describe('common utils', () => { diff --git a/test/utils/objectCreators.test.js b/test/utils/objectCreators.test.js index 955a8ef..9fbfbc2 100644 --- a/test/utils/objectCreators.test.js +++ b/test/utils/objectCreators.test.js @@ -1,4 +1,21 @@ +/* + * 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. + */ + const path = require('path'); +const helpers = require('@reportportal/client-javascript/lib/helpers'); const { getSystemAttributes, getLaunchStartObject, @@ -18,21 +35,13 @@ const pjson = require('../../package.json'); const sep = path.sep; -const { RealDate, MockedDate, currentDate, getDefaultConfig } = require('../mock/mocks'); +const { currentDate, getDefaultConfig } = require('../mock/mocks'); const { testItemStatuses, entityType } = require('../../lib/constants'); describe('object creators', () => { - const testFileName = `test${sep}example.spec.js`; - - beforeEach(() => { - global.Date = jest.fn(MockedDate); - Object.assign(Date, RealDate); - }); + jest.spyOn(helpers, 'now').mockReturnValue(currentDate); - afterEach(() => { - jest.clearAllMocks(); - global.Date = RealDate; - }); + const testFileName = `test${sep}example.spec.js`; describe('getAgentInfo', () => { it('getAgentInfo: should contain version and name properties', () => { diff --git a/test/utils/specCountCalculation.test.js b/test/utils/specCountCalculation.test.js index 538c62f..687e49e 100644 --- a/test/utils/specCountCalculation.test.js +++ b/test/utils/specCountCalculation.test.js @@ -1,3 +1,19 @@ +/* + * 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. + */ + const mock = require('mock-fs'); const path = require('path'); const { diff --git a/version_fragment b/version_fragment index 9eb7b90..acb503f 100644 --- a/version_fragment +++ b/version_fragment @@ -1 +1 @@ -patch +minor