Repository navigation
fix(emulate): scope remembered overrides to the session and attachment - #352
Merged
Merged
Conversation
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.
Summary
After session A returns a tab, Chrome's debugger detach clears its emulation overrides. A later session B that sets only width and height can nevertheless restore A's user agent, touch settings, mobile flag and DPR, because the extension remembers those fields in a global map keyed only by tab ID.
Scope remembered overrides to the session context and the CDP runner/attachment that applied them. Preserve partial updates within the same live context. Fixes #350.
Reproduction and evidence
Failing base: 8cbcc490. Validated PR head: 67629e81.
The emulation-lifecycle.browser.test.ts performs this sequence on a surviving Chrome tab:
390 × 844, DPR3,mobile: true, user agentBSK-AUDIT-OLD-SESSION, and touch with 5 points.releaseSessionTab, then stop A. The debugger is actually detached; a subsequent read reattaches and confirms the original desktop UA and zero touch points.width: 1200, height: 800.navigator.userAgent/navigator.maxTouchPoints.55005return; response also contains DPR3andmobile: true0remain; applied request contains only the new dimensionsThe browser regression failed on the base and passed on this PR. The unit tests additionally isolate owner and attachment changes, rather than relying only on a scenario that changes both at once.
Implementation
The remembered state is now a
WeakMap<SessionContext, Map<tabId, EmulationState>>. Each entry records the CDP runner, attachment ID, and fully applied overrides.SessionContextstarts without the previous owner's remembered fields, even if the session ID string is reused.offclears that context's remembered entry.This changes cache ownership and validation at the next merge. It relies on the existing debugger detach path to reset Chrome's actual overrides; it does not introduce new tab-return or session-stop hooks.
Validation
Local environment: macOS, Node 26.10.0, pnpm 10.17.0, Vitest 4.1.6, Chrome 153.0.8010.54.
git diff --checkLocal focused total: 33 passed.
Use the repository's declared pnpm 10.17.0, from the repository root. The local runs used
npm exec --yes --package pnpm@10.17.0 -- pnpm ...to select that version. SetBSK_CLICK_CHROMEto an installed Chrome executable; without it the browser test is skipped.Hosted CI: one failure remains
For 67629e81, checked 2026-09-26 UTC, 7 checks passed and 1 failed. Frontend lint/typecheck/tests/build, Rust, all Windows jobs, Node scripts and CodeCC passed.
The browser CI job failed in unchanged network-control.browser.test.ts:
GitHub marks the subsequent Run emulation-lifecycle browser regression step as skipped. Accordingly, this PR's new browser regression is locally verified, but it did not run in that hosted attempt.
The failing network test and the new emulation browser test passed together in a local follow-up run (2/2):
BSK_CLICK_CHROME=/path/to/chrome \ pnpm --filter @browser-skill/extension exec vitest run \ src/debug/__tests__/network-control.browser.test.ts \ src/tools/__tests__/emulation-lifecycle.browser.test.tsNo debug/CDP implementation or existing network browser test is changed by this PR. The cause of that hosted failure has not been established; the local pass is not a substitute for the failed hosted check. GitHub denied the rerun request with
Must have admin rights to Repository, so a maintainer rerun or investigation is still needed.Verification boundary
The browser test executes production
ChromiumCdp,handleEmulate, andreleaseSessionTabagainst real Chrome. Window creation, tab ownership metadata, and session window removal are adapted by the harness. It does not drive the extension's tab-borrow/return UI or the complete CLI/daemon transport. DPR/mobile defaults and merge isolation are also checked at the handler/CDP-call level in unit tests.