fix(web): reject connect without a cdpEndpoint resolver at config load

Merged
TH
10d ago
+78-17

A web({ connect }) with reconnectEndpoint but no cdpEndpoint passed config load and failed every attempt with ENGINE_FAILURE: connection failed: resolve is not a function: the persistent attach called the undefined resolver (packages/web/src/surface.ts:449 hands it to packages/web/src/cdp-recovery.ts:52). A cdpEndpoint given as a string did the same at init, as browser connect failed: source.resolve is not a function.

  • web() validates connect in one place now, validateConnect in packages/web/src/engine.ts: not a plain object, no cdpEndpoint, or a cdpEndpoint or reconnectEndpoint that is not a function is INVALID_CONFIG at config load. The missing-key message says reconnectEndpoint only reconnects to the browser cdpEndpoint provisioned.
  • Messages name the value's kind (got a string) and never echo it: a CDP URL can carry a session token.
  • docs/reference/web.mdx: the connect paragraph says cdpEndpoint is required and both keys are resolvers, and drops the resolver call timing that read as if one browser served the worker. The recovery section opens with the fresh-browser-per-attempt rule and points to the setup-test session for reusing a sign-in across files (ENG-945); the engine mechanics it described are gone, nine lines shorter than main. skills/e2e/references/setup.md carries the same contract.

Closes ENG-986, ENG-945.

Verified

Ran it locally: yes

  • testbed, a scratch config selecting each connect shape with ENG986_CASE=missing|string|reused, e2e run --config e2e.scratch-eng986.config.ts, built packages on both sides:
shapemainthis branch
{ reconnectEndpoint } onlyevery test ENGINE_FAILURE: connection failed: resolve is not a functionINVALID_CONFIG at load, no test runs
{ cdpEndpoint: 'ws://…' } (a string)every test ENGINE_FAILURE: browser connect failed: source.resolve is not a functionINVALID_CONFIG at load, no test runs
both resolvers returning one headless Chromiumsecond test CDP recovery failed: cdpEndpoint reused a browser from a previous attemptsame, by design, now stated up front in the docs
 ERROR  configuration error INVALID_CONFIG (config)
web({ connect }) requires cdpEndpoint, the resolver that provisions the browser: (signal) => url; reconnectEndpoint only reconnects to the browser cdpEndpoint provisioned
 ERROR  configuration error INVALID_CONFIG (config)
web({ connect: { cdpEndpoint } }) must be a resolver function (signal) => url, got a string