From c41b3483b94308131f3339f3897fc5ab439f0352 Mon Sep 17 00:00:00 2001 From: uid11 Date: Thu, 21 Nov 2024 05:17:36 +0300 Subject: [PATCH] FI-1512 fix: add pack option and page property `navigationTimeout` --- README.md | 7 +++--- autotests/packs/allTests.ts | 3 +-- .../E2edReportExample/E2edReportExample.ts | 4 ++-- src/Page.ts | 22 ++++++++--------- src/actions/navigateToUrl.ts | 11 ++++----- src/actions/pages/history/backPageHistory.ts | 4 +--- .../pages/history/forwardPageHistory.ts | 4 +--- src/actions/pages/history/goPageHistory.ts | 4 +--- src/actions/setHeadersAndNavigateToUrl.ts | 10 +++++--- src/actions/waitFor/waitForNewTab.ts | 2 +- src/actions/waitFor/waitForStartOfPageLoad.ts | 2 +- src/config.ts | 2 +- src/types/config/config.ts | 1 - src/types/config/ownE2edConfig.ts | 12 ++++------ src/types/index.ts | 1 + src/types/internal.ts | 1 + src/types/navigation.ts | 7 ++++++ src/utils/config/assertUserlandPack.ts | 24 +++++++------------ 18 files changed, 56 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index d633a78b..bd4d4dd7 100644 --- a/README.md +++ b/README.md @@ -325,16 +325,15 @@ If the mapping returns `undefined`, the log entry is not skipped, but is printed `your-project/autotests/bin/runDocker.sh` (until the test passes). For example, if it is equal to three, the test will be run no more than three times. +`navigationTimeout: number`: default timeout for navigation to url +(`navigateToPage`, `navigateToUrl` actions) in milliseconds. + `overriddenConfigFields: PlaywrightTestConfig | null`: if not `null`, then this value will override fields of internal Playwright config. `packTimeout: number`: timeout (in millisecond) for the entire pack of tests (tasks). If the test pack takes longer than this timeout, the pack will fail with the appropriate error. -`pageStabilizationInterval: number`: after navigating to the page, `e2ed` will wait until -the page is stable for the specified time in millisecond, and only after that it will consider the page loaded. -This parameter can be overridden on a specific page instance. - `pathToScreenshotsDirectoryForReport: string | null`: path to the directory where screenshots will be stored for displaying them in the HTML report. This path must be either relative (from the HTML report file) or absolute (i.e. with http/https protocol). diff --git a/autotests/packs/allTests.ts b/autotests/packs/allTests.ts index f06b6e4d..be8a3699 100644 --- a/autotests/packs/allTests.ts +++ b/autotests/packs/allTests.ts @@ -65,10 +65,9 @@ export const pack: Pack = { mapLogPayloadInLogFile, mapLogPayloadInReport, maxRetriesCountInDocker: 3, + navigationTimeout: 6_000, overriddenConfigFields: null, packTimeout: packTimeoutInMinutes * msInMinute, - pageRequestTimeout: 7_000, - pageStabilizationInterval: 500, pathToScreenshotsDirectoryForReport: './screenshots', port1: 1337, port2: 1338, diff --git a/autotests/pageObjects/pages/E2edReportExample/E2edReportExample.ts b/autotests/pageObjects/pages/E2edReportExample/E2edReportExample.ts index ef5d36f6..4772930a 100644 --- a/autotests/pageObjects/pages/E2edReportExample/E2edReportExample.ts +++ b/autotests/pageObjects/pages/E2edReportExample/E2edReportExample.ts @@ -37,6 +37,8 @@ export class E2edReportExample extends Page { readonly navigationRetriesButtonSelected: Selector = this.navigationRetriesButton.filterByLocatorParameter('selected', 'true'); + override readonly navigationTimeout = 5_000; + /** * Cookies that we set (additionally) on a page before navigating to it. */ @@ -47,8 +49,6 @@ export class E2edReportExample extends Page { */ readonly pageRequestHeaders: StringHeaders | undefined; - override readonly pageStabilizationInterval = 600; - /** * Test run button. */ diff --git a/src/Page.ts b/src/Page.ts index 105282dd..a7d77e94 100644 --- a/src/Page.ts +++ b/src/Page.ts @@ -10,7 +10,7 @@ import {reloadDocument} from './utils/document'; import {getPlaywrightPage} from './useContext'; import type {PageRoute} from './PageRoute'; -import type {AsyncVoid, PageClassTypeArgs, Url} from './types/internal'; +import type {AsyncVoid, NavigateToUrlOptions, PageClassTypeArgs, Url} from './types/internal'; /** * Abstract page with base methods. @@ -33,17 +33,15 @@ export abstract class Page { readonly maxIntervalBetweenRequestsInMs: number; /** - * Immutable page parameters. + * Default timeout for navigation to url (`navigateToPage`, `navigateToUrl` actions) in milliseconds. + * The default value is taken from the corresponding field of the pack config. */ - readonly pageParams: PageParams; + readonly navigationTimeout: number; /** - * After navigating to the page, `e2ed` will wait until - * the page is stable for the specified time in millisecond, - * and only after that it will consider the page loaded. - * The default value is taken from the corresponding field of the pack config. + * Immutable page parameters. */ - readonly pageStabilizationInterval: number; + readonly pageParams: PageParams; constructor(...args: PageClassTypeArgs) { const [createPageToken, pageParams] = args; @@ -56,12 +54,12 @@ export abstract class Page { this.pageParams = pageParams as PageParams; const { - pageStabilizationInterval, + navigationTimeout, waitForAllRequestsComplete: {maxIntervalBetweenRequestsInMs}, } = getFullPackConfig(); this.maxIntervalBetweenRequestsInMs = maxIntervalBetweenRequestsInMs; - this.pageStabilizationInterval = pageStabilizationInterval; + this.navigationTimeout = navigationTimeout; } /** @@ -114,8 +112,8 @@ export abstract class Page { /** * Navigates to the page by url. */ - navigateToPage(url: Url): Promise { - return navigateToUrl(url, {skipLogs: true}); + navigateToPage(url: Url, options?: NavigateToUrlOptions): Promise { + return navigateToUrl(url, {skipLogs: true, timeout: this.navigationTimeout, ...options}); } /** diff --git a/src/actions/navigateToUrl.ts b/src/actions/navigateToUrl.ts index 1c380d9a..e5aec3ce 100644 --- a/src/actions/navigateToUrl.ts +++ b/src/actions/navigateToUrl.ts @@ -2,16 +2,15 @@ import {LogEventType} from '../constants/internal'; import {getPlaywrightPage} from '../useContext'; import {log} from '../utils/log'; -import type {Page} from '@playwright/test'; - -import type {Url} from '../types/internal'; - -type Options = Readonly<{skipLogs?: boolean} & Parameters[1]>; +import type {NavigateToUrlOptions, Url} from '../types/internal'; /** * Navigate to the `url` (without waiting of interface stabilization). */ -export const navigateToUrl = async (url: Url, options: Options = {}): Promise => { +export const navigateToUrl = async ( + url: Url, + options: NavigateToUrlOptions = {}, +): Promise => { const {skipLogs = false} = options; if (skipLogs !== true) { diff --git a/src/actions/pages/history/backPageHistory.ts b/src/actions/pages/history/backPageHistory.ts index 11cc75a2..fd78ed58 100644 --- a/src/actions/pages/history/backPageHistory.ts +++ b/src/actions/pages/history/backPageHistory.ts @@ -2,8 +2,6 @@ import {LogEventType} from '../../../constants/internal'; import {createClientFunction} from '../../../createClientFunction'; import {log} from '../../../utils/log'; -import {waitForInterfaceStabilization} from '../../waitFor'; - import type {AnyPageClassType} from '../../../types/internal'; const backPageHistoryClient = createClientFunction(() => window.history.back(), { @@ -22,5 +20,5 @@ export const backPageHistory = async (page: InstanceType): Pro await backPageHistoryClient(); - await waitForInterfaceStabilization(page.pageStabilizationInterval); + await page.waitForPageLoaded(); }; diff --git a/src/actions/pages/history/forwardPageHistory.ts b/src/actions/pages/history/forwardPageHistory.ts index 537cfe9e..1c5dc468 100644 --- a/src/actions/pages/history/forwardPageHistory.ts +++ b/src/actions/pages/history/forwardPageHistory.ts @@ -2,8 +2,6 @@ import {LogEventType} from '../../../constants/internal'; import {createClientFunction} from '../../../createClientFunction'; import {log} from '../../../utils/log'; -import {waitForInterfaceStabilization} from '../../waitFor'; - import type {AnyPageClassType} from '../../../types/internal'; const forwardPageHistoryClient = createClientFunction(() => window.history.forward(), { @@ -22,5 +20,5 @@ export const forwardPageHistory = async (page: InstanceType): await forwardPageHistoryClient(); - await waitForInterfaceStabilization(page.pageStabilizationInterval); + await page.waitForPageLoaded(); }; diff --git a/src/actions/pages/history/goPageHistory.ts b/src/actions/pages/history/goPageHistory.ts index 51e1a563..bde827c3 100644 --- a/src/actions/pages/history/goPageHistory.ts +++ b/src/actions/pages/history/goPageHistory.ts @@ -2,8 +2,6 @@ import {LogEventType} from '../../../constants/internal'; import {createClientFunction} from '../../../createClientFunction'; import {log} from '../../../utils/log'; -import {waitForInterfaceStabilization} from '../../waitFor'; - import type {AnyPageClassType} from '../../../types/internal'; const goPageHistoryClient = createClientFunction((delta: number) => window.history.go(delta), { @@ -25,5 +23,5 @@ export const goPageHistory = async ( await goPageHistoryClient(delta); - await waitForInterfaceStabilization(page.pageStabilizationInterval); + await page.waitForPageLoaded(); }; diff --git a/src/actions/setHeadersAndNavigateToUrl.ts b/src/actions/setHeadersAndNavigateToUrl.ts index 7bade993..a0401bec 100644 --- a/src/actions/setHeadersAndNavigateToUrl.ts +++ b/src/actions/setHeadersAndNavigateToUrl.ts @@ -7,12 +7,16 @@ import {applyHeadersMapper} from '../utils/requestHooks'; import {navigateToUrl} from './navigateToUrl'; -import type {MapOptions, Url} from '../types/internal'; +import type {MapOptions, NavigateToUrlOptions, Url} from '../types/internal'; /** * Navigate to the url and map custom response and request headers. */ -export const setHeadersAndNavigateToUrl = async (url: Url, options: MapOptions): Promise => { +export const setHeadersAndNavigateToUrl = async ( + url: Url, + options: MapOptions, + navigateToUrlOptions?: NavigateToUrlOptions, +): Promise => { const {mapRequestHeaders, mapResponseHeaders} = options; const page = getPlaywrightPage(); @@ -52,5 +56,5 @@ export const setHeadersAndNavigateToUrl = async (url: Url, options: MapOptions): ); } - await navigateToUrl(url, {skipLogs: true}); + await navigateToUrl(url, {skipLogs: true, ...navigateToUrlOptions}); }; diff --git a/src/actions/waitFor/waitForNewTab.ts b/src/actions/waitFor/waitForNewTab.ts index 2e71f131..7ac5a63c 100644 --- a/src/actions/waitFor/waitForNewTab.ts +++ b/src/actions/waitFor/waitForNewTab.ts @@ -17,7 +17,7 @@ export const waitForNewTab = async (options?: Options): Promise => { const startTimeInMs = Date.now() as UtcTimeInMs; const context = getPlaywrightPage().context(); - const timeout = options?.timeout ?? getFullPackConfig().pageRequestTimeout; + const timeout = options?.timeout ?? getFullPackConfig().navigationTimeout; const page = await context.waitForEvent('page', {timeout}); diff --git a/src/actions/waitFor/waitForStartOfPageLoad.ts b/src/actions/waitFor/waitForStartOfPageLoad.ts index e9977e61..83d9513b 100644 --- a/src/actions/waitFor/waitForStartOfPageLoad.ts +++ b/src/actions/waitFor/waitForStartOfPageLoad.ts @@ -18,7 +18,7 @@ export const waitForStartOfPageLoad = async (options?: Options): Promise => const startTimeInMs = Date.now() as UtcTimeInMs; const page = getPlaywrightPage(); - const timeout = options?.timeout ?? getFullPackConfig().pageRequestTimeout; + const timeout = options?.timeout ?? getFullPackConfig().navigationTimeout; let urlObject: URL | undefined; let wasCalled = false; diff --git a/src/config.ts b/src/config.ts index 3078e746..a54a1cd8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -102,7 +102,7 @@ const useOptions: PlaywrightTestConfig['use'] = { headless: isLocalRun ? userlandPack.enableHeadlessMode : true, isMobile: userlandPack.enableMobileDeviceMode, launchOptions: {args: [...userlandPack.browserFlags]}, - navigationTimeout: userlandPack.pageRequestTimeout, + navigationTimeout: userlandPack.navigationTimeout, trace: 'retain-on-failure', userAgent: userlandPack.userAgent, viewport: {height: userlandPack.viewportHeight, width: userlandPack.viewportWidth}, diff --git a/src/types/config/config.ts b/src/types/config/config.ts index 10592056..7a678538 100644 --- a/src/types/config/config.ts +++ b/src/types/config/config.ts @@ -60,7 +60,6 @@ export type UserlandPackWithoutDoBeforePack< > = Readonly<{ assertionTimeout: number; concurrency: number; - pageRequestTimeout: number; port1: number; port2: number; selectorTimeout: number; diff --git a/src/types/config/ownE2edConfig.ts b/src/types/config/ownE2edConfig.ts index 98e6786d..911791c1 100644 --- a/src/types/config/ownE2edConfig.ts +++ b/src/types/config/ownE2edConfig.ts @@ -158,6 +158,11 @@ export type OwnE2edConfig< */ maxRetriesCountInDocker: number; + /** + * Default timeout for navigation to url (`navigateToPage`, `navigateToUrl` actions) in milliseconds. + */ + navigationTimeout: number; + /** * If not `null`, then this value will override fields of internal Playwright config. */ @@ -169,13 +174,6 @@ export type OwnE2edConfig< */ packTimeout: number; - /** - * After navigating to the page, `e2ed` will wait until the page is stable - * for the specified time in millisecond, and only after that it will consider the page loaded. - * This parameter can be overridden on a specific page instance. - */ - pageStabilizationInterval: number; - /** * Path to the directory where screenshots will be stored for displaying them in the HTML report. * This path must be either relative (from the HTML report file) or absolute (i.e. with http/https protocol). diff --git a/src/types/index.ts b/src/types/index.ts index c7fb99b0..7e3c0b4b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -38,6 +38,7 @@ export type { } from './http'; export type {KeyboardPressKey} from './keyboard'; export type {ApiMockFunction} from './mockApiRoute'; +export type {NavigateToUrlOptions} from './navigation'; export type { AnyPageClassType, NavigateToOrAssertPageArgs, diff --git a/src/types/internal.ts b/src/types/internal.ts index fedb3afe..76edc861 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -70,6 +70,7 @@ export type { export type {ApiMockFunction} from './mockApiRoute'; /** @internal */ export type {ApiMockState} from './mockApiRoute'; +export type {NavigateToUrlOptions} from './navigation'; /** @internal */ export type {NavigationDelay} from './navigation'; export type { diff --git a/src/types/navigation.ts b/src/types/navigation.ts index 092c2776..4b9b14ac 100644 --- a/src/types/navigation.ts +++ b/src/types/navigation.ts @@ -1,3 +1,10 @@ +import type {Page} from '@playwright/test'; + +/** + * Options for `navigateToUrl` action. + */ +export type NavigateToUrlOptions = Readonly<{skipLogs?: boolean} & Parameters[1]>; + /** * Object with information for navigation delay. * @internal diff --git a/src/utils/config/assertUserlandPack.ts b/src/utils/config/assertUserlandPack.ts index 2e988f9d..1551acda 100644 --- a/src/utils/config/assertUserlandPack.ts +++ b/src/utils/config/assertUserlandPack.ts @@ -27,27 +27,19 @@ export const assertUserlandPack = (userlandPack: UserlandPack): void => { logParams, ); - assertNumberIsPositiveInteger( - userlandPack.packTimeout, - 'packTimeout is positive integer', - logParams, - ); - - if (userlandPack.pageRequestTimeout !== 0) { + if (userlandPack.navigationTimeout !== 0) { assertNumberIsPositiveInteger( - userlandPack.pageRequestTimeout, - 'pageRequestTimeout is positive integer', + userlandPack.navigationTimeout, + 'navigationTimeout is positive integer', logParams, ); } - if (userlandPack.pageStabilizationInterval !== 0) { - assertNumberIsPositiveInteger( - userlandPack.pageStabilizationInterval, - 'pageStabilizationInterval is positive integer', - logParams, - ); - } + assertNumberIsPositiveInteger( + userlandPack.packTimeout, + 'packTimeout is positive integer', + logParams, + ); assertNumberIsPositiveInteger(userlandPack.port1, 'port1 is positive integer', logParams); assertNumberIsPositiveInteger(userlandPack.port2, 'port2 is positive integer', logParams);