feat: page interaction verbs β type, hover, press, drag, scroll with receipt evidence and assertable interaction counts - #2
Merged
Conversation
Extends the click primitive to the other ways a user makes UI state: typing (per-character key events pipelined on the session socket, or one insertText), hovering, and key presses including modifier chords. Every verb records pages[].interactions evidence under the driver witness and never asserts β assertions stay in expect.page.*. Typed text is redacted by default (textLength stays honest); password fields are always redacted, even with redact: false. Ctrl/Meta chords send no text so Chrome cannot both insert the character and fire the shortcut. Drag and scroll interaction kinds and their timeline witness mappings are registered now; their drivers land in a follow-up.
drag dispatches a pipelined pointer sequence with interpolated moves (drag libraries only track past a movement threshold); the target probe runs after the source probe since scrollIntoView moves coordinates. Native HTML5 drag-and-drop is documented as out of scope with the Input.setInterceptDrags follow-up path. scroll uses wheel semantics (+y = down) with an event-driven confirmation that something actually scrolled; gesture: true uses Input.synthesizeScrollGesture with the spec's inverted sign normalized inside the driver. expect.page.outcome gains exact per-verb interaction counts, making the recorded interaction evidence itself assertable. Spec, README, and changelog updates ride the same change.
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.
Extends the
clickprimitive to the other ways a user makes UI state: type, hover, press, drag, and scroll.The verbs
insertText. Typed text is redacted by default (textLengthstays honest); password fields are always redacted, even withredact: false. Ctrl/Meta chords send no text, so Chrome cannot both insert the character and fire the shortcut.scrollIntoViewmoves coordinates. Native HTML5 drag-and-drop is documented as out of scope, with theInput.setInterceptDragsfollow-up path noted.+y= down) with an event-driven confirmation that something actually scrolled.gesture: trueusesInput.synthesizeScrollGesture, with the spec's inverted sign normalized inside the driver.Receipt evidence
Every verb records evidence on
PageRecord.interactionsunder the driver witness and never asserts β assertions stay inexpect.page.*. The interaction is a fact on the receipt whether or not anything is claimed about it.expect.page.outcomegains exact per-verb interaction counts, which makes the recorded interaction evidence itself assertable: a box can state how many times it typed, hovered, pressed, dragged, or scrolled, and that claim lands on the record as a named assertion rather than as prose.Spec, README, and changelog updates ride the same change.
Commits
fbefac9β type, hover, and press interaction verbs with receipt evidence83b86deβ drag and scroll verbs plus assertable interaction countsPossible follow-ups
Observations from consuming this API in a downstream verification suite (a browser suite driving built pages over witness's own CDP driver). These are notes, not commitments β nothing beyond the two commits above ships in this PR.
expect.networkassertion verb.expectcovers DOM and page evidence; there is no network equivalent, so every network claim in that suite is a hand-rollednetworkRequests()diff raised through a localassert()helper. It lands in the receipt as a box error rather than a named, passing assertion, which under-states what the box actually checked. Something shaped likeexpect.network(page, { since, requested, notRequested, maxBytes })would put those claims on the record.networkRequests()until the count holds still; a first-classpage.waitForNetworkIdle()(or asettledoption on the assertion above) would remove the hand-rolled loop.data:-URL filtering in network capture. CDP reports inline assets through the sameNetwork.*events, so an inline SVG in a stylesheet shows up as a 0-byte "request" as soon as it renders. Boxes filter by scheme themselves today; a scheme- orresourceType-aware filter in the handle would be kinder.BrowserVisitOptionscarries onlynetworkConditions. Nothing in that suite needed a fixed viewport β witness scrolls elements into view before acting β but a layout-sensitive suite has no knob.browser.visit()dev-server behavior for absolute URLs. It always starts the project's dev server, even when every route visited is an absolute external URL. Absolute URLs do pass through cleanly (new URL(route, baseUrl)), so this is a small cost rather than a blocker, but it forces a placeholder config to exist.π€ Generated with Claude Code