From b51d97d6da3f53feb0fd64ebabaccb848306e12d Mon Sep 17 00:00:00 2001 From: uid11 Date: Wed, 2 Sep 2026 14:18:29 +0300 Subject: [PATCH] PRO-21872 feat: add function `readJsonDataFromHtmlReport` to public API feat: export function for getting reference of scenarios and tests fix: use correct expires in getCookies/setCookies actions --- src/actions/getCookies.ts | 13 +++- src/actions/setCookies.ts | 11 ++- src/types/http/cookie.ts | 3 + src/types/http/http.ts | 2 +- src/types/index.ts | 15 ++++- src/types/internal.ts | 7 +- src/types/report.ts | 12 ++-- src/types/testRun.ts | 1 - src/utils/index.ts | 3 + src/utils/parse/codeReport/fillTestErrors.ts | 15 +++-- .../parse/codeReport/getFullStepDefinition.ts | 13 ++++ .../getScenarioStepsWithReference.ts | 13 ++-- .../parse/codeReport/getStepReference.ts | 10 +++ .../codeReport/getTestStepsWithReference.ts | 9 ++- src/utils/parse/codeReport/index.ts | 2 + src/utils/parse/index.ts | 9 ++- .../getJsonDataBeginning.ts | 15 +++++ .../parse/readJsonDataFromHtmlReport/index.ts | 1 + .../readJsonData.ts | 34 ++++++++++ .../readJsonDataFromHtmlReport.ts | 67 +++++++++++++++++++ .../readPartialJsonData.ts | 51 ++++++++++++++ .../report/client/readPartOfJsonReportData.ts | 4 +- src/utils/report/render/JsonData.tsx | 8 +-- 23 files changed, 282 insertions(+), 36 deletions(-) create mode 100644 src/utils/parse/codeReport/getFullStepDefinition.ts create mode 100644 src/utils/parse/codeReport/getStepReference.ts create mode 100644 src/utils/parse/readJsonDataFromHtmlReport/getJsonDataBeginning.ts create mode 100644 src/utils/parse/readJsonDataFromHtmlReport/index.ts create mode 100644 src/utils/parse/readJsonDataFromHtmlReport/readJsonData.ts create mode 100644 src/utils/parse/readJsonDataFromHtmlReport/readJsonDataFromHtmlReport.ts create mode 100644 src/utils/parse/readJsonDataFromHtmlReport/readPartialJsonData.ts diff --git a/src/actions/getCookies.ts b/src/actions/getCookies.ts index 3c3519cd..3915580c 100644 --- a/src/actions/getCookies.ts +++ b/src/actions/getCookies.ts @@ -5,6 +5,8 @@ import {assertValueIsDefined} from '../utils/asserts'; import type {Cookie} from '../types/internal'; +const msInSecond = 1_000; + /** * Returns page's cookies with the specified cookies parameters. * If there are no cookies parameters, returns all the cookies. @@ -24,8 +26,15 @@ export const getCookies = async ( await step( logMessage, async () => { - const page = getPlaywrightPage(); - const allCookies = await page.context().cookies(page.url()); + const playwrightPage = getPlaywrightPage(); + const playwrightCookies = await playwrightPage.context().cookies(playwrightPage.url()); + + // Playwright's `cookies` returns `expires` in unix time in seconds (`-1` for session cookies), + // while `Cookie` type uses milliseconds (as in `Date.now()`). + const allCookies: readonly Cookie[] = playwrightCookies.map(({expires, ...cookie}) => ({ + ...cookie, + ...(expires !== -1 ? {expires: expires * msInSecond} : undefined), + })); if (parameters.length === 0) { cookies = allCookies; diff --git a/src/actions/setCookies.ts b/src/actions/setCookies.ts index 48a02f96..e18c6a54 100644 --- a/src/actions/setCookies.ts +++ b/src/actions/setCookies.ts @@ -4,6 +4,8 @@ import {getPlaywrightPage} from '../useContext'; import type {Cookie} from '../types/internal'; +const msInSecond = 1_000; + /** * Set cookies with the specified cookies parameters. */ @@ -15,7 +17,14 @@ export const setCookies = (cookies: readonly Cookie[]): Promise => const browserContext = page.context(); - await browserContext.addCookies(cookies); + // Playwright's `addCookies` expects `expires` in unix time in seconds, + // while `Cookie` type uses milliseconds (as in `Date.now()`). + const playwrightCookies = cookies.map(({expires, ...cookie}) => ({ + ...cookie, + ...(expires !== undefined ? {expires: Math.round(expires / msInSecond)} : undefined), + })); + + await browserContext.addCookies(playwrightCookies); }, {payload: {cookies}, type: LogEventType.InternalAction}, ); diff --git a/src/types/http/cookie.ts b/src/types/http/cookie.ts index 7eefa662..0a6ac1f4 100644 --- a/src/types/http/cookie.ts +++ b/src/types/http/cookie.ts @@ -5,6 +5,9 @@ import type {Brand} from '../brand'; */ export type Cookie = Readonly<{ domain?: string; + /** + * Unix time in milliseconds (as in `Date.now()`). + */ expires?: number; httpOnly?: boolean; name: string; diff --git a/src/types/http/http.ts b/src/types/http/http.ts index 04556962..6e9c78ff 100644 --- a/src/types/http/http.ts +++ b/src/types/http/http.ts @@ -41,7 +41,7 @@ export type MapOptions = Readonly<{ * HTTP method. */ export type Method = - 'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE'; + 'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'QUERY' | 'TRACE'; /** * Object with query (search) part of the url, or query string itself. diff --git a/src/types/index.ts b/src/types/index.ts index 326dc4db..01e92205 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -91,7 +91,7 @@ export type { PropertyDescriptor, PropertyKey, } from './properties'; -export type {LiteReport, LiteRetry} from './report'; +export type {HtmlReportJsonData, LiteReport, LiteRetry, ReportClientData} from './report'; export type { ApiRouteClassType, ApiRouteClassTypeWithGetParamsFromUrl, @@ -104,6 +104,19 @@ export type {PackageInfo, StartInfo} from './startInfo'; export type {StepBody, StepOptions} from './step'; export type {StringForLogs} from './string'; export type {Tab} from './tab'; +export type { + FullTestRun, + LiteTestRun, + RejectTestRun, + RunError, + RunHash, + RunId, + TestFn, + TestFunction, + TestOptions, + TestRun, + TestStaticOptions, +} from './testRun'; export type {MergeTuples, TupleRest} from './tuples'; export type { CloneWithoutUndefinedProperties, diff --git a/src/types/internal.ts b/src/types/internal.ts index 6f82c23d..721f97a5 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -134,16 +134,14 @@ export type { PropertyDescriptor, PropertyKey, } from './properties'; -export type {LiteReport, LiteRetry} from './report'; +export type {HtmlReportJsonData, LiteReport, LiteRetry, ReportClientData} from './report'; /** @internal */ export type { - ReportClientData, ReportClientState, ReportData, Retry, RetryButtonProps, RetryProps, - ScriptJsonData, TestRunButtonProps, } from './report'; /** @internal */ @@ -171,6 +169,7 @@ export type {Tab} from './tab'; /** @internal */ export type {InternalTab} from './tab'; export type { + FullTestRun, LiteTestRun, RejectTestRun, RunError, @@ -183,7 +182,7 @@ export type { TestStaticOptions, } from './testRun'; /** @internal */ -export type {CompletedTestRun, FullTestRun, RunTest, Test, TestUnit} from './testRun'; +export type {CompletedTestRun, RunTest, Test, TestUnit} from './testRun'; export type {MergeTuples, TupleRest} from './tuples'; export type { CloneWithoutUndefinedProperties, diff --git a/src/types/report.ts b/src/types/report.ts index a87d4ab4..83395314 100644 --- a/src/types/report.ts +++ b/src/types/report.ts @@ -15,6 +15,11 @@ import type { TestMetaPlaceholder, } from './userland'; +/** + * JSON data in `'); + + if (index === -1) { + throw new Error('Cannot find end of