diff --git a/examples/folio/sanderling/predicates.ts b/examples/folio/sanderling/predicates.ts index ec48f93..13149b5 100644 --- a/examples/folio/sanderling/predicates.ts +++ b/examples/folio/sanderling/predicates.ts @@ -39,14 +39,19 @@ export function parseTypedAmount(text: string | undefined | null): number { // When the last action is a tap (or double-tap) on the transaction Submit // button, the absolute change in total balance must equal the amount the // user typed. A double-submit lands two transactions and shifts the balance -// by 2x the typed amount, tripping this check. +// by 2x the typed amount, tripping this check. The route gate skips steps +// whose landing screen is not Home: totalBalance is only freshly computed +// from visible AccountCards on Home, so off-Home comparisons would read a +// stale carrier value and false-fire. export function submitChangesBalanceByTypedAmount(args: { + route: string | null; lastAction: { kind?: string; on?: string | object } | null; typedAmount: number; prevTotalBalance: number; currTotalBalance: number; }): boolean { - const { lastAction, typedAmount, prevTotalBalance, currTotalBalance } = args; + const { route, lastAction, typedAmount, prevTotalBalance, currTotalBalance } = args; + if (route !== "home") return true; if (lastAction == null) return true; if (lastAction.kind !== "Tap" && lastAction.kind !== "DoubleTap") return true; const on = lastAction.on; diff --git a/examples/folio/sanderling/spec.ts b/examples/folio/sanderling/spec.ts index ee21cd3..a323b6c 100644 --- a/examples/folio/sanderling/spec.ts +++ b/examples/folio/sanderling/spec.ts @@ -98,10 +98,12 @@ const newAccountBalanceIsZero = always( // Property 2: a tap on TxnSubmit must move the total balance by exactly the // typed amount. A double-submit lands two transactions, so the balance shifts -// by twice the typed amount and the check fires. +// by twice the typed amount and the check fires. The route gate inside the +// predicate skips off-Home landings where totalBalance.current is the carrier. const submitMovesBalanceByTypedAmount = always( next(() => submitChangesBalanceByTypedAmount({ + route: route.current, lastAction: lastAction.current, typedAmount: parseTypedAmount(txnAmountField.previous?.text), prevTotalBalance: totalBalance.previous ?? 0,