[fix]: close parity gaps across SDKs for local browser launching - #2864
Conversation
🦋 Changeset detectedLatest commit: a7bccfa The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
All reported issues were addressed across 7 files
Architecture diagram
sequenceDiagram
participant App as SDK Consumer
participant SDK as Python / Go / TypeScript SDK
participant Launch as Local Chrome Launcher
participant Env as Environment and Platform
participant Port as Loopback Port
participant Profile as Chrome Profile
participant Chrome as Chrome Process
participant CDP as Chrome CDP Endpoint
Note over App,CDP: Local browser launch runtime flow shared across SDKs
App->>SDK: Launch local browser(options)
SDK->>Launch: Validate viewport, scale factor, proxy, and launch options
alt Invalid options
Launch-->>SDK: Validation error
SDK-->>App: Reject launch before resource creation
else Valid options
Launch->>Env: Resolve executable
alt Explicit executable is configured
Env-->>Launch: Use explicit executable
else CHROME_PATH is configured
Env-->>Launch: Use CHROME_PATH executable
else No explicit path
Env-->>Launch: Search platform candidates in shared order
end
Launch->>Port: Inspect requested loopback port
alt Automatic port
Port-->>Launch: Available ephemeral port
else Explicit port available
Port-->>Launch: Confirm requested port
else Explicit port occupied
Port-->>Launch: Address-in-use error
Launch-->>SDK: Focused occupied-port error
SDK-->>App: Reject before profile creation or process spawn
end
Launch->>Profile: Resolve profile ownership
alt Caller-provided profile
Profile->>Profile: Create directory recursively
Profile-->>Launch: Preserve caller-owned profile
else SDK-created temporary profile
Profile-->>Launch: SDK-owned profile marked for cleanup
end
Launch->>Launch: Build ordered shared Chrome flags
Note over Launch,Chrome: Includes viewport, remote debugging port, profile path, and about:blank
opt Linux process runs as root
Launch->>Launch: Disable Chromium sandbox
end
Launch->>Chrome: Spawn executable with flags
alt Spawn fails
Chrome-->>Launch: Process creation error
Launch->>Profile: Remove SDK-owned profile
Launch-->>SDK: Combined launch and cleanup error if cleanup fails
SDK-->>App: Reject launch
else Spawn succeeds
loop Until CDP is ready
Launch->>CDP: GET /json/version
alt Valid response with non-empty webSocketDebuggerUrl
CDP-->>Launch: CDP readiness
else Not ready or malformed response
CDP-->>Launch: Retry after polling interval
end
Chrome-->>Launch: Process exit status
end
alt Chrome exits or initialization is cancelled before readiness
Launch->>Chrome: Terminate owned process
Launch->>Profile: Remove SDK-owned profile
Launch-->>SDK: Launch failure and cleanup result
SDK-->>App: Reject launch
else Ready
Launch-->>SDK: Resolved browser with CDP URL and close callback
SDK-->>App: Return local browser
end
end
end
App->>SDK: Close local browser
SDK->>Launch: Run shared close task
alt Unix platform
Launch->>Chrome: Graceful process-group termination
opt Process group does not exit in time
Launch->>Chrome: Forced process-group termination
end
else Windows platform
Launch->>Chrome: taskkill /T
opt Process tree remains
Launch->>Chrome: taskkill /T /F
end
end
Launch->>Profile: Remove SDK-owned profile
Profile-->>Launch: Cleanup result
Launch-->>SDK: Preserve caller profile and report combined errors
SDK-->>App: Close complete
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| if requested_port is None: | ||
| return _available_port() |
There was a problem hiding this comment.
port=0 used to mean "auto-pick" here but now only None takes the auto path, that's great but passing 0 can cause a hang (_inspect_chrome_port(0) binds fine)
TS rejects this in validateLocalBrowserOptions ("Chrome port must be an integer between 1 and 65535"), should we do the same here?
There was a problem hiding this comment.
passing 0 in the public upstream API would fail pydantic validation, but i can add an extra check here in the internal fn
why
this PR addresses parity gaps in local launch behaviour:
Go & Python also accepted an explicit debugging port without first proving it was available. that could let launch continue toward a browser endpoint the SDK did not own
what changed
about:blank, viewport behavior, & profile ownershipCHROME_PATHthen platform candidates/json/versionresponse with a non-emptywebSocketDebuggerUrlbefore a Python launch resolvestaskkill /Tthen/Ftest plan
CHROME_PATH, complete platform discovery order, unsupported platforms, & caller profile creation.Summary by cubic
Closes local browser-launching parity gaps across the Python, Go, and TypeScript SDKs. Python previously returned after spawning Chrome and could leave failed launches behind; it now waits for a usable CDP endpoint, while Python and Go reject occupied debugging ports and all SDKs treat empty profile paths as omitted.
Bug Fixes
Tests
Written for commit a7bccfa. Summary will update on new commits.