fix(sdk-ts): preserve JSON keys in script arguments

Draft
YU
4d ago
+59-10

why

Function arguments for page.evaluate(), page.addInitScript(), and context.addInitScript() are validated as JSON but currently embedded in the generated source as an object literal. An own __proto__ JSON key then receives JavaScript object-literal semantics instead of remaining data. For example, a parsed JSON object containing that key loses it when the callback serializes its argument again; nested keys are affected too.

This was found by inspection and reproduced against the actual SDK modules, rather than a production browser session.

what changed

  • Reuse the existing parsedArgument helper, already used by waitForFunction, for the two function-argument normalization paths. It reconstructs JSON data with JSON.parse and preserves omitted arguments as undefined.
  • Add regression coverage for own keys, nested arrays/objects, primitives, omitted arguments, and escaped/Unicode strings. Raw script strings and validation of non-JSON values stay unchanged.
  • Update three wrapper expectations for the generated source and add a patch Changeset for the TypeScript SDK only. No protocol or extension changes.

test plan

  • New own-key regressions against unchanged main: 3 failed, 6 passed in the initial nine-case suite; patched 9 passed. The final suite adds ordinary JSON/escaping coverage.
  • Final SDK unit tests: 628 passed across 27 files, excluding browser-runtime/integration and the package contract. Two focused test files: 104 passed.
  • Independent review: 10 failed, 16 passed on baseline; 26 passed after the fix. It exercises the actual generated source with node:vm, including nested keys, prototype identity, escaping, omitted arguments and validation errors.
  • A separate diagnostic calls the real public Page/BrowserContext methods with only the transport replaced by a test seam, then executes their emitted source. Baseline fails; all three patched paths pass. This is not a real-browser E2E test.
  • SDK TypeScript checking, scoped Oxlint/Oxfmt, Changeset validation and its seven utility tests, and git diff --check pass.
  • The extension production build passes. SDK production tsdown was killed with exit 137; a resource-limited retry exhausted its JavaScript heap (exit 134). The package contract therefore still fails because the SDK distribution was not built. The full attempted SDK unit run was 628 passed, 1 failed; that failed package check is not counted as passing.

Node 24.22.1, pinned workspace dependencies. Full monorepo checks, Python/Go suites, real-browser tests and live provider tests were not run.

AI assistance was used for implementation and testing, with a separate automated review. No human review is claimed.


Summary by cubic

Fixes function arguments passed to page.evaluate(), page.addInitScript(), and context.addInitScript() losing own __proto__ JSON keys. Arguments are now embedded via JSON.parse(...) instead of as object literals, so serialized JSON keeps its keys exactly.

  • Adds regression tests for own keys, nested values, primitives, omitted arguments, and escaped/Unicode strings.
  • Adds a patch Changeset for the TypeScript SDK.