fix(click): observe post-click effects + scope snapshot locators to modal#11
Merged
Merged
Conversation
- click handler now observes downstream effects within a 300ms budget (configurable via --observe-ms, opt-out via --no-observe) and returns dialogDismissed, urlChanged, preDialogCount, postDialogCount, observedMs alongside ok. Eliminates the silent-no-op confusion seen on HubSpot's "Save changes?" alertdialog where the trusted click was dispatched correctly but loc.click() resolved ~1.3s before React unmounted the modal — agents would see ok:true, retry, and double-save. - snapshot now scopes per-node Locators to the auto-detected modal. Previously the rendered ARIA tree was modal-only but getByRole(...) ran page-wide, so a same-named button outside the modal (zombie React subtree, stacked dialogs) could trigger strict-mode or pick the wrong element. - console --dedup smoke check uses a per-run marker so a warm daemon's CircularBuffer can no longer cause count=10 on the second smoke run. 99/99 smoke checks pass. Live-verified on HubSpot service-keys page.
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
ghax clicknow reports observable downstream effects —dialogDismissed,urlChanged,preDialogCount,postDialogCount,observedMs— alongside the existingok. Default 300ms budget, configurable via--observe-ms <n>, opt-out via--no-observe. Fixes the silent-no-op confusion whereloc.click()resolved before React actually unmounted a confirm modal.ghax snapshotnow scopes per-node Locators to the auto-detected modal when dialog-scope kicks in. Previously the rendered ARIA tree was modal-only butgetByRole(...)ran page-wide, so a same-named button outside the modal could trigger strict-mode errors or, where Playwright's pick resolved uniquely, silently click the wrong element. Stacked dialogs (HubSpot stacks analertdialogover an already-opendialog) hit this routinely.console --deduptest now uses a per-run marker so the daemon'sCircularBuffercan no longer causecount=10on a second smoke run against the same daemon.Why this matters
A field report described
ghax click @e<ref>returning{ok: true}on the HubSpot "Yes, save" confirmation modal but the modal not dismissing. Reproduced live: the click was dispatched correctly via Playwright's CDPInput.dispatchMouseEvent(soisTrusted: true— that hypothesis was wrong); HubSpot just runs an async network round-trip before unmounting the dialog, ~1.3s later. The old{ok: true}told callers nothing about whether the effect landed. Agents retry, double-save.The new fields let agents write deterministic checks like
if (!result.dialogDismissed && !result.urlChanged) retry().Test plan
npm run typechecknpm run buildcargo build --releaseGHAX_BIN=$PWD/target/release/ghax npm run test:smoke— 99/99 pass in ~400s/service-keys/21999358/key/38111555:click Edit→urlChanged: true, postDialogCount: 1click Save→preDialogCount: 1, postDialogCount: 2(alertdialog stacks)click "Yes, save" --observe-ms 2500→urlChanged: trueNew smoke checks
click reports dialogDismissed when a modal closesclick reports dialogDismissed=false when nothing changesclick --no-observe skips post-click observationsnapshot scopes locators to the auto-detected modal