diff --git a/examples/folio/sanderling/spec.ts b/examples/folio/sanderling/spec.ts index 639787a..7604768 100644 --- a/examples/folio/sanderling/spec.ts +++ b/examples/folio/sanderling/spec.ts @@ -36,38 +36,41 @@ function parseCents(desc: string | null | undefined): number { return Number(parts[1]) || 0; } -// Screen detection via unique element presence -const loggedIn = extract(s => s.ax.find("desc:login_submit") == null); +// Route and auth state derived from screen root nodes +const loggedIn = extract(s => s.ax.find("desc:LoginScreen") == null); const route = extract(s => { - if (s.ax.find("desc:login_submit")) return "login"; - if (s.ax.find("desc:add_account_button")) return "home"; - if (s.ax.find("desc:account_name_field")) return "add-account"; - if (s.ax.find("descPrefix:active_account:")) return "ledger"; - if (s.ax.find("desc:txn_amount")) return "add-transaction"; + if (s.ax.find("desc:LoginScreen")) return "login"; + if (s.ax.find("desc:HomeScreen")) return "home"; + if (s.ax.find("desc:AddAccountScreen")) return "add-account"; + if (s.ax.find("desc:LedgerScreen")) return "ledger"; + if (s.ax.find("desc:AddTransactionScreen")) return "add-transaction"; return null; }); -const accounts = extract(s => s.ax.findAll("descPrefix:account:") +// All element lookups scoped through their screen root +const accounts = extract(s => s.ax.findAll("desc:HomeScreen > descPrefix:account:") .map(el => parseAccount(el.desc))); -const ledgerRows = extract(s => s.ax.findAll("descPrefix:ledger_row:") +const ledgerRows = extract(s => s.ax.findAll("desc:LedgerScreen > descPrefix:ledger_row:") .map(el => parseLedgerRow(el.desc))); const ledgerBalance = extract(s => - parseCents(s.ax.find("descPrefix:ledger_balance:")?.desc)); + parseCents(s.ax.find("desc:LedgerScreen > descPrefix:ledger_balance:")?.desc)); const activeAccountId = extract(s => - s.ax.find("descPrefix:active_account:")?.desc?.split(":")[1] ?? null); + s.ax.find("desc:LedgerScreen > descPrefix:active_account:")?.desc?.split(":")[1] ?? null); + +// focusedInput lives in the app root (not inside any screen), so unscoped const focusedInput = extract(s => s.ax.find("descPrefix:focused_input:")?.desc?.split(":")[1] ?? null); -const loginEmailField = extract(s => s.ax.find("desc:login_email")); -const loginPasswordField = extract(s => s.ax.find("desc:login_password")); -const loginSubmit = extract(s => s.ax.find("desc:login_submit")); -const addAccountButton = extract(s => s.ax.find("desc:add_account_button")); -const accountNameField = extract(s => s.ax.find("desc:account_name_field")); -const addAccountSubmit = extract(s => s.ax.find("desc:add_account_submit")); -const addTxnButton = extract(s => s.ax.find("desc:add_txn_button")); -const txnAmountField = extract(s => s.ax.find("desc:txn_amount")); -const txnSubmit = extract(s => s.ax.find("desc:txn_submit")); -const accountCards = extract(s => s.ax.findAll("descPrefix:account:")); +const loginEmailField = extract(s => s.ax.find("desc:LoginScreen > desc:login_email")); +const loginPasswordField = extract(s => s.ax.find("desc:LoginScreen > desc:login_password")); +const loginSubmit = extract(s => s.ax.find("desc:LoginScreen > desc:login_submit")); +const addAccountButton = extract(s => s.ax.find("desc:HomeScreen > desc:add_account_button")); +const accountNameField = extract(s => s.ax.find("desc:AddAccountScreen > desc:account_name_field")); +const addAccountSubmit = extract(s => s.ax.find("desc:AddAccountScreen > desc:add_account_submit")); +const addTxnButton = extract(s => s.ax.find("desc:LedgerScreen > desc:add_txn_button")); +const txnAmountField = extract(s => s.ax.find("desc:AddTransactionScreen > desc:txn_amount")); +const txnSubmit = extract(s => s.ax.find("desc:AddTransactionScreen > desc:txn_submit")); +const accountCards = extract(s => s.ax.findAll("desc:HomeScreen > descPrefix:account:")); const backButton = extract(s => s.ax.find("desc:Back")); // Property 1: every new account starts with balance === 0