6.7 KiB
Browser zoom capability repro
Date: 2026-08-31
Target: http://127.0.0.1:34401 (rendered login page, /auth/login)
Browser: Google Chrome for Testing 152.0.7977.64
CLI: agent-browser 0.27.0
Result
True browser zoom is repeatable through a disposable Manifest V3 extension
loaded by agent-browser. The extension calls chrome.tabs.setZoom(tabId, factor) with 0.8, 1.25, or 2.0.
This satisfies the requested invariant at every factor and viewport tested:
visualViewport.scalestays1.- CSS viewport dimensions change by the inverse zoom factor.
devicePixelRatiotracks the browser zoom factor.- The rendered
h1bounds change with the layout.
The agent-browser press Control+- path is not native browser zoom. It
dispatches a page key event and left all measured values unchanged. The CLI
reference also has no direct Chrome browser-zoom command. Do not relabel
Emulation.setPageScaleFactor, CSS zoom, or viewport/device emulation as
browser zoom; those are separate mechanisms.
The provided vault login helper was attempted without reading vault metadata or credential values. The rendered login page was sufficient for this browser-level probe, so no product interaction or mutation was required.
Repeatable method
-
Create a disposable extension with
tabspermission and host permission limited to the candidate app. SetZOOM_FACTORto the desired value.manifest.json:{ "manifest_version": 3, "name": "Disposable native zoom probe", "version": "1.0.0", "permissions": ["tabs"], "host_permissions": ["http://127.0.0.1:34401/*"], "background": { "service_worker": "background.js" } }background.js:const ZOOM_FACTOR = 1.25; // replace with 0.8, 1.25, or 2.0 function applyZoom(tab) { if (tab?.id == null || !tab.url?.startsWith("http://127.0.0.1:34401")) return; chrome.tabs.setZoom(tab.id, ZOOM_FACTOR); } chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { if (changeInfo.status === "complete") applyZoom({ ...tab, id: tabId }); }); chrome.tabs.query({}, (tabs) => tabs.forEach(applyZoom)); -
Start a fresh, uniquely named session and disposable profile. On this headless host, extensions require explicit
--headless=new; keep--no-sandboxin the launch args. The non-extension baseline sessions used the exact--args '--no-sandbox'form:npx -y --package agent-browser agent-browser \ --session zoom-extension-<factor>-<unique> \ --profile /tmp/agent-browser-zoom-profile-<factor>-<unique> \ --extension /tmp/agent-browser-native-zoom-extension-<factor>-<unique> \ --headed false \ --args '--no-sandbox,--headless=new' \ open http://127.0.0.1:34401 -
Set the exact viewport and measure the same fixed element:
npx -y --package agent-browser agent-browser \ --session zoom-extension-<factor>-<unique> set viewport 320 568 npx -y --package agent-browser agent-browser \ --session zoom-extension-<factor>-<unique> eval \ "(()=>{const e=document.querySelector('h1')||document.body;const r=e.getBoundingClientRect();const v=window.visualViewport;return {innerWidth,innerHeight,outerWidth,outerHeight,devicePixelRatio,visualViewport:{width:v?.width,height:v?.height,scale:v?.scale},fixed:{x:r.x,y:r.y,width:r.width,height:r.height}}})()" -
Capture the screenshot, then close the session. Use a fresh profile or clear the disposable profile before testing another factor:
npx -y --package agent-browser agent-browser \ --session zoom-extension-<factor>-<unique> screenshot \ /absolute/path/.screenshots/release-v2/repro-browser-zoom-capability/native-<factor>-320x568.png npx -y --package agent-browser agent-browser \ --session zoom-extension-<factor>-<unique> close
The same method was run at 1920 1080. A native extension zoom session must
be restarted when changing the factor; changing only the viewport is safe.
Measurements
The fixed probe is the first rendered h1 (Log in to your account). Bounds
are CSS pixels in x, y, width, height order. outer is the browser window
metric reported by Chromium; it is intentionally included because it stays
at the window size while the CSS viewport changes.
320x568 requested viewport
| Zoom | inner (W x H) | outer (W x H) | devicePixelRatio | visualViewport (W x H / scale) | fixed h1 bounds |
|---|---|---|---|---|---|
| 100% baseline | 320 x 568 | 500 x 711 | 1 | 305 x 568 / 1 | 87, 177, 191, 57.59375 |
| 80% native | 400 x 710 | 500 x 711 | 0.800000011920929 | 381.25 x 710 / 1 | 87.2265625, 201.23046875, 266.7578125, 28.7890625 |
| 125% native | 256 x 454 | 500 x 711 | 1.25 | 244 x 454.3999938964844 / 1 | 86.80000305175781, 176.8000030517578, 130.40000915527344, 86.4000015258789 |
| 200% native | 160 x 284 | 500 x 711 | 2 | 152.5 x 284 / 1 | 87, 177, 95.5703125, 86.390625 |
1920x1080 requested viewport
| Zoom | inner (W x H) | outer (W x H) | devicePixelRatio | visualViewport (W x H / scale) | fixed h1 bounds |
|---|---|---|---|---|---|
| 100% baseline | 1920 x 1080 | 1920 x 1223 | 1 | 1920 x 1080 / 1 | 765, 418.71875, 340.71875, 28.796875 |
| 80% native | 2400 x 1350 | 1920 x 1223 | 0.800000011920929 | 2400 x 1350 / 1 | 1005.21484375, 562.734375, 340.64453125, 28.7890625 |
| 125% native | 1536 x 864 | 1920 x 1223 | 1.25 | 1536 x 864 / 1 | 572.7999877929688, 320.20001220703125, 340.7250061035156, 28.80000114440918 |
| 200% native | 960 x 540 | 1920 x 1223 | 2 | 952.5 x 540 / 1 | 281.25, 295.3984375, 340.71875, 28.796875 |
Negative controls
At 320x568, press Control+- produced no change from the 100% baseline:
innerWidth=320, innerHeight=568, outerWidth=500, outerHeight=711,
devicePixelRatio=1, visualViewport=305x568, scale=1, and the fixed h1
remained 87,177,191,57.59375. The corresponding capture is
keyboard-control-noop-320x568.png.
Pre-seeding a disposable profile with profile.default_zoom_level,
partition.default_zoom_level, and a localhost per_host_zoom_levels entry
also did not alter metrics when launched through agent-browser; it is not a
reliable path here. A first extension launch without --headless=new exited
before CDP with a missing X server error.
Evidence artifacts
All captures are 8-bit PNGs at the requested pixel dimensions under
.screenshots/release-v2/repro-browser-zoom-capability/:
baseline-320x568-100.pngbaseline-1920x1080-100.pngnative-80-320x568.png,native-80-1920x1080.pngnative-125-320x568.png,native-125-1920x1080.pngnative-200-320x568.png,native-200-1920x1080.pngkeyboard-control-noop-320x568.png
No product tests, builds, Docker compilation, or E2E tests were run.