import { type CachedStorageState } from "./hydrateStorageState"; import { type AuthCredentials, type ResolveCredentialsOptions } from "./resolveCredentials"; export type { AuthCredentials }; export type LoginOptions = ResolveCredentialsOptions; /** Matches HostLayout's `hideMenuForUrls` — routes where MainMenu is not rendered. */ export declare const HIDE_MENU_URL_FRAGMENTS: readonly ["/marketplace", "/auth/", "/terms"]; export declare const MAIN_MENU_READY_TIMEOUT_MS = 180000; /** * Default budget for the first login on a worker to wait for the branch host * to answer `GET /env` with 200. The deploy job only waits for ArgoCD health, * which does not cover the Emissary/Envoy route for a freshly created feature * branch, so the host can return 404 for several minutes after the deploy job * is green. Override per run with {@link ENV_READY_TIMEOUT_ENV_VAR}. */ export declare const ENV_READY_TIMEOUT_MS = 300000; /** * Environment variable that overrides {@link ENV_READY_TIMEOUT_MS} (in * milliseconds). Useful for local runs against a fixed host where a long wait * only delays the inevitable failure. */ export declare const ENV_READY_TIMEOUT_ENV_VAR = "NX_E2E_ENV_READY_TIMEOUT_MS"; export declare const ENV_READY_POLL_INTERVAL_MS = 5000; /** Gap between reloads of a manager-classic session document that did not load. */ export declare const SESSION_DOCUMENT_RETRY_DELAY_MS = 1000; export declare const MAIN_MENU_READY_SELECTOR = "[data-testid=\"mainMenu\"]:not(:has([data-testid=\"mainMenuItems-skeleton\"], [data-testid=\"menu-items-skeleton\"]))"; type MainMenuReadinessInput = { readonly selector: string; readonly fragments: ReadonlyArray; }; type MainMenuWaitPage = { waitForFunction: (pageFunction: (input: MainMenuReadinessInput) => boolean, input: MainMenuReadinessInput, options?: { timeout?: number; }) => Promise; }; type TestTimeoutInfo = { timeout: number; setTimeout: (timeout: number) => void; }; /** * Grows the running test's timeout by `budgetMs` so a readiness wait cannot * eat into the test's own budget. A timeout of 0 means "unlimited" in * Playwright and is left untouched. */ export declare const extendTestTimeout: (testInfo: TestTimeoutInfo | undefined, budgetMs: number) => void; /** * Gives the feature-branch session handoff its own readiness budget. * * Root cause (GLU-2631): after `/env` answers, a feature-branch host can still * serve a failed session document or stay on `manager-classic` for a while. * Those waits share {@link MAIN_MENU_READY_TIMEOUT_MS} after `/env` is ready, * so the test timeout is extended by that budget before the slow path. The * `/env` wait extends it by its own budget. A host that is not a feature * branch is unchanged. */ export declare const reserveFeatureBranchLoginBudget: (testInfo?: TestTimeoutInfo) => void; /** Returns whether the main menu is ready or intentionally hidden for the current route. */ export declare const isMainMenuReady: ({ selector, fragments }: MainMenuReadinessInput) => boolean; /** * Waits until Manager's main menu is rendered without a loading skeleton, or * until the browser is on a HostLayout hide-menu route (marketplace / auth / * terms) where the menu is intentionally absent. */ export declare const waitForMainMenuReady: (page: MainMenuWaitPage, testInfo?: TestTimeoutInfo) => Promise; type EnvReadyResponse = { status: () => number; }; type EnvReadyRequestContext = { get: (url: string, options?: { timeout?: number; }) => Promise; }; /** Thrown by {@link waitForEnvReady} when `/env` did not answer 200 inside its budget. */ export declare class EnvReadyTimeoutError extends Error { /** @param message the budget, host and last status/error, as reported by the poller */ constructor(message: string); } /** * Polls `GET /env` on the branch host until it returns 200 and resolves with * that response, untouched. Non-200 responses (404 while Envoy has no route * yet, 503 while pods start) and timed-out requests are retried every * {@link ENV_READY_POLL_INTERVAL_MS} until the budget ({@link ENV_READY_TIMEOUT_MS}, * or {@link ENV_READY_TIMEOUT_ENV_VAR}) is spent. The resulting error names the * host and the last status/error so the failure is attributable to the * environment rather than to the test. Connection-level failures fail fast. */ export declare const waitForEnvReady: (context: EnvReadyRequestContext, baseURL: string | undefined, testInfo?: TestTimeoutInfo) => Promise; export interface TrackunitBaseFixtures { login: (options?: LoginOptions) => Promise; } /** * Worker-scoped, in-memory cache of authenticated `storageState` snapshots, * keyed by `(baseURL, username)`. Implementation detail of the `login` * fixture — exposed on the fixtures object so Playwright can manage its * lifecycle, but prefixed with `_` to signal "don't touch from tests". */ export interface LoginCacheFixtures { _loginCache: Map; } /** * Each worker is its own Node process, so a `Map` is sufficient — no * cross-worker sharing concerns, no disk I/O, no cleanup needed. The cache * dies with the worker, which is the desired behaviour: a fresh `nx run` * always starts with empty caches. */ export declare const test: import("@playwright/test").TestType; type LoginJsonBody = { auth?: { url?: unknown; }; sessionToken?: string; }; type LoginEnvResponse = EnvReadyResponse & { json: () => Promise; }; type LoginRequestContext = { get: (url: string, options?: { timeout?: number; }) => Promise; post: (url: string, options: { data: { username: string; password: string; options: { warnBeforePasswordExpired: boolean; multiOptionalFactorEnroll: boolean; }; }; headers: { "Content-Type": "application/json"; }; timeout: number; }) => Promise<{ ok: () => boolean; json: () => Promise; }>; dispose: () => Promise; }; type SessionDocument = { ok: () => boolean; }; type OktaLoginPage = { goto: (url: string, options?: { timeout?: number; }) => Promise; waitForURL: (url: (url: URL) => boolean, options?: { timeout?: number; }) => Promise; locator: (selector: string) => { waitFor: (options: { state: "visible"; timeout: number; }) => Promise; }; }; /** * Performs the slow path: wait for the branch host to serve `/env`, hit Okta's * `/api/v1/authn`, redeem the `sessionToken` via the manager-classic redirect, * and wait for the host layout to render. Factored out so the cache hit/miss * branches read clearly. * * `createRequestContext`, `now`, and `sleep` are injectable so a unit test can * drive the session handoff without a browser or a real three-minute wait. */ export declare const performOktaLogin: ({ page, baseURL, credentials, testInfo, createRequestContext, now, sleep: pause, }: { page: OktaLoginPage; baseURL: string | undefined; credentials: AuthCredentials; testInfo?: TestTimeoutInfo; createRequestContext?: (baseURL: string | undefined) => Promise; /** Injectable clock. Production uses `Date.now`. The handoff budget is {@link MAIN_MENU_READY_TIMEOUT_MS}. */ now?: () => number; /** Injectable pause between session document reloads. Production waits on the event loop. */ sleep?: (ms: number) => Promise; }) => Promise; export { expect } from "@playwright/test";