feat: expose browser-side function waits across Stagehand SDKs
Merged
SU
8d ago+1303+1303+0123456789012345678901234567890123456789-73-73-01234567890123456789
why
Expose browser-side predicate waiting consistently across Stagehand SDKs, without transport polling.
This is PR2 of 2, stacked directly on #3179 (amel/wait-for-function-extension). Polling, navigation recovery, and cleanup live in the parent; merge it first using the repository’s stacked-PR handoff rules.
what changed
- Register
page.wait_for_functionand connect the extension controller/runtime to the internal implementation. - Add TypeScript
waitForFunction(expression, arg?, options?), Pythonwait_for_function(expression, *, arg, polling, timeout), and GoWaitForFunction. As in Playwright, an expression that evaluates to a function is invoked on each poll and receives the optional JSONarg. - Preserve JSON result keys through opaque wire metadata, with roundtrip coverage for own
toString,constructor, andhasOwnPropertykeys in nested payloads. No browser-handle API is introduced. - Provide RAF/interval polling and no deadline by default in all three SDKs; pass
timeoutto bound a wait. An omitted or zero timeout also drops the client response deadline. - Derive internal wait options from the canonical protocol contract. Reuse the TypeScript argument serializer. Model Go’s string-or-number polling option through its existing typed-union generator extension point.
- Regenerate protocol/models/final ZIP and include docs plus minor release entries for all five packages.
Reviewed with the requested Thermo-Nuclear Code Quality Review skill, including an independent cross-review of SDK boundaries. No SDK polling loops, duplicated serializer, broad generator abstraction, or new 1,000-line file crossing.
test plan
- 9 real-Chrome tests passed, including main-world access, async predicates, custom intervals, error propagation, navigation recovery, concurrent waits, and timeout-zero closure.
- 79 extension/selector tests and 788 protocol/docs/SDK/architecture guards passed.
- 184 Python tests plus Ruff/type checks passed; Go SDK package tests passed.
- Follow-up review: 26 wire tests passed; canonical option types emit unchanged JavaScript, and the rebuilt extension ZIP remains identical.
- Extension/SDK/protocol typechecks, dependency-ordered build, generated-model/ZIP checks, formatting, lint, and
git diff --checkpassed.