Skip to content

fix(web): preserve the backend ref so snapshot refs match actionable refs - #2283

Merged
thymikee merged 2 commits into
mainfrom
fix/web-ref-preservation
Sep 5, 2026
Merged

fix(web): preserve the backend ref so snapshot refs match actionable refs#2283
thymikee merged 2 commits into
mainfrom
fix/web-ref-preservation

Conversation

@thymikee

@thymikee thymikee commented Sep 4, 2026

Copy link
Copy Markdown
Member

Summary

Preserve agent-browser refs through snapshot normalization and storage so web actions target the element shown in the snapshot. Backends without refs retain positional numbering.

For a snapshot exposing Username e2, Passcode e3, and Sign in e4, fill @e2 Ada targets Username and click @e4 targets Sign in.

Six files changed. Adds production-route regression coverage through the public browser provider, request router, stored snapshot refs, and backend fill/click commands.

Validation

Tested commit: bb43f00ddb.

  • pnpm check:affected --run: passed (730 files, 5,585 tests). First run hit a session-runtime Apple cleanup process-guard failure; the isolated file and full rerun passed.
  • Provider regression passes; removing either the normalizer's ref preservation or attachRefs preservation independently fails with positional e1/e2/e3 replacing e2/e3/e4.
  • Live built CLI with managed agent-browser 0.27.1 against a local login fixture: snapshot showed Username e2, Passcode e3, Sign in e4; fill @e2 Ada produced DOM values #login-username="Ada", #login-password=""; after a fresh snapshot, click @e4 fired Sign in. Session closed successfully. This live fixture included a heading at e1; the automated route scenario supplies the non-dense case.
  • CI on this head is pending; previous-head checks passed.

…refs

The web/agent-browser backend mints refs in tree order and skips
non-interactive nodes, so its `@eN` refs are not dense. agent-device was
dropping that ref in `normalizeAgentBrowserSnapshot` and then re-minting a
dense positional `e${index+1}` in `attachRefs`. The ref an agent reads off
the snapshot (dense, positional) therefore did not equal the ref the backend
resolves on the next action (tree-ordered). On the ShopDemo login screen the
username textbox displayed as one ref while the backend's ref for the same
position pointed at the passcode field, so `fill @e3` landed in the wrong
input.

Preserve the backend ref on each web node and make `attachRefs` keep a
node's existing `ref` when present, falling back to dense numbering for
backends that do not mint refs (iOS/Android/maestro are unaffected).
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 2.61 MB 2.61 MB +17 B
JS gzip 878.4 kB 878.4 kB +8 B
npm bundled raw 2.61 MB 2.61 MB +17 B
npm bundled gzip 878.4 kB 878.4 kB +8 B
npm tarball 1.04 MB 1.04 MB +178 B
npm unpacked 3.52 MB 3.52 MB +526 B
npm clean-installed 3.52 MB 3.52 MB +526 B

npm unpacked components

Component Base Current Diff
JS / dist source 2.77 MB 2.77 MB +526 B
Apple runner source/project 544.4 kB 544.4 kB 0 B
Apple snapshot presentation source 33.8 kB 33.8 kB 0 B
Apple Simulator snapshot bridge source 30.5 kB 30.5 kB 0 B
macOS helper source 54.8 kB 54.8 kB 0 B
Android helper artifacts 43.3 kB 43.3 kB 0 B
Other package files 46.7 kB 46.7 kB 0 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 28.8 ms 28.6 ms -0.2 ms
CLI --help 80.2 ms 76.2 ms -4.0 ms

Top changed chunks: no changes in the largest emitted chunks.

Top changed packed files

Packed file Base Current Diff
dist/src/sdk-contracts.d.ts 18.3 kB 18.8 kB +509 B
dist/src/agent-browser-provider.js 16.4 kB 16.4 kB +10 B
dist/src/sdk-contracts.js 11.7 kB 11.7 kB +7 B

@thymikee

thymikee commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Review at exact head f848b6f found one actionable regression-proof gap. The new tests prove the agent-browser normalizer retains draft.ref and attachRefs preserves it in isolation, but they do not prove the shipped snapshot → buildSnapshotState → stored-ref resolution → web fillRef/tapRef route. Existing route coverage uses dense positional refs and would still pass with the original bug. Please add a non-dense production-route scenario where the snapshot exposes e2/e3/e4 and acting on displayed e2 is forwarded as @e2 to the intended username element; reverting either preservation leg must make it red. Also record practical after-fix web evidence (snapshot ref, action command, and DOM outcome), since the PR currently records only the live reproduction. No other code finding. The failed iOS smoke was an unrelated xcrun SDK lookup timeout during unchanged package verification; its failed-job rerun is in progress.

@thymikee

thymikee commented Sep 5, 2026

Copy link
Copy Markdown
Member Author

