fix(browser): scope evaluateWithArgs declarations in an IIFE#1707
Open
MatrixA wants to merge 1 commit into
Open
fix(browser): scope evaluateWithArgs declarations in an IIFE#1707MatrixA wants to merge 1 commit into
MatrixA wants to merge 1 commit into
Conversation
`browser upload` would throw `SyntaxError: Identifier 'markerAttr' has already been declared` on the second invocation against the same page — even after a navigation. Root cause: `BasePage.evaluateWithArgs` prepended raw `const <key> = ...` statements to the caller-supplied expression and sent the whole script to `Runtime.evaluate`. Because the upload command always passes a fixed key set (`markerAttr`, `markerValue`), and the bridge reuses the same execution context, the second call hit a duplicate top-level `const`. Wrap the declarations and the caller expression in an IIFE so the bindings are block-scoped. `wrapForEval` already detects this shape as already-IIFE and forwards it unchanged. The body is parenthesized and returned, preserving Promise return values (CDP awaits via `awaitPromise: true`). Added a regression test that asserts the emitted script is IIFE-wrapped with the declarations inside.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
opencli browser <session> upload <ref> <file>throws on the secondinvocation against the same page:
Reloading the page does not clear the error — the same execution context is reused.
Minimal repro
Root cause
BasePage.uploadFilescallsevaluateWithArgswith{ markerAttr, markerValue }.evaluateWithArgs(src/browser/base-page.ts:160-170) emits:wrapForEvalcorrectly classifies this as a "bare expression" and sends it as-is toRuntime.evaluate. Theconstdeclarations land at script top level. With the bridgereusing the same execution context, the second call hits a duplicate-binding
SyntaxError. Same applies to every otherevaluateWithArgscallsite that uses fixedkeys —
uploadjust happens to be the easiest to trip because it always reusesmarkerAttr/markerValue.Fix
Wrap the declarations and the caller-supplied expression in an IIFE so the bindings
are block-scoped.
wrapForEvalalready recognizes this shape as already-IIFE andforwards it unchanged. The body is parenthesized and
returned so Promise returnvalues are preserved (CDP awaits via
awaitPromise: true).Verification
BasePage.evaluateWithArgs > wraps declarations and body in an IIFE …asserts the emitted script is IIFE-wrapped and
returns the inner expression.npx vitest run --project unit→ 1139 passed, 1 skipped.npm run typecheck→ clean.browser uploadcalls on the samesession no longer throw the
markerAttrSyntaxError. (Whatever underlyingDOM.setFileInputFilespermission errors a page may still surface are independentof this fix.)
Notes
evaluateWithArgscallsites pass an expression ((() => …)()or(async () => …)()), so thereturn (${js});wrapper is safe for every caller.evaluateWithArgsis updated to call out the IIFE requirement so futurerefactors don't silently regress it.