diff --git a/.eslintrc b/.eslintrc index d71ab5a..3b8c3c6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,7 +8,8 @@ "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 2018, - "sourceType": "module" + "sourceType": "module", + "project": "./tsconfig.eslint.json" }, "globals": { "expectAsync": true @@ -19,8 +20,6 @@ "jasmine": true }, "rules": { - "indent": ["error", 2], - "max-len": ["error", 120], "valid-jsdoc": ["error", { "requireReturn": false }], "consistent-return": 0, "@typescript-eslint/no-plusplus": 0, @@ -35,6 +34,7 @@ "@typescript-eslint/dot-notation": 0, "@typescript-eslint/ban-ts-comment": 0, "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/no-floating-promises": 2, "max-classes-per-file": 0 } } diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..4a82b9c --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @AmsterGet @Bam6ycha diff --git a/CHANGELOG.md b/CHANGELOG.md index e660e8d..32fd5f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### Added +- `Promise.allSettled` polyfill to support NodeJS 10 +### Fixed +- Reporting is down on error with collect request on reporting start +- Can not read property `realId` of undefined during reporting, resolves [#99](https://github.com/reportportal/agent-js-playwright/issues/99) ## [5.0.13] - 2023-08-28 ### Added diff --git a/VERSION b/VERSION index 2713f14..5e95ca2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.0.13 +5.0.14-SNAPSHOT diff --git a/lib/polyfills.js b/lib/polyfills.js new file mode 100644 index 0000000..f59b5c6 --- /dev/null +++ b/lib/polyfills.js @@ -0,0 +1,19 @@ +//! Was added to support NodeJS 10. +if (!Promise.allSettled) { + Promise.allSettled = function (promises) { + return Promise.all( + promises.map((p) => + Promise.resolve(p).then( + (value) => ({ + status: 'fulfilled', + value, + }), + (error) => ({ + status: 'rejected', + reason: error, + }), + ), + ), + ); + }; +} diff --git a/lib/report-portal-client.js b/lib/report-portal-client.js index e95eb46..b34ddac 100644 --- a/lib/report-portal-client.js +++ b/lib/report-portal-client.js @@ -7,6 +7,7 @@ const { getClientConfig } = require('./commons/config'); const Statistics = require('../statistics/statistics'); const { EVENT_NAME } = require('../statistics/constants'); const { RP_STATUSES } = require('./constants/statuses'); +require('./polyfills'); const MULTIPART_BOUNDARY = Math.floor(Math.random() * 10000000000).toString(); @@ -115,11 +116,11 @@ class RPClient { return RestClient.request('GET', url, {}, { headers: this.headers }); } - triggerStatisticsEvent() { + async triggerStatisticsEvent() { if (process.env.REPORTPORTAL_CLIENT_JS_NO_ANALYTICS) { return; } - this.statistics.trackEvent(); + await this.statistics.trackEvent(); } /** @@ -206,7 +207,7 @@ class RPClient { ); }); } - this.triggerStatisticsEvent(); + this.triggerStatisticsEvent().catch(console.error); return { tempId, promise: this.map[tempId].promiseStart, @@ -581,32 +582,38 @@ class RPClient { itemObj.finishSend = true; this.logDebug(`Finish all children for test item with tempId ${itemTempId}`); - Promise.all( + Promise.allSettled( itemObj.children.map((itemId) => this.map[itemId] && this.map[itemId].promiseFinish), - ).then( - () => { + ) + .then((results) => { + if (this.debug) { + results.forEach((result, index) => { + if (result.status === 'fulfilled') { + this.logDebug( + `Successfully finish child with tempId ${itemObj.children[index]} + of test item with tempId ${itemTempId}`, + ); + } else { + this.logDebug( + `Failed to finish child with tempId ${itemObj.children[index]} + of test item with tempId ${itemTempId}`, + ); + } + }); + } + this.cleanMap(itemObj.children); - this.logDebug( - `All children for test item with tempId ${itemTempId} successfully finished.`, - ); + this.logDebug(`Finish test item with tempId ${itemTempId}`, finishTestItemRQ); this.finishTestItemPromiseStart( itemObj, itemTempId, Object.assign(finishTestItemData, { launchUuid: this.launchUuid }), ); - }, - () => { - this.cleanMap(itemObj.children); + }) + .catch(() => { this.logDebug(`Error finish children of test item with tempId ${itemTempId}`); - this.logDebug(`Finish test item with tempId ${itemTempId}`, finishTestItemRQ); - this.finishTestItemPromiseStart( - itemObj, - itemTempId, - Object.assign(finishTestItemData, { launchUuid: this.launchUuid }), - ); - }, - ); + }); return { tempId: itemTempId, diff --git a/spec/statistics.spec.js b/spec/statistics.spec.js index 3979316..277eef1 100644 --- a/spec/statistics.spec.js +++ b/spec/statistics.spec.js @@ -72,5 +72,17 @@ describe('Statistics', () => { expect(axios.post).toHaveBeenCalledOnceWith(url, baseRequestValidation); }); + + it('Should properly handle errors if any', async () => { + const statistics = new Statistics(eventName, agentParams); + const errorMessage = 'Error message'; + + spyOn(axios, 'post').and.throwError(errorMessage); + spyOn(console, 'error'); + + await statistics.trackEvent(); + + expect(console.error).toHaveBeenCalledWith(errorMessage); + }); }); }); diff --git a/statistics/statistics.js b/statistics/statistics.js index 076d7e7..56042ee 100644 --- a/statistics/statistics.js +++ b/statistics/statistics.js @@ -28,20 +28,24 @@ class Statistics { } async trackEvent() { - const requestBody = { - client_id: await getClientId(), - events: [ - { - name: this.eventName, - params: this.eventParams, - }, - ], - }; + try { + const requestBody = { + client_id: await getClientId(), + events: [ + { + name: this.eventName, + params: this.eventParams, + }, + ], + }; - await axios.post( - `https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_KEY}`, - requestBody, - ); + await axios.post( + `https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_KEY}`, + requestBody, + ); + } catch (error) { + console.error(error.message); + } } }