import type { PlaywrightTestConfig } from '@playwright/test'; /** * The serializable subset of a Playwright `webServer` entry that the readiness * gate needs. Passed back from the config-eval child over IPC. */ export interface ResolvedWebServer { command: string; url?: string; port?: number; reuseExistingServer?: boolean; ignoreHTTPSErrors?: boolean; timeout?: number; waitsForOutput?: boolean; hasEnv?: boolean; } export declare function normalizeWebServers(webServer: PlaywrightTestConfig['webServer']): ResolvedWebServer[]; /** The values of the probe variables set in an env. */ export type ProbeEnv = Record; export declare function pickProbeEnv(env: NodeJS.ProcessEnv): ProbeEnv; /** * The webServer entries a config evaluation resolved and the probe env it left * behind, which is what Playwright's own probe runs under: the config runs * before the probe and can write env (through `dotenv`, say) that the readiness * task, its own target in its own process, never sees. */ export interface ConfigEvaluation { webServers: ResolvedWebServer[]; probeEnv: ProbeEnv; } /** * Loads a Playwright config in this process, hands it to `consume`, and * returns the consumed value with the probe env the evaluation left in * `process.env`, then puts `process.env` back the way it was: the task and * gate dotenv files expand against it, and a later env comparison has to see * the graph-time env, not whatever the last config wrote. `consume` must be * synchronous and must not let the config object escape: a config can expose * getters that read env it set while loading, so every read has to happen * before the restore. Loads are serialized because createNodes evaluates * configs concurrently and a concurrent load's writes would be misattributed. * A client env applied mid-load (the daemon forwards it as it arrives) is * re-applied over the restored env; restoring the pre-load values alone would * revert it. * * `ambientEnv` is a snapshot of the restored env, taken while still holding * the load lock. Task-env reconstruction and comparison after this returns * must base on it rather than on the live `process.env`: the lock is released * on return, so a sibling load's transient writes can be visible in the live * env by then and would be read as ambient. */ export declare function loadConfigWithProbeEnv(configPath: string, consume: (config: T) => R): Promise<{ consumed: R; probeEnv: ProbeEnv; ambientEnv: NodeJS.ProcessEnv; }>; /** * The env var names whose values would make the readiness gate probe `servers` * differently than the consuming task's own Playwright probe: `taskEnv` is the * env that probe runs under (the task env after its config loaded) and * `gateEnv` the env the gate target runs under. The gate is its own target, so * it loads its own dotenv files, not the consumer's, and it never loads the * config: a task-scoped or config-written proxy exclusion or CA bundle never * reaches it, and a gate probing through the wrong route can fail where * Playwright would pass. A non-empty result means the gate cannot reproduce * the task's probe and must not be inferred. * * Both probes follow redirects, so as soon as one server probes a url the * routes for every protocol and host are compared, not only the route the * configured url takes: an `https_proxy` for an http url or a `no_proxy` entry * for another host can still decide how a redirect target is reached. * `NODE_EXTRA_CA_CERTS` is compared unless every url server sets * `ignoreHTTPSErrors`, which turns verification off on both sides for every * hop, except that the tunnel to an https proxy is verified with the process * defaults either way. With `legacyProxiedTls` (an installed Playwright below * 1.59.0, whose probe never verifies the origin behind a proxy tunnel, and * neither does the gate on that version) it is also left out while every * https hop can only take such a tunnel: an http proxy on the https route, no * https proxy on the http route, and no `no_proxy` entry that could send a * redirect target direct. `NODE_TLS_REJECT_UNAUTHORIZED` only reaches that * tunnel to an https proxy, since every request sets `rejectUnauthorized` * itself, and only its `'0'` state counts. With `npmConfigProxy` (an installed * Playwright below 1.59.0, whose probe reads npm's `npm_config_*` proxy * variables ahead of the standard ones, as the gate does on that version) those * variables route the probe and are compared too. */ export declare function getProbeEnvDivergence(servers: Array<{ url?: string; ignoreHTTPSErrors?: boolean; }>, taskEnv: NodeJS.ProcessEnv, gateEnv: NodeJS.ProcessEnv, legacyProxiedTls?: boolean, npmConfigProxy?: boolean): string[]; /** * Whether the task env a chain would run with differs from the graph-time * ambient env. Only a difference can change how the config resolves, so an * identical env skips the (expensive) child evaluation entirely. `ambientEnv` * is the locked snapshot loadConfigWithProbeEnv returned, not the live * `process.env`, which a concurrent load may be mutating. */ export declare function taskEnvDivergesFromAmbient(taskEnv: NodeJS.ProcessEnv, ambientEnv: NodeJS.ProcessEnv): boolean; /** * The messages the config-eval worker sends over IPC. Tagged so the parent can * tell them apart from anything else on the channel: the user's config module * runs in the child and can itself call `process.send` during evaluation, and * such a message must not settle the resolution. */ export type WebserverConfigWorkerMessage = ({ type: 'webserver-config-result'; } & ConfigEvaluation) | { type: 'webserver-config-error'; error: string; }; type ChildEval = (configFilePath: string, workspaceRoot: string, env: NodeJS.ProcessEnv) => Promise; /** * Evaluates `configFilePath`'s `webServer` addresses under `taskEnv`, bounded by * the concurrency cap. Used only when the env diverges from ambient. */ export declare function resolveWebServersUnderEnv(configFilePath: string, workspaceRoot: string, taskEnv: NodeJS.ProcessEnv): Promise; export declare function _setChildEval(impl: ChildEval | null): void; export declare function _setWorkerScriptPath(path: string | null): void; export {};