Repository navigation
Travel sites: pop-ups, calendars, place boxes, click into view - #78
Conversation
A press on a sight mark goes through a selector, and a selector's element that shows at all is not scrolled first: the press lands on its middle whether the window shows that point or not, and reports success. Live, a store's "Add to cart" sat at the window's foot with its middle below it, and every press went nowhere. Before pressing a sight mark, the surface now runs INTO_VIEW_JS: an element whose middle lies outside the window is scrolled to the window's middle, and one in view is left where it is. A ref of the tree is still brought into view by agent-browser itself. The fake's check for stray page scripts (evaluated_besides_every_press) leaves this script out, as it does the one that keeps a press in the tab.
A click listener Preact keeps on an element (`l` once minified, or
`_listeners`, as "click" or "clickfalse") makes it a control, as a React
press handler does. Live, a hotel site's place suggestions were rows with
only such a listener, read as page text, and the place typed was never
chosen. Inside another control, an element with a press handler of its
own is a control too: a sort menu's options sat inside their
pointer-cursor trigger and read as one button naming them all.
A class behind a variant prefix (`placeholder:text-disabled`,
`disabled:opacity-50`) no longer reads as disabled or selected: a flight
site's place box carried the first and was never seen. Words run together
in camel case in an icon's class ("icClose") are read as words, so a
sign-up pop-up whose only way out was such a sprite can be closed.
A calendar drawn without a table, a grid of 28 to 49 cells numbered from
1 below the month and year it shows, is read as one, its days as dates; a
title naming two months names two grids in order. A picker showing two
months side by side is paged by the block that holds both, and a table's
header is read as shown, so a hidden month list no longer hides the month
it shows. A row scrolled out of its own list's view (a popover's airport
rows below its fold) reads offscreen rather than covered, so it is ranked
and offered rather than dropped.
Each has a live sight test against a page in Chrome, in the new
live_controls_tests.rs and live_calendar_tests.rs topics, along with one
that a control below the window's foot is brought into it and pressed.
Live runs on travel sites stalled on a few patterns any site can draw;
each is now handled by what the page shows, not by where it is.
What Jev is shown. Of the 120 elements a state holds, those in view come
first and the rest keep a quarter of the room in page order (seen_first):
a sign-up pop-up drawn at the end of a long page was cut off, and a
calendar in front crowded out the guests button it covers. A knockout
that must drop chunks drops them first from regions with nothing in view,
so the list in front and a dialog's rows are offered whole. A place box's
suggestion is a row in view and in front, never a footer link of the
same name.
Dialogs. Front keeps whose the dialog in front is (Dialog: the page's,
the task's still asking, answered, or served by a step before), in place
of separate flags. A dialog at a run's first look is the task's only when
the task's run before left its own dialog in front, which contract 2.9
carries: RunFlowRequest and FlowRunResult gain `dialog_left_open`, kept
by the task store for a rescue. A sign-up or a menu the page opened at a
rescue's first look no longer refuses every move past it. A calendar the
task opened and has pressed in since no longer blocks a press behind it,
and on a page that draws its pop-up without a dialog's role, a closer
that went with what it was pressed on is the pop-up dismissed.
Calendars and place boxes. An enter step picks each date from a
calendar already showing before it looks for a box, rather than pressing
the calendar's own button closed. A form that draws its place boxes as
buttons ("From DEL", "To BLR") has each slot's opener pressed once, one
slot at a time (enter/open.rs). A date the field's button shows
("Departure Thu, 22 Oct") counts as made. An enter value with no box is
picked only from what the screen shows, a list's option is one option
however long its label, and "to" or "from" alone names only a container
that begins with it. A pick opens only lists whose items hold something
to press, never a strip of bare fares.
RunFlowRequest's new flag sits beside three others that callers set by
name; its struct_excessive_bools allow says why folding them into one
enum is not worth a major bump.
Tiny Sweeper review
Last completed reportTiny Sweeper reviewTiny Sweeper reviewed this change across 6 lane(s) and found 20 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below. State: Changes requested Review snapshot
Completeness: Complete What changedThe review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below. FeaturesNone identified with supported citations. TestsNo supported feature-to-test mapping was produced. Test execution is not inferred. Findings
Resolved this pass
Before merge
Agent review detailscritique
security
tests
commits
description
e2e
Evidence and run details
|
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Comment |
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is critical.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.1267 · 2,592,786 in / 136,056 out · 251,153 cached (10%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0736 · 1,417,865 in / 84,626 out · 136,534 cached (10%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0514 · 957,898 in / 42,421 out · 110,907 cached (12%) · gpt-5.6-luna
tests: $0.0008 · 105,325 in / 3,155 out · 3,648 cached (3%) · glm-5.3-flash
description: $0.0003 · 52,850 in / 1,980 out · 0 cached (0%) · glm-5.3-flash
Front took any press in a dialog the task opened for its answer, so a
calendar whose month was turned counted as served, and a covered press
could close it before its day was picked. Pressing a control that only
turns the month ("next month", "Previous month") now leaves the calendar
asking; a day pressed in it still serves its field.
A grid of bare numbers counted as a calendar's days even with no month on
screen, so a seat map pressed in could be closed for a press behind it.
Grid cells named by a number now count only when the screen names a month
somewhere; cells that name or are described with a month count as before.
A run that ended before its first look reported no dialog left open,
dropping the one its run before had left. Front::left_open now hands that
dialog on until the run has looked.
A dismissal step on a pop-up drawn without a dialog's role ends when the control pressed names a closer and went with what it sat on. "Accept all" and "I agree" close a consent bar as surely as "Reject all" does, but were not closer words, so a step accepting cookies on such a bar fell back to a judge that cannot see which button closed it. A simulated cookie bar now checks that accepting it ends the step.
closest kept a long option row by an exact role match, while is_one_option, beside it, compares roles in any case. It now uses that helper, so an "Option" row is kept like an "option" one. The in_region rustdoc now says a placing word's region never holds a control that only names it, which is what the code does on purpose.
The simulated ride form drops a box's unpicked text when a press lands anywhere else, as a page does, except when the press was the other box's "From"/"To" button: that switched boxes and kept the old list on show. It now closes the open list first, so a flow cannot pass by picking from a list a real page would have closed.
Sight took each grid calendar's parent as its month while still looking for grids, so when two months' grids sat side by side in one block, the first claimed the block and the second was skipped: none of its days read as dates. Grids are now all found first, and a block holding two of them is no one month; the picker pass still adds it so its arrows page both. A row's middle outside its scrolling container reads offscreen, but a control fixed to the window moves with no container and none clips it. A fixed button drawn from inside a scrolling list read offscreen wherever it showed. scrollerOf now stops at a fixed element. Live tests in Chrome cover both, and each fails without its fix.
named_opener's rustdoc said a label holding a slot's word anywhere, while it looks only at the first three words; it now says so and why. seen_first said "those in view first" where it keeps them first but lists every kept element in screen order, as jev-harness.md says. The contract spec's 2.9 note broke the sentence it sat in; it now closes the version list and explains dialog_left_open apart.
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is critical.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0884 · 1,577,666 in / 126,097 out · 143,701 cached (9%) · gpt-5.6-luna, glm-5.3-flash, gpt-6-luna
critique: $0.0463 · 821,241 in / 66,289 out · 84,583 cached (10%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0375 · 576,708 in / 50,132 out · 59,118 cached (10%) · gpt-5.6-luna
tests: $0.0005 · 57,709 in / 2,204 out · 0 cached (0%) · glm-5.3-flash
description: $0.0006 · 58,271 in / 5,089 out · 0 cached (0%) · glm-5.3-flash
A pick "closest to 9" was judged item by item, and live, with a store's sizes 9 and 10 sold out, Jev found none of 6, 7, and 8 clearly closest, so the step failed and every rescue went back to the sold-out 9. tinycomputer-core gains closest_to, which reads the number a criterion such as "closest to 9" or "nearest to size 42" names, and rank_closest, which ranks records by the distance of the first number each shows. pick ranks such a criterion within the list from names (asking which when several show, as for "first", through the new named_list), and takes the first ranked item that belongs, as for prices. Both are additive.
Return is refused while a sheet or alert shows, since there it presses the dialog's default button. Live, a store's search opened as a full-window sheet, and the step to press Enter in the box just typed into was refused 154 times; a rescue had to pick a suggestion instead. FlowRun now keeps the field its last action typed into (typed_last, kept through waits), and Return goes through in front of a sheet when that field is a search box: a searchbox, or a box that takes text and names itself for searching. A simulated search that opens as a sheet checks both that Return runs it and that Return stays refused with no search box typed into.
A product grid repeats one "ADD" on every card, and by its name alone
every copy is the same. Live, "add the first Maggi product" pressed the
first card's ADD, on a ramen above the Maggi, and two packets of the wrong
product went into the cart.
Sight now describes a control whose role and name repeat, with no
description of its own, by the name of the card holding it when that
card is a control itself ("in Maggi Double Masala 95 g ₹20"). A live
test in Chrome checks it, and that a control no other card repeats is
left alone.
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0700 · 904,877 in / 75,127 out · 69,977 cached (8%) · gpt-5.6-luna, glm-5.3-flash, gpt-6-luna
critique: $0.0266 · 420,422 in / 35,847 out · 42,663 cached (10%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0380 · 279,388 in / 26,801 out · 27,186 cached (10%) · gpt-5.6-luna
tests: $0.0006 · 66,076 in / 4,821 out · 64 cached (0%) · glm-5.3-flash
description: $0.0006 · 66,551 in / 4,151 out · 64 cached (0%) · glm-5.3-flash
From the second review of this branch:
holds_calendar read a day only as a label's first word, so cells named
whole dates ("Thu Oct 01 2026", "Choose Thursday, October 22nd, 2026")
were no calendar's days. A short label that names a month now holds its
day anywhere, with a leading zero or an ordinal ending (day_of).
turns_the_month reads the description too: a "Next" described "next
month" turns the month.
Return in front of a sheet went through on the field typed into last
even after a dialog came up over it. The field must still show,
uncovered (still_shows): a dialog over it takes the keys.
named_opener took a link or button only in lower case; any case now.
records_of numbers its fields with three digits, so their keys sort in
reading order past ten fields, as rank_closest and the price parsers
read them.
The simulated ride form hid a box behind its button again only once a suggestion was picked: pressed elsewhere or escaped, its list closed but its box stayed on show. drop_unpicked now closes the box with its list. The cookie bar's doc says it covers no control, as the promo toast does, since nothing behind it is refused.
A grid of days took its month from a sibling before it, read through shownWords, which falls back to innerText, and a hidden element's innerText still holds its text: a template or a month menu the page never shows could title a grid of numbered buttons. A sibling must now show. A live test checks that a grid titled only by hidden text is no calendar.
Summary
Fixes for the travel-site rounds after #77 (Goibibo, OYO, MakeMyTrip, Agoda, ixigo). Each one handles a pattern any page can draw; none names a site.
This PR does not depend on tinyhumansai/agent-browser#2. The
vendor/agent-browsergitlink is unchanged (ebf10fb, as on main). The click-into-view fix was first tried in agent-browser'selement.rs. It is done here in tinycomputer instead.Three commits:
INTO_VIEW_JS(surface/uncover.rs) now scrolls such an element to the window's middle before the press and leaves one in view alone.l/_listeners), e.g. OYO's place suggestions.placeholder:text-disabled) are no longer read as disabled or selected.icClose).Frontkeeps whose dialog is in front (Dialog: the page's, or the task's asking, answered, or served). A dialog at a rescue's first look is the task's only when the run before left it open, and contract 2.9 carries that across.Related issue
Part of tinyhumansai/openhuman#7000. Follows #77.
API or behavior changes
RunFlowRequest.dialog_left_openandFlowRunResult.dialog_left_open, both optional and defaulting tofalse. The task controller sets the field for a rescue run itself, so a host needs no change. A host built against 2.8 still binds this module; a host built against 2.9 needs a 2.9 module.Validation
cargo fmt --all -- --check: clean.cargo clippy --all-targets --all-features -- -D warnings: clean on every crate excepttinycomputer-accessibility, which this PR doesn't touch. That crate's macOS-only code (focus.rs,paste.rs,permissions.rs) fails 4 lints under local clippy 0.1.98, and fails the same way on main. CI runs on Ubuntu, where that code isn't compiled.cargo build --all-targets --all-features: not run on its own. The clippy run and the test build above compile every target.cargo test --all-features, run ascargo test --release --workspace --exclude tinycomputer-accessibility --all-features: every suite passes. Re-run after the new tests moved into topic files: engine 452 passed, browser 135 passed.RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features --workspace --exclude tinycomputer-accessibility: clean.Live sight tests in Chrome (
TINYCOMPUTER_LIVE_BROWSER=1): 19 passed.Live site runs through the loaded module (
task_live), all made before the last fixes:enterstep left To and the date to rescues. Search, 4 flights read, the cheapest picked and Book pressed all went through. It ended when the destructive guard refused a "… Pay ₹4,300 fee …" radioFront's flags were folded into one state to satisfy clippy. This doesn't change behavior.live_a_control_whose_middle_is_below_the_window_is_brought_into_it_and_pressed.Tests
flow_tests/picker_tests.rs: a closer that goes with its pop-up; a calendar picked in, closed for a press behind it; a date picked without pressing its button.CalendarStaysOpen, and place boxes drawn as buttons.sight_tests/live_controls_tests.rsandsight_tests/live_calendar_tests.rs, plus the scrolled-list case inlive_tests.rs. These need Chrome andTINYCOMPUTER_LIVE_BROWSER=1, and return early without them.INTO_VIEW_JS's scroll itself runs only in the live test.Documentation
docs/crates/tinycomputer-browser/interacting.md: bringing a sight mark into view.docs/crates/tinycomputer-browser/sight.md: Preact listeners and variant classes.docs/technical/decision-thresholds.md:CALENDAR_DAYS.docs/technical/jev-harness.md: in-view-first order of the 120 elements.docs/technical/specs/desktop-module-contract.md: the 2.9 bump.crates/tinycomputer-bus/src/flow/guide.md: a pop-up that may not show is closed in anifstep.Checklist
#[allow(...)],#[ignore], or relaxed lints: there is one#[allow(clippy::struct_excessive_bools)], onRunFlowRequest. The comment beside it gives the reason: folding its four flags into an enum would renameallow_destructive,include_valuesandtraceon the wire, which is a major bump. The same allow already sits ondescribe.rsandobservation/types.rs..envcontents in the diff or the description.Known gaps, not fixed here
enterstep left To and the date to rescues. A radio worded as a fee ("… Pay ₹4,300 fee …") is refused as irreversible, which is an acceptable end.