From ac9e970b7ca6eeb270823166316e8bcf2082aca4 Mon Sep 17 00:00:00 2001 From: Bam6ycha <84175555+Bam6ycha@users.noreply.github.com> Date: Tue, 8 Aug 2023 16:42:10 +0500 Subject: [PATCH] EPMRPP-8485 || Test is finished when test exceed timeout (#116) * EPMRPP-8485 || Test-is-finished-when-test-exceed-timeout * EPMRPP-84855 || Adjust onTestEnd logic We need to remove result.status === timedOut because in case we have expect().toPass({timeout:5_000}) and global timeout set to 20_000 status !== timedOut. .toPass retries expect until it pass or timer exceeds. If timer exceeds test has result === failed, but playwright itself doesn't invoke onStepEnd method. * EPMRPP-84855 || Code review fixes - 1 * EPMRPP-84855 || Add unit tests --- CHANGELOG.md | 4 +- .../reporter/finishTestItemReporting.spec.ts | 44 +++++++++++++++++++ src/reporter.ts | 16 +++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5284c8..4ab5250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ -## [5.1.2] - 2023-06-23 +### Fixed +- [#111](https://github.com/reportportal/agent-js-playwright/issues/111) Test is not finished when `expect().toPass()` exceed test timeout +- ## [5.1.2] - 2023-06-23 ### Changed - `token` configuration option was renamed to `apiKey` to maintain common convention. - `@reportportal/client-javascript` bumped to version `5.0.12`. diff --git a/src/__tests__/reporter/finishTestItemReporting.spec.ts b/src/__tests__/reporter/finishTestItemReporting.spec.ts index 5661896..46ed03a 100644 --- a/src/__tests__/reporter/finishTestItemReporting.spec.ts +++ b/src/__tests__/reporter/finishTestItemReporting.spec.ts @@ -18,6 +18,7 @@ import { RPReporter } from '../../reporter'; import { mockConfig } from '../mocks/configMock'; import { RPClientMock } from '../mocks/RPClientMock'; import { FinishTestItemObjType } from '../../models'; +import { STATUSES } from '../../constants'; const rootSuite = 'rootSuite'; const suiteName = 'suiteName'; @@ -145,4 +146,47 @@ describe('finish test reporting', () => { expect(reporter.client.finishTestItem).toHaveBeenCalledTimes(0); expect(reporter.testItems.size).toBe(0); }); + + test('client.finishTestItem should finish all unfinished steps and delete them from the this.nestedSteps', async () => { + reporter.nestedSteps = new Map([[`${testCase.id}/testTitle`, { name: 'name', id: '1214r1' }]]); + + // @ts-ignore + await reporter.onTestEnd({ ...testCase, outcome: () => 'expected' }, {}); + + expect(reporter.nestedSteps.has(`${testCase.id}/testTitle`)).toBe(false); + }); + test('client.finishTestItem should finish all unfinished steps and finish test steps with status INTERRUPTED if result.status === "timedOut"', async () => { + const result = { + status: 'timedOut', + }; + + reporter.nestedSteps = new Map([[`${testCase.id}/testTitle`, { name: 'name', id: '1214r1' }]]); + + // @ts-ignore + await reporter.onTestEnd({ ...testCase, outcome: () => 'expected' }, result); + + const finishStepObject: FinishTestItemObjType = { + endTime: reporter.client.helpers.now(), + status: STATUSES.INTERRUPTED, + }; + + expect(reporter.client.finishTestItem).toHaveBeenCalledWith('1214r1', finishStepObject); + }); + test('client.finishTestItem should finish all unfinished steps and finish test steps with status FAILED if result.status === "failed"', async () => { + const result = { + status: 'failed', + }; + + reporter.nestedSteps = new Map([[`${testCase.id}/testTitle`, { name: 'name', id: '1214r1' }]]); + + // @ts-ignore + await reporter.onTestEnd({ ...testCase, outcome: () => 'expected' }, result); + + const finishStepObject: FinishTestItemObjType = { + endTime: reporter.client.helpers.now(), + status: STATUSES.FAILED, + }; + + expect(reporter.client.finishTestItem).toHaveBeenCalledWith('1214r1', finishStepObject); + }); }); diff --git a/src/reporter.ts b/src/reporter.ts index b128fd8..152be5a 100644 --- a/src/reporter.ts +++ b/src/reporter.ts @@ -491,6 +491,22 @@ export class RPReporter implements Reporter { }); testDescription = (description || '').concat(`\n\`\`\`error\n${stacktrace}\n\`\`\``); } + + [...this.nestedSteps.entries()].forEach(([key, value]) => { + if (key.includes(test.id)) { + const { id: stepId } = value; + const itemObject = { + status: result.status === 'timedOut' ? STATUSES.INTERRUPTED : STATUSES.FAILED, + endTime: this.client.helpers.now(), + }; + + const { promise } = this.client.finishTestItem(stepId, itemObject); + this.addRequestToPromisesQueue(promise, 'Failed to finish nested step.'); + + this.nestedSteps.delete(key); + } + }); + const finishTestItemObj: FinishTestItemObjType = { endTime: this.client.helpers.now(), status,