Commit Graph
245 Commits
Author SHA1 Message Date
pj 5e6f45408e fix(folio): totalBalance carrier tracks only Home, not Ledger
Home cardSum is a multi-account total; Ledger's LedgerBalance is a single
account on a different scale. Blending them in the carrier produced bogus
cross-screen deltas (prev from Ledger, curr from Home), triggering false
positives in submitMovesBalanceByTypedAmount. Restrict the carrier to
Home AccountCard totals via the computeHomeTotalBalance helper.
2026-05-31 21:15:21 +05:30
pj 5a5b15e89e feat(folio): add computeHomeTotalBalance helper
Pure helper that tracks Home multi-account total only and carries the last
Home sum across off-Home steps. Ledger's single-account balance is excluded
because mixing it would corrupt cross-screen scale comparisons.
2026-05-31 21:15:16 +05:30
pj 9647d5e042 test(folio): cover submit predicate with raw typed-amount inputs
Pipes realistic raw keystrokes through parseTypedAmount + the predicate
so single submits clear and double submits fire as expected.
2026-05-31 18:57:34 +05:30
pj 3e4cf965b0 fix(folio): carry forward total balance across off-screen transitions
AddTransactionScreen shows neither AccountCard nor LedgerBalance, so the
extractor used to report 0 at the step before submit. That made every
non-zero current balance look like the full delta and tripped the typed
amount property on every honest submit. Remember the last-seen sum and
return it whenever the current snapshot has no balance signal.
2026-05-31 18:57:07 +05:30
pj 7ef448987f fix(folio): parse raw amount input as cents in submit predicate
txnAmountField holds raw user keystrokes, not formatted balance text.
Route it through parseTypedAmount so "50" reads as $50, matching how
the app commits the transaction.
2026-05-31 18:56:46 +05:30
pj d88200f398 fix(folio): add parseTypedAmount helper matching app's parseCents
Raw user input like "50" must become 5000 cents, not 50. The existing
parseDollarCents helper strips non-digits and so reads "50" as 50 cents,
which is correct for formatted balance text but off by 100x for raw
input from the amount field.
2026-05-31 18:56:30 +05:30
pj ee1fad1d30 fix(verifier): populate Action.On when tap chooser picks an element
Coordinate-targeted Taps/DoubleTaps left On empty, so action-gated
properties reading lastAction.on couldn't tell which target was hit and
were vacuously skipped. Resolve the picked element to a stable
key:value selector (resource-id, testTag, text, desc) and validate it
resolves back to the same element so we don't accidentally redirect the
tap to a sibling that shares the identifier.
2026-05-31 18:53:27 +05:30
pj ff1a8928dc fix(runner): mark nil/empty hierarchy as transitional
A failed or empty sidecar hierarchy fetch was pushed straight to the
verifier, letting spec extractors crash with "Cannot read property 'map'
of undefined" when findAll returned null. Treat that case like a
transitional capture: skip the verifier push, still record the step, and
keep the loop progressing.
2026-05-31 18:50:28 +05:30
pj 211f3fbf96 docs(action-space): move LongPress, Scroll, DoubleTap to current actions 2026-05-31 18:13:23 +05:30
pj 49333d42f8 test(runner): cover LongPress and Scroll dispatch 2026-05-31 18:13:23 +05:30
pj e14dd20a83 feat(runner): dispatch LongPress and Scroll actions 2026-05-31 18:13:18 +05:30
pj 9df5edb900 test(proto): expect LongPress in service descriptor 2026-05-31 18:11:37 +05:30
pj b23a8efbdb test(spec): cover LongPress and Scroll runtime members 2026-05-31 18:09:34 +05:30
pj 792010c6d0 feat(spec): re-export longPresses and scrolls as opt-in generators 2026-05-31 18:09:34 +05:30
pj 8efcfbce51 feat(spec): no-op LongPress and Scroll in web runtime 2026-05-31 18:09:34 +05:30
pj 66b2877f9f feat(spec): add LongPress and Scroll authoring surface 2026-05-31 18:08:19 +05:30
pj a6a629a6bc test(folio-spec): unit tests for submitChangesBalanceByTypedAmount
Covers single vs double submit, the DoubleTap variant, vacuous cases
(null action, wrong kind, wrong target, zero typed), and selector-as-
object coercion.
2026-05-31 18:07:57 +05:30
pj c6efc15951 test(verifier): cover longPresses and scrolls generators 2026-05-31 18:07:37 +05:30
pj dc0026ad37 feat(verifier): wire longPresses and scrolls generators 2026-05-31 18:07:37 +05:30
pj 2397a65b9f feat(folio-spec): wire submitMovesBalanceByTypedAmount property
Adds lastAction and totalBalance extractors and uses them in the new
property. Drops ledgerRows/ledgerBalance extractors since nothing else
referenced them.
2026-05-31 18:07:08 +05:30
pj 7a2f03e67f feat(folio-spec): predicate that gates balance check on TxnSubmit tap
Replaces the row-sum predicate (which always held by construction since
balance is derived from rows in Folio) with one that compares the typed
amount to the actual balance delta after a tap on TxnSubmit. Catches the
planted double-submit bug.
2026-05-31 18:07:01 +05:30
pj 8ffb174c1b feat(verifier): add LongPress and Scroll action kinds 2026-05-31 18:06:29 +05:30
pj ae271b86e0 test(sidecar): implement longPress in snapshot test backend 2026-05-31 18:03:41 +05:30
pj 050246448b test(sidecar): cover LongPress dispatch 2026-05-31 18:02:50 +05:30
pj 95bb77d43c feat(sidecar): dispatch LongPress RPC to backend 2026-05-31 18:02:50 +05:30
pj 33fbf2a68e feat(sidecar): implement longPress across backends 2026-05-31 18:02:50 +05:30
pj b3742101d1 feat(chrome): implement LongPress as press-and-hold 2026-05-31 18:02:08 +05:30
pj ecaae817a0 feat(mock): record LongPress action 2026-05-31 18:01:38 +05:30
pj fc54e86b17 feat(sidecar): add LongPress client method 2026-05-31 18:01:38 +05:30
pj 55352f72c5 feat(driver): add LongPress to DeviceDriver interface 2026-05-31 18:01:24 +05:30
pj 1ffca2e560 chore(proto): regenerate Go stubs for LongPress 2026-05-31 18:01:18 +05:30
pj 26ed8e7760 feat(proto): add LongPress RPC 2026-05-31 18:01:09 +05:30
pj 9f7f2f5b21 test(sidecar): assert InputText types at cursor without clearing
Captures the adb command stream and verifies a single input-text call
with no preceding delete keyevents, plus the adb escaping cases.
2026-05-31 17:52:45 +05:30
pj 4d497cce56 fix(sidecar): type text at cursor instead of clearing the field
InputText now appends at the focus caret, matching the native driver
and the standard mobile-input contract, instead of deleting existing
content first. Adds an injectable command runner so the behavior is
testable without a device.
2026-05-31 17:52:24 +05:30
pj 17fc698e10 fix(chrome): launch with no-sandbox so headless Chrome starts in CI 2026-05-31 17:09:35 +05:30
pj 726e5e0a20 fix(build): rebuild sidecar JAR when Kotlin sources change
Without source-file deps on $(SIDECAR_JAR), make never re-ran shadowJar
after a Kotlin edit, so a stale embedded JAR shipped on every install
and the new sidecar code was silently absent at runtime.
2026-05-31 15:56:30 +05:30
pj 37079a0d84 test(spec): cover balanceMatchesAddedSum single, sum-match, over, under cases
Pins the sum-based predicate: a single new row matching delta and two new
rows summing to delta both hold; two-row over-sum (double-submit) and
under-sum cases both violate.
2026-05-31 15:49:55 +05:30
pj b88b6c239d fix(folio): use sum-of-added-rows in balanceMatchesAddedTxn
The old predicate (every row's signed amount equals delta) silently passed
the double-submit bug because two same-amount rows each match the delta in
isolation. Switching to the sum check (addedSum === delta) catches both the
double-submit case and any future multi-row append whose total drifts from
the balance change.
2026-05-31 15:49:51 +05:30
pj 35fce05b65 fix(folio): extract balanceMatchesAddedSum predicate as testable helper
Move the ledger-balance-vs-added-rows predicate into a pure helper module
so the property's logic is unit-testable in isolation. Marks the sanderling
example as an ES module so cross-package ESM imports resolve under node.
2026-05-31 15:49:45 +05:30
pj e9c6066ba4 refactor(inspect-ui): rename Step.action to Step.next_action
Aligns the SPA type and consumers with the trace schema rename. The
StepSummary.action_kind/action_label labels stay unchanged since they
are derived labels, not the raw next-action.
2026-05-31 15:41:25 +05:30
pj f237eb2c4d test(inspect): update fixtures to use next_action trace field
Aligns inspect tests with the trace schema rename. Step constructors
now set NextAction and the JSONL fixtures use the next_action tag.
2026-05-31 15:40:34 +05:30
pj 7916123458 refactor(inspect): decode trace step's next_action JSON field
Mirrors the trace schema rename of action to next_action. The summary
shape exposed to the SPA (action_kind/action_label) keeps its current
JSON tags since these are derived labels, not the raw next-action.
2026-05-31 15:40:04 +05:30
pj 332e7a034d refactor(runner): assign trace action to Step.NextAction field
Follows the rename of trace.Step.Action to Step.NextAction. The runner
already computed the next iteration's action here; only the field name
changes.
2026-05-31 15:39:43 +05:30
pj 4ee3d97cff refactor(trace): rename Step.Action to Step.NextAction
The trace step's action field is the action chosen FOR THE NEXT iteration
based on observing this step's hierarchy, not the action that produced
this step. Rename Step.Action to Step.NextAction and the JSON tag to
next_action to make causality explicit at the data level.
2026-05-31 15:39:32 +05:30
pj 8d29b2906f test(runner): cover transitional step skips verifier and clean control 2026-05-31 15:36:04 +05:30
pj d83b2f8da1 fix(runner): skip verifier for transitional trees after retry budget
When fetchSyncedState exits its retry loop with a tree that still shows a NavHost cross-fade, the runner now marks the step transitional, writes the step + screenshot to the trace, and skips Verifier.PushSnapshot / EvaluateProperties / ChangedExtractors so the previous-to-current extractor advance is not poisoned by transient state. The next clean step's previous still references the prior clean state. NextAction continues to run so the loop never deadlocks on a never-stabilizing screen.
2026-05-31 15:35:03 +05:30
pj 2d2c11f830 feat(trace): add Transitional flag to Step 2026-05-31 15:33:25 +05:30
pj 56b762deac test(driver): cover Snapshot in proto descriptor and sidecar client
Adds Snapshot to the descriptor allowlist and a sidecar-client test that
asserts both fields come back over the wire.
2026-05-31 15:28:50 +05:30
pj 5c58610181 test(runner): assert step uses Snapshot, not raw hierarchy/screenshot
TestRunner_UsesAtomicSnapshot catches regressions to the two-goroutine
race, and the existing parallel-fetch test now keys off ActionSnapshot.
2026-05-31 15:27:45 +05:30
pj 1931c0b57f refactor(runner): observe each step via the atomic Snapshot RPC
fetchSyncedState now issues one Snapshot per attempt so hierarchy and
screenshot describe the same on-device frame. The transitional retry
stays: that case handles a fully-captured but mid cross-fade frame,
which atomic capture cannot fix.
2026-05-31 15:27:39 +05:30