diff --git a/src/types/events.ts b/src/types/events.ts index 25c05796..2a5cd84a 100644 --- a/src/types/events.ts +++ b/src/types/events.ts @@ -52,6 +52,7 @@ export type Onlog = () => void; export type TestRunEvent = Readonly<{ logEvents: readonly LogEvent[]; onlog: Onlog; + outputDirectoryName: string; reject: RejectTestRun; retryIndex: number; runId: RunId; diff --git a/src/types/internal.ts b/src/types/internal.ts index 6ee376d6..fedb3afe 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -137,7 +137,7 @@ export type { TestStaticOptions, } from './testRun'; /** @internal */ -export type {FullTestRun, Test} from './testRun'; +export type {FullTestRun, RunTest, Test, TestUnit} from './testRun'; export type {MergeTuples, TupleRest} from './tuples'; export type { CloneWithoutUndefinedProperties, diff --git a/src/types/testRun.ts b/src/types/testRun.ts index d60c51e4..130eb487 100644 --- a/src/types/testRun.ts +++ b/src/types/testRun.ts @@ -1,4 +1,4 @@ -import type {PlaywrightTestArgs} from '@playwright/test'; +import type {PlaywrightTestArgs, TestInfo} from '@playwright/test'; import type {TestRunStatus} from '../constants/internal'; import type {E2edError} from '../utils/error'; @@ -11,6 +11,25 @@ import type {TestFilePath} from './paths'; import type {StringForLogs} from './string'; import type {TestMetaPlaceholder} from './userland'; +/** + * Full test run object result of userland hooks (like mainParams and runHash). + * @internal + */ +export type FullTestRun = Readonly<{mainParams: string; runHash: RunHash}> & TestRun; + +/** + * Lite test run object with userland metadata. + */ +export type LiteTestRun = Readonly<{ + endTimeInMs: UtcTimeInMs; + mainParams: string; + runError: RunError; + runHash: RunHash; + startTimeInMs: UtcTimeInMs; + status: TestRunStatus; +}> & + TestStaticOptions; + /** * Reject test run. */ @@ -32,6 +51,16 @@ export type RunHash = Brand; */ export type RunId = Brand; +/** + * Playwright's function for run test. + * @internal + */ +export type RunTest = ( + this: void, + testController: PlaywrightTestArgs, + testInfo: TestInfo, +) => Promise; + /** * Test function itself. */ @@ -87,20 +116,15 @@ export type TestFunction = ( ) => void; /** - * Lite test run object with userland metadata. - */ -export type LiteTestRun = Readonly<{ - endTimeInMs: UtcTimeInMs; - mainParams: string; - runError: RunError; - runHash: RunHash; - startTimeInMs: UtcTimeInMs; - status: TestRunStatus; -}> & - TestStaticOptions; - -/** - * Full test run object result of userland hooks (like mainParams and runHash). + * Test unit for run. * @internal */ -export type FullTestRun = Readonly<{mainParams: string; runHash: RunHash}> & TestRun; +export type TestUnit = Readonly<{ + beforeRetryTimeout: number | undefined; + outputDirectoryName: string; + retryIndex: number; + runId: RunId; + testController: PlaywrightTestArgs; + testFn: TestFn; + testStaticOptions: TestStaticOptions; +}>; diff --git a/src/utils/events/registerEndTestRunEvent.ts b/src/utils/events/registerEndTestRunEvent.ts index e5e433e0..6624067c 100644 --- a/src/utils/events/registerEndTestRunEvent.ts +++ b/src/utils/events/registerEndTestRunEvent.ts @@ -32,6 +32,7 @@ export const registerEndTestRunEvent = async (endTestRunEvent: EndTestRunEvent): logEvents, name, options, + outputDirectoryName, retryIndex, runLabel, status: originalStatus, @@ -77,6 +78,7 @@ export const registerEndTestRunEvent = async (endTestRunEvent: EndTestRunEvent): logEvents, name, options, + outputDirectoryName, retryIndex, runError, runId, diff --git a/src/utils/test/beforeTest.ts b/src/utils/test/beforeTest.ts index 29e870ec..ac7241cf 100644 --- a/src/utils/test/beforeTest.ts +++ b/src/utils/test/beforeTest.ts @@ -14,24 +14,10 @@ import {getUserlandHooks} from '../userland'; import {getTestFnAndReject} from './getTestFnAndReject'; -import type { - RunId, - TestFn, - TestRunEvent, - TestStaticOptions, - UtcTimeInMs, -} from '../../types/internal'; +import type {TestRunEvent, TestUnit, UtcTimeInMs} from '../../types/internal'; import {test} from '@playwright/test'; -type Options = Readonly<{ - beforeRetryTimeout: number | undefined; - retryIndex: number; - runId: RunId; - testFn: TestFn; - testStaticOptions: TestStaticOptions; -}>; - const additionToPlaywrightTestTimeout = 500; /** @@ -40,11 +26,12 @@ const additionToPlaywrightTestTimeout = 500; */ export const beforeTest = ({ beforeRetryTimeout, + outputDirectoryName, retryIndex, runId, testFn, testStaticOptions, -}: Options): void => { +}: TestUnit): void => { const {options} = testStaticOptions; setMeta(options.meta); @@ -88,6 +75,7 @@ export const beforeTest = ({ ...testStaticOptions, logEvents: [], onlog, + outputDirectoryName, reject, retryIndex, runId, diff --git a/src/utils/test/getOutputDirectoryName.ts b/src/utils/test/getOutputDirectoryName.ts new file mode 100644 index 00000000..f4f3fd40 --- /dev/null +++ b/src/utils/test/getOutputDirectoryName.ts @@ -0,0 +1,19 @@ +import {INTERNAL_REPORTS_DIRECTORY_PATH} from '../../constants/internal'; + +import {assertValueIsTrue} from '../asserts'; + +/** + * Get output directory name of test in `internal` directory. + * @internal + */ +export const getOutputDirectoryName = (outputDirectory: string): string => { + const indexOfInternalDirectory = outputDirectory.indexOf(INTERNAL_REPORTS_DIRECTORY_PATH); + + assertValueIsTrue(indexOfInternalDirectory > 0, 'indexOfInternalDirectory greater than 0', { + outputDirectory, + }); + + return outputDirectory.slice( + INTERNAL_REPORTS_DIRECTORY_PATH.length + indexOfInternalDirectory + 1, + ); +}; diff --git a/src/utils/test/getRunTest.ts b/src/utils/test/getRunTest.ts index 207cd6eb..28c28fba 100644 --- a/src/utils/test/getRunTest.ts +++ b/src/utils/test/getRunTest.ts @@ -6,17 +6,14 @@ import {assertValueIsDefined} from '../asserts'; import {afterErrorInTest} from './afterErrorInTest'; import {afterTest} from './afterTest'; import {beforeTest} from './beforeTest'; +import {getOutputDirectoryName} from './getOutputDirectoryName'; import {getShouldRunTest} from './getShouldRunTest'; import {getTestStaticOptions} from './getTestStaticOptions'; import {preparePage} from './preparePage'; import {runTestFn} from './runTestFn'; import {waitBeforeRetry} from './waitBeforeRetry'; -import type {PlaywrightTestArgs, TestInfo} from '@playwright/test'; - -import type {Test, TestStaticOptions} from '../../types/internal'; - -type RunTest = (testController: PlaywrightTestArgs, testInfo: TestInfo) => Promise; +import type {RunTest, Test, TestStaticOptions, TestUnit} from '../../types/internal'; /** * Get complete run test function by the complete test options. @@ -24,7 +21,7 @@ type RunTest = (testController: PlaywrightTestArgs, testInfo: TestInfo) => Promi */ export const getRunTest = (test: Test): RunTest => - ({context, page, request}: PlaywrightTestArgs, testInfo: TestInfo): Promise => { + ({context, page, request}, testInfo): Promise => { const runTest = async (): Promise => { const retryIndex = testInfo.retry + 1; const runId = createRunId(test, retryIndex); @@ -48,11 +45,21 @@ export const getRunTest = clearPage = await preparePage(page); - beforeTest({beforeRetryTimeout, retryIndex, runId, testFn: test.testFn, testStaticOptions}); - const testController = {context, page, request}; - await runTestFn({beforeRetryTimeout, retryIndex, runId, testController, testStaticOptions}); + const testUnit: TestUnit = { + beforeRetryTimeout, + outputDirectoryName: getOutputDirectoryName(testInfo.outputDir), + retryIndex, + runId, + testController, + testFn: test.testFn, + testStaticOptions, + }; + + beforeTest(testUnit); + + await runTestFn(testUnit); } catch (error) { hasRunError = true; unknownRunError = error; diff --git a/src/utils/test/runTestFn.ts b/src/utils/test/runTestFn.ts index 52aa55e4..58a37fb5 100644 --- a/src/utils/test/runTestFn.ts +++ b/src/utils/test/runTestFn.ts @@ -9,20 +9,10 @@ import {getDurationWithUnits} from '../getDurationWithUnits'; import {log} from '../log'; import {getPromiseWithResolveAndReject} from '../promise'; -import type {PlaywrightTestArgs} from '@playwright/test'; - -import type {RunId, TestStaticOptions} from '../../types/internal'; +import type {TestUnit} from '../../types/internal'; const delayForTestRunPromiseResolutionAfterTestTimeoutInMs = 100; -type Options = Readonly<{ - beforeRetryTimeout: number | undefined; - retryIndex: number; - runId: RunId; - testController: PlaywrightTestArgs; - testStaticOptions: TestStaticOptions; -}>; - /** * Runs test function with reject in test run event. * @internal @@ -33,7 +23,7 @@ export const runTestFn = async ({ runId, testController, testStaticOptions, -}: Options): Promise => { +}: TestUnit): Promise => { const {status, testFnWithReject} = getTestRunEvent(runId); const testTimeout = getTestTimeout();