fix(app): restore green Flutter tests on main (#21302 #21340 #21341 #21343 follow-ups)

Merged
GI
2d ago
+49-6

Summary

Restore green Flutter tests on main for follow-ups to #21302, #21340, #21341, and #21343.

Per-test root cause and fix

  • app/test/services/device_service_connection_failure_test.dart — The native reconnect contract was already preserved by DeviceService; the test emitted a broadcast stream event and asserted state in the same turn, before the asynchronous listener ran. Verdict: test timing was wrong. Await one event-loop turn after emitting the event. This does not change connection or reconnect behavior.

  • app/test/widgets/apps_category_section_large_text_test.dart — The measurement used TextPainter('Ag') with the card styles but omitted the inherited DefaultTextStyle, which supplies line metrics used by the actual Text widgets. The card renders a 60 pt icon, three maxLines: 1/ellipsis labels, 2 pt gaps, and 8 pt vertical padding on both sides; there is no explicit strut or line-height override. Verdict: product layout was wrong. Measure single lines with the inherited style, scaler, direction, one-line/ellipsis settings, and the card's actual body/footnote/caption styles. Derive row height as max(85, 16 + max(60, textStack) + 1), with no extra slack. The test also corrects its expected label count (the heading plus three cards all say Productivity) and pins rendered row targets and fit at all four scales.

    Text scaleOld raw text stackRendered text stackOld targetItemHeight (+32 slack)Correct targetItemHeight
    1.0x45 pt63 pt94 pt85 pt
    1.15x52 pt71 pt101 pt88 pt
    1.3x57 pt80 pt106 pt97 pt
    1.5x67 pt92 pt116 pt109 pt

    The omitted inherited line metrics account for 18, 19, 23, and 25 pt of stack height respectively. The corrected targets include the actual 16 pt padding and 1 pt clearance. iPhone 17 Pro simulator (iOS 26.5, 393x852 logical viewport, 3x) screenshots at 1.0x were captured and opened: the section is 389 pt tall before and 333 pt after; labels stay single-line and ellipsized. The 85 pt default target returns to the original baseline.

  • app/test/widgets/settings/ai_app_generator_large_text_test.dart — The English localization includes an ellipsis (Try something like…), while the test expected the text without it. Verdict: test expectation was wrong. Match the localized label, verify the horizontal suggestion list, and retain the loaded fallback prompt assertion. The product strip already scales with text size. Test passes across all four configured scales.

  • app/test/widgets/settings/settings_search_header_stability_test.dart — The harness did not provide UsageProvider, which SettingsDrawer reads while building. The header was never mounted, so the key finder failed before measuring layout. Verdict: test harness was incomplete. Supply the provider; the existing 48 pt header and alignment behavior pass.

Verification

  • Flutter 3.44.5: each of the four focused test files passes.
  • CI-equivalent bash test.sh --reporter expanded: 5,493 passed, 21 existing skips, no failures.
  • bash scripts/analyze_ratchet.sh: passed.
  • No other red tests found.

Failure-Class: none
UI-Evidence: none -- Opened iOS simulator before/after captures are local at /private/tmp/main-red-tests/before/category-1-0.png and /private/tmp/main-red-tests/after/category-1-0.png; automated widget assertions cover the 1.0x through 1.5x targets.

🤖 Generated with Claude Code