Add E2E test regular send flow#547
Conversation
…into beast/add-android-e2e-setup
…tus-Network/quantus-apps into beast/e2e-regular-send-flow
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c57e681. Configure here.
| final feeData = await balancesService.getBalanceTransferFee(account, recipientAddress, ed); | ||
| final required = ed + feeData.fee; | ||
|
|
||
| if (balance < required) { |
There was a problem hiding this comment.
Preflight ignores sender ED reserve
Medium Severity
SendPreflight treats a wallet as funded when on-chain balance is at least existential deposit plus fee, but the send amount screen validates against effectiveMaxBalanceProvider, which reserves another existential deposit on the sender. Wallets funded only to the preflight threshold can pass the check yet stay blocked on review with insufficient balance.
Reviewed by Cursor Bugbot for commit c57e681. Configure here.
| DART_DEFINES+=(--dart-define-from-file=.env.test) | ||
| elif [[ -n "${TEST_IMPORT_MNEMONIC:-}" ]]; then | ||
| echo "==> Injecting test secrets from environment" | ||
| DART_DEFINES+=(--dart-define=TEST_IMPORT_MNEMONIC="$TEST_IMPORT_MNEMONIC") |
There was a problem hiding this comment.
CI dart-defines env fallback removed
Medium Severity
patrol_collect_dart_defines no longer maps exported environment variables (e.g. TEST_IMPORT_MNEMONIC) to --dart-define when .env.test is absent, though comments still describe that CI path. Runners that inject secrets via env without creating .env.test will build Patrol tests without required defines and fail at runtime.
Reviewed by Cursor Bugbot for commit c57e681. Configure here.
n13
left a comment
There was a problem hiding this comment.
Review — E2E regular send flow
Reviewed the full diff in an isolated worktree with flutter analyze (clean, including patrol_test/). The production surface is tiny — inert E2E Keys plus one overflow fix — everything else is test-only. Nice work: DRY is respected and the Patrol/Flutter pitfalls (debounced fee, hit-testable disabled buttons, locale-aware amount formatting) are handled thoughtfully.
Bugbot findings — verified
1. Preflight ignores sender ED reserve — VALID (low practical severity).
SendPreflight guarantees balance ≥ ED + fee and sends amount = ED, but the amount screen validates against effectiveMaxBalanceProvider (balance − ED, since the ED toggle defaults to true) via getAmountStatus ((amount + fee) > balance ⇒ insufficientBalance). So actually sending ED requires balance ≥ 2·ED + fee. A wallet funded in the [ED+fee, 2·ED+fee) window passes preflight but the Review button stays disabled, so _openReviewSend taps a disabled button until the 45s timeout (slow failure) instead of surfacing the intended clear error. The window is only ~0.001 QUAN wide (ED = 1e9 planck, 12 decimals), so any sensibly funded fixture clears it.
Fix: make preflight mirror the UI — require balance ≥ 2·ED + fee and update the "need>=…" error text.
2. dart-define env fallback removed — PARTIALLY VALID (stale docs, no CI breakage).
The elif [[ -n "${TEST_IMPORT_MNEMONIC}" ]] branch is gone; only .env.test is read now. But there is no Patrol/E2E CI job — ci.yaml runs analyze + unit tests on main and only touches .env (not .env.test), and nothing in .github/ references patrol / .env.test / these vars. So no existing CI breaks. The genuine defects are documentation-level: the header comment (patrol_common.sh lines 76–79) still says "CI: export TEST_IMPORT_MNEMONIC…", and the warning names only TEST_IMPORT_MNEMONIC, not the new TEST_SEND_RECIPIENT_ADDRESS (which the old elif never injected anyway).
Fix: update the comment + warning to state .env.test is the only supported mechanism, or restore env injection for both vars if the beast/add-android-e2e-setup base will export secrets in CI.
Other (non-blocking)
- [Low] Inconsistent text entry: the recipient uses bulk
enterTextbut the amount usestypeTextIntoField(send_flow_test.dart:43vs:47). TheonChanged-not-firing rationale intext_input.dartapplies to the recipient step too — add a comment explaining why they differ, or unify. - [Low] The
review_send_screenerror message moved outside the scroll region (now pinned above the confirm button). Arguably better (always visible) but is a behavioral change — confirm it matches design intent. - [Nit]
typeTextIntoField:if (char.isEmpty) continue;is dead code, andsplit('')breaks surrogate pairs (fine for numeric input — worth documenting the numeric-only assumption). - [Nit] The pending-activity key attaches to the first matching pending send; a leftover pending send from a prior run could take it. The assertion ("a pending outgoing send is visible") still holds.
Positives
- Correct, minimal overflow fix —
ScaffoldBaseboundsmainContentheight, soExpanded(SingleChildScrollView(_summarySection))is valid (hero fixed, summary scrolls) with no nested-scroll hazard. - Faithful DRY extraction (
WalletFlows.importFromWelcomereproduces the old test body exactly). e2e_locale.dartmirrors the app's locale resolution precisely and reuses production types.- All 12 new
E2EKeysare wired, mirrored inSelectors, and exercised; no collisions/orphans.flutter analyzeclean.
Verdict
Approve with comments. Production risk is minimal and analyze is clean. Bugbot #1 is a real but low-probability funding-contract mismatch and #2 is stale docs — both worth a quick follow-up, neither blocks this test-only PR.
Reviewed in an isolated worktree at commit c57e681.
n13
left a comment
There was a problem hiding this comment.
Review — E2E regular send flow
Reviewed the full diff in an isolated worktree with flutter analyze (clean, including patrol_test/). The production surface is tiny — inert E2E Keys plus one overflow fix — everything else is test-only. Nice work: DRY is respected and the Patrol/Flutter pitfalls (debounced fee, hit-testable disabled buttons, locale-aware amount formatting) are handled thoughtfully.
Bugbot findings — verified
1. Preflight ignores sender ED reserve — VALID (low practical severity).
SendPreflight guarantees balance >= ED + fee and sends amount = ED, but the amount screen validates against effectiveMaxBalanceProvider (balance - ED, since the ED toggle defaults to true) via getAmountStatus ((amount + fee) > balance => insufficientBalance). So actually sending ED requires balance >= 2*ED + fee. A wallet funded in the [ED+fee, 2*ED+fee) window passes preflight but the Review button stays disabled, so _openReviewSend taps a disabled button until the 45s timeout (slow failure) instead of surfacing the intended clear error. The window is only ~0.001 QUAN wide (ED = 1e9 planck, 12 decimals), so any sensibly funded fixture clears it.
Fix: make preflight mirror the UI — require balance >= 2*ED + fee and update the "need>=..." error text.
2. dart-define env fallback removed — PARTIALLY VALID (stale docs, no CI breakage).
The elif [[ -n "${TEST_IMPORT_MNEMONIC}" ]] branch is gone; only .env.test is read now. But there is no Patrol/E2E CI job — ci.yaml runs analyze + unit tests on main and only touches .env (not .env.test), and nothing in .github/ references patrol / .env.test / these vars. So no existing CI breaks. The genuine defects are documentation-level: the header comment (patrol_common.sh lines 76-79) still says "CI: export TEST_IMPORT_MNEMONIC...", and the warning names only TEST_IMPORT_MNEMONIC, not the new TEST_SEND_RECIPIENT_ADDRESS (which the old elif never injected anyway).
Fix: update the comment + warning to state .env.test is the only supported mechanism, or restore env injection for both vars if the beast/add-android-e2e-setup base will export secrets in CI.
Other (non-blocking)
- [Low] Inconsistent text entry: the recipient uses bulk
enterTextbut the amount usestypeTextIntoField(send_flow_test.dart:43vs:47). TheonChanged-not-firing rationale intext_input.dartapplies to the recipient step too — add a comment explaining why they differ, or unify. - [Low] The
review_send_screenerror message moved outside the scroll region (now pinned above the confirm button). Arguably better (always visible) but is a behavioral change — confirm it matches design intent. - [Nit]
typeTextIntoField:if (char.isEmpty) continue;is dead code, andsplit('')breaks surrogate pairs (fine for numeric input — worth documenting the numeric-only assumption). - [Nit] The pending-activity key attaches to the first matching pending send; a leftover pending send from a prior run could take it. The assertion ("a pending outgoing send is visible") still holds.
Positives
- Correct, minimal overflow fix —
ScaffoldBaseboundsmainContentheight, soExpanded(SingleChildScrollView(_summarySection))is valid (hero fixed, summary scrolls) with no nested-scroll hazard. - Faithful DRY extraction (
WalletFlows.importFromWelcomereproduces the old test body exactly). e2e_locale.dartmirrors the app's locale resolution precisely and reuses production types.- All 12 new
E2EKeysare wired, mirrored inSelectors, and exercised; no collisions/orphans.flutter analyzeclean.
Verdict
Approve with comments. Production risk is minimal and analyze is clean. Bugbot #1 is a real but low-probability funding-contract mismatch and #2 is stale docs — both worth a quick follow-up, neither blocks this test-only PR.
…into beast/e2e-regular-send-flow


Summary
Add e2e test for regular send. When running the test, found UI overflow bug. Already addressed here.
Note
Medium Risk
Touches real send/review UI and submits on-chain transfers in E2E (testnet/fixture only), plus a small layout change on the review screen users see when confirming sends.
Overview
Adds a Patrol E2E test that imports a wallet, sends the minimal funded amount on a simulator/emulator only, and asserts a pending outgoing send appears on home. Test support includes shared
WalletFlows.importFromWelcome,SendPreflight(balance + fee vs existential deposit), locale-aware amount text,typeTextIntoFieldso amount parsing/onChangedruns, andTEST_SEND_RECIPIENT_ADDRESSvia dart-define (with.env.testinjection unchanged for other secrets).Production changes wire
E2EKeysthrough home send, the full send stack (recipient → amount → review → submitted), and the first pending send row in home activity;AddressInputFieldgains an optional field key.review_send_screenlayout is adjusted so the summary scrolls inside anExpandedregion—fixing overflow found while exercising the flow.Reviewed by Cursor Bugbot for commit c57e681. Configure here.