Addressed the regression-proof and live-evidence request in bb43f00ddb.

  • Added a non-dense production-route scenario in test/integration/provider-scenarios/web-provider.test.ts. It uses the public agent-browser provider with only backend command execution faked, then drives the real request router → snapshot normalization → snapshot state/storage → displayed-ref resolution → web fill/click path. Username/Passcode/Sign in are exposed as e2/e3/e4; filling the displayed Username ref emits fill @e2 Ada, preserves empty Passcode, and clicking the refreshed Sign in ref emits click @e4.
  • Independently removed each preservation leg. Both runs failed because the displayed refs became e1/e2/e3; restoring the fix passes.
  • Live after-fix check with the built CLI and agent-browser 0.27.1: snapshot -i exposed Username e2, Passcode e3, Sign in e4; fill @e2 Ada yielded DOM #login-username="Ada", #login-password="". After a fresh snapshot, click @e4 fired the Sign in handler. The page reported actual DOM values to its local fixture server. The browser session closed successfully. The live page included heading e1; non-dense coverage is supplied by the automated scenario.

pnpm check:affected --run passed (730 files, 5,585 tests). The first run hit an Apple runner cleanup process-guard failure in session-open-runtime.test.ts; that file passed in isolation and in the full rerun. Final gate passed on bb43f00ddb. Updated the PR description with this evidence. New-head CI is pending.

@thymikee

thymikee commented Sep 5, 2026

Copy link
Copy Markdown
Member Author

Sentinel reconciliation at bb43f00: the non-dense production-route regression and recorded after-fix browser evidence address the previous review requests; no remaining code finding in this diff. CI is now blocked: iOS run 33984867542 failed smoke:automation-input while waiting for Agent Device Tester. Diagnostics report wait_runner_restart_exhausted, readableCaptures=0, runner_connect_failed_before_command_send (10s budget; about 23.8s elapsed). This is a runner connection/restart failure, not evidence of a web-ref assertion failure; a flake is not proven. Investigate/rerun that lane before merge. No readiness label applied.

@thymikee
thymikee merged commit 2dabe29 into main Sep 5, 2026
17 of 18 checks passed
@thymikee
thymikee deleted the fix/web-ref-preservation branch September 5, 2026 19:06
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-05 19:07 UTC

thymikee added a commit that referenced this pull request Sep 5, 2026
* origin/main:
  perf: bundle runtime dependencies and report full install size (#2310)
  ci: avoid unrelated Apple runner cache invalidation (#2303)
  fix(web): preserve the backend ref so snapshot refs match actionable refs (#2283)
  test(daemon): session-open-url-prewarm through the request seam (#2304)
  test(daemon): session-devices-batch-runtime through the request seam (#2305)
  chore(gates): layering baselines ratchet against merge-base (#2299)
  test(daemon): one typed conformance helper for the daemon runtime suites (#2298)
  chore(layering): derive the contracts export inventory from package.json (#2297)
  perf: bundle tar-stream to reduce install footprint (#2286)
  docs: simplify agent context and resolve conflicting guidance (#2287)
  refactor(cli): let help resolve command aliases itself and retire R12 (#2293)
thymikee added a commit that referenced this pull request Sep 5, 2026
* origin/main:
  perf: bundle runtime dependencies and report full install size (#2310)
  ci: avoid unrelated Apple runner cache invalidation (#2303)
  fix(web): preserve the backend ref so snapshot refs match actionable refs (#2283)
  test(daemon): session-open-url-prewarm through the request seam (#2304)
  test(daemon): session-devices-batch-runtime through the request seam (#2305)
  chore(gates): layering baselines ratchet against merge-base (#2299)
  test(daemon): one typed conformance helper for the daemon runtime suites (#2298)
  chore(layering): derive the contracts export inventory from package.json (#2297)
  perf: bundle tar-stream to reduce install footprint (#2286)
  docs: simplify agent context and resolve conflicting guidance (#2287)
  refactor(cli): let help resolve command aliases itself and retire R12 (#2293)
  refactor(commands): retire the navigation-only type projection (#2294)
  feat(runtime): route managed leases through contained transports (#2285)
  refactor(contracts): build unavailable runtime facts once (#2291)
  refactor(cli): derive the common flag readers from the common-field table (#2292)
  feat(daemon): add managed allocation operation journal (#2284)
thymikee added a commit that referenced this pull request Sep 5, 2026
* origin/main:
  perf: bundle runtime dependencies and report full install size (#2310)
  ci: avoid unrelated Apple runner cache invalidation (#2303)
  fix(web): preserve the backend ref so snapshot refs match actionable refs (#2283)
  test(daemon): session-open-url-prewarm through the request seam (#2304)
  test(daemon): session-devices-batch-runtime through the request seam (#2305)
  chore(gates): layering baselines ratchet against merge-base (#2299)
  test(daemon): one typed conformance helper for the daemon runtime suites (#2298)
  chore(layering): derive the contracts export inventory from package.json (#2297)
  perf: bundle tar-stream to reduce install footprint (#2286)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant