lib/widgets/action_button.dart |
test/widgets/action_button_test.dart |
lib/widgets/buttons/app_filled_button.dart |
test/widgets/buttons/app_buttons_test.dart (combined) |
lib/widgets/buttons/app_text_button.dart |
test/widgets/buttons/app_buttons_test.dart (combined) |
lib/widgets/date_picker_field.dart |
test/widgets/date_picker_field_test.dart |
lib/widgets/form/country_field.dart |
test/widgets/form/country_field_test.dart |
lib/widgets/form/dropdown_field.dart |
test/widgets/form/form_fields_test.dart (combined) |
lib/widgets/form/labeled_text_field.dart |
test/widgets/form/form_fields_test.dart (combined) |
lib/widgets/handlebars.dart |
test/widgets/outlined_tile_handlebars_test.dart (combined) |
lib/widgets/hide_amount_text.dart |
test/widgets/hide_amount_text_test.dart |
lib/widgets/iban_input_formatter.dart |
test/widgets/iban_formatters_test.dart (combined; not strictly a widget) |
lib/widgets/iban_text_formatter.dart |
test/widgets/iban_formatters_test.dart (combined; not strictly a widget) |
lib/widgets/info_row.dart |
test/widgets/info_row_test.dart |
lib/widgets/mnemonic_field.dart MnemonicReadOnlyField part-class |
test/widgets/mnemonic_read_only_field_test.dart |
| Mnemonic extensions |
test/widgets/mnemonic_extensions_test.dart, test/widgets/mnemonic_field_extensions_test.dart |
lib/widgets/number_pad.dart |
test/widgets/number_pad_test.dart |
lib/widgets/outlined_tile.dart |
test/widgets/outlined_tile_handlebars_test.dart (combined) |
lib/widgets/standard_slide_button.dart |
test/widgets/standard_slide_button_test.dart |
lib/widgets/tab_selector.dart |
test/widgets/tag_tab_selectors_test.dart (combined) |
lib/widgets/tag_selection.dart |
test/widgets/tag_tab_selectors_test.dart (combined) |
lib/widgets/text_link_span.dart |
test/widgets/text_link_span_test.dart |
lib/widgets/text_substring_highlighting.dart |
test/widgets/text_substring_highlighting_test.dart |
Context
lib/widgets/holds 31 Dart files. Two are not strictly widgets (iban_input_formatter.dartis aTextInputFormatter,iban_text_formatter.dartis a utility class) — but both are in scope for tests because they sit inlib/widgets/.Mechanical accounting against existing tests:
mnemonic_field.dart)Form / mnemonic widgets are the primary entry point for untrusted user input (KYC, restore-wallet seed entry, contact form). A silent regression in any of them ripples into every consuming screen.
Already tested — do not re-add
lib/widgets/action_button.darttest/widgets/action_button_test.dartlib/widgets/buttons/app_filled_button.darttest/widgets/buttons/app_buttons_test.dart(combined)lib/widgets/buttons/app_text_button.darttest/widgets/buttons/app_buttons_test.dart(combined)lib/widgets/date_picker_field.darttest/widgets/date_picker_field_test.dartlib/widgets/form/country_field.darttest/widgets/form/country_field_test.dartlib/widgets/form/dropdown_field.darttest/widgets/form/form_fields_test.dart(combined)lib/widgets/form/labeled_text_field.darttest/widgets/form/form_fields_test.dart(combined)lib/widgets/handlebars.darttest/widgets/outlined_tile_handlebars_test.dart(combined)lib/widgets/hide_amount_text.darttest/widgets/hide_amount_text_test.dartlib/widgets/iban_input_formatter.darttest/widgets/iban_formatters_test.dart(combined; not strictly a widget)lib/widgets/iban_text_formatter.darttest/widgets/iban_formatters_test.dart(combined; not strictly a widget)lib/widgets/info_row.darttest/widgets/info_row_test.dartlib/widgets/mnemonic_field.dartMnemonicReadOnlyFieldpart-classtest/widgets/mnemonic_read_only_field_test.darttest/widgets/mnemonic_extensions_test.dart,test/widgets/mnemonic_field_extensions_test.dartlib/widgets/number_pad.darttest/widgets/number_pad_test.dartlib/widgets/outlined_tile.darttest/widgets/outlined_tile_handlebars_test.dart(combined)lib/widgets/standard_slide_button.darttest/widgets/standard_slide_button_test.dartlib/widgets/tab_selector.darttest/widgets/tag_tab_selectors_test.dart(combined)lib/widgets/tag_selection.darttest/widgets/tag_tab_selectors_test.dart(combined)lib/widgets/text_link_span.darttest/widgets/text_link_span_test.dartlib/widgets/text_substring_highlighting.darttest/widgets/text_substring_highlighting_test.dartDead code — delete, do not test
lib/widgets/chain_asset_icon.dart— verified bygrep -rn "ChainAssetIcon"acrosslib/: zero consumers in the production tree. PureStatelessWidget, no callers. Tracked as its own cleanup ticket (separate "chore: delete dead widget" issue).Scope — 8 testable files (the true gap after removing dead code)
Form / input widgets (user-input boundary)
lib/widgets/form/birthday_field.dart— date picker round-trip, locale handlinglib/widgets/form/file_picker_field.dart— file selection, validation, error displaylib/widgets/form/phone_number_field.dart— test the actual contract: hard-coded prefix list['+41', '+49']atphone_number_field.dart:16, digit-only number input, minimum length 6 (:91-99), prefix/number split on initial value, recombine on emit. Do not assert E.164 round-trip — the widget does not implement E.164.Mnemonic widgets (security-critical)
lib/widgets/mnemonic_field.dart—MnemonicInputFieldinteractive class. The four filesmnemonic_input_field.dart,mnemonic_input_field_controller.dart,mnemonic_field_base.dart,mnemonic_read_only_field.dartare allpart of 'mnemonic_field.dart';(line 1 of each) and cannot be imported independently. One test file coversMnemonicInputFieldpaste handling, focus traversal, BIP-39 validation.MnemonicReadOnlyFieldis already tested.lib/widgets/seed_blur_card.dart— verifies the wrapped mnemonic is hidden by default (ExcludeSemanticsatseed_blur_card.dart:23) and revealed only on explicit tap-to-show.KYC-document upload (testable today, no refactor needed)
lib/widgets/image_picker_sheet.dart— consumers aresettings_edit_name_page.dartandsettings_edit_address_page.dart(KYC proof-of-identity / proof-of-address). A bug here blocks KYC completion. Sheet selection logic (theListTiletaps →ImageSourcemapping → null-on-dismiss) is fully testable today via Navigator-pop assertions;ImagePicker().pickImage(...)itself can be stubbed viaTestDefaultBinaryMessenger.setMockMethodCallHandleron theplugins.flutter.io/image_pickerchannel — no source refactor needed.Earlier versions of this issue said this file was "blocked on refactor / Port abstraction" — verified false. The sheet's
ListTiletaps each return distinctImageSourcevalues; swapping camera ↔ gallery is a plausible regression worth catching.Picker (low-value but cheap)
lib/widgets/date_picker.dart— pure Flutter (Cupertino branch viaDeviceInfo.instance.isIOSatdate_picker.dart:13, Material branch viashowDatePicker). Both branches testable influtter_test. Specific bug-pattern worth catching: the Cupertino branch'sselectedDatedefaults toinitialDateand is only updated viaonDateTimeChanged— if the popup is dismissed by tap-outside, it returnsinitialDateinstead ofnull, diverging from Material'sshowDatePickerwhich returnsnullon cancel. Consumers aresettings_tax_report_page.dartandtransaction_history_page.dart(non-funds-loss but UX-incorrect).Allow-list candidates
None from the current
lib/widgets/tree.chain_asset_icon.dartwould have been one, but it's dead code (delete instead).Acceptance criteria
*_test.dartcovering: builds with required + minimal props, builds with optional props, handles user interaction (tap / fill / select) when applicable, asserts callback wire-upmnemonic_field.darttest additionally asserts that the entered text is excluded from the Semantics tree (verifiable viaseed_blur_card.dart:23ExcludeSemantics).image_picker_sheet.darttest usesTestDefaultBinaryMessenger.setMockMethodCallHandlerfor the image-picker channel; does NOT require a port-abstraction refactor.test/widgets/form/form_fields_test.dartandtest/widgets/buttons/app_buttons_test.dartboth define a private_host(Widget child) => MaterialApp(...)helper and calltester.pumpWidget(_host(...)). This is the established pattern for widget-level tests. (pumpAppfromtest/helper/helper.dartis the screen-test convention used by*_page_test.dart— not the widget-test convention.)Cross-issue coordination
lib/widgets/**/*.darthas a test") is owned by CI: file-pair existence guard (every page/widget needs a test or an allow-list entry) #551. Combined test files must be tolerated by the guard (this issue lists 6 such combined specs). The CI guard is a forward-looking complement; this issue can ship without it.chain_asset_icon.dartdeletion tracked as separate cleanup issue (referenced from.test-coverage-allowlistuntil chore: delete deadchain_asset_iconwidget #560 lands).Estimated effort
image_picker_sheet(channel-mock + sheet logic)date_picker(Cupertino + Material branches, cancel-semantics bug)chain_asset_icon.dart(#560)Related
lib/widgets/**— source treetest/widgets/form/form_fields_test.dart,test/widgets/buttons/app_buttons_test.dart— canonical widget-test pattern (_host+pumpWidget)*_page.dart(12 untested + 5 special-handling) #544 — sister issue for*_page.darttestWidgets (uses differentpumpAppconvention fromtest/helper/helper.dart)chain_asset_iconwidget #560 — chore: delete deadchain_asset_iconwidget