From 252545090ea74a2e9c94097031e99e9127c503de Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:48:29 -0700 Subject: [PATCH 1/4] Enable bottom_navigation_bar_test --- .../bottom_navigation_bar_test.dart | 9 ++-- .../material_ui/test/feedback_tester.dart | 51 +++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) rename packages/material_ui/{temporarily_disabled_tests => test}/bottom_navigation_bar_test.dart (99%) create mode 100644 packages/material_ui/test/feedback_tester.dart diff --git a/packages/material_ui/temporarily_disabled_tests/bottom_navigation_bar_test.dart b/packages/material_ui/test/bottom_navigation_bar_test.dart similarity index 99% rename from packages/material_ui/temporarily_disabled_tests/bottom_navigation_bar_test.dart rename to packages/material_ui/test/bottom_navigation_bar_test.dart index ca2a1ca474a3..47e12629a56b 100644 --- a/packages/material_ui/temporarily_disabled_tests/bottom_navigation_bar_test.dart +++ b/packages/material_ui/test/bottom_navigation_bar_test.dart @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@Skip( - 'This file is skipped due to a cross-import that needs to be fixed. Tracked in https://github.com/flutter/flutter/issues/177028.', -) // This file is run as part of a reduced test set in CI on Mac and Windows // machines. @Tags(['reduced-test-set']) @@ -13,13 +10,13 @@ library; import 'dart:math'; import 'dart:ui'; -import 'package:material_ui/material_ui.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:material_ui/material_ui.dart'; import 'package:vector_math/vector_math_64.dart' show Vector3; -import '../widgets/feedback_tester.dart'; -import '../widgets/semantics_tester.dart'; +import 'feedback_tester.dart'; +import 'semantics_tester.dart'; void main() { testWidgets('BottomNavigationBar callback test', (WidgetTester tester) async { diff --git a/packages/material_ui/test/feedback_tester.dart b/packages/material_ui/test/feedback_tester.dart new file mode 100644 index 000000000000..a08224959c0a --- /dev/null +++ b/packages/material_ui/test/feedback_tester.dart @@ -0,0 +1,51 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Tracks how often feedback has been requested since its instantiation. +/// +/// It replaces the MockMethodCallHandler of [SystemChannels.platform] and +/// cannot be used in combination with other classes that do the same. +class FeedbackTester { + FeedbackTester() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( + SystemChannels.platform, + _handler, + ); + } + + /// Number of times haptic feedback was requested (vibration). + int get hapticCount => _hapticCount; + int _hapticCount = 0; + + /// Number of times the click sound was requested to play. + int get clickSoundCount => _clickSoundCount; + int _clickSoundCount = 0; + + Future _handler(MethodCall methodCall) async { + if (methodCall.method == 'HapticFeedback.vibrate') { + _hapticCount++; + } + if (methodCall.method == 'SystemSound.play' && + methodCall.arguments == SystemSoundType.click.toString()) { + _clickSoundCount++; + } + } + + /// Stops tracking. + void dispose() { + assert( + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.checkMockMessageHandler( + SystemChannels.platform.name, + _handler, + ), + ); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( + SystemChannels.platform, + null, + ); + } +} From 0b0a2245d7295c7f57e7e6e83dc64358fe6ac077 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:34:30 -0700 Subject: [PATCH 2/4] Move findByTooltip into shared utils folder --- .../test/bottom_navigation_bar_test.dart | 7 +-- .../material_ui/test/navigation_bar_test.dart | 44 ++----------------- packages/material_ui/test/utils/finders.dart | 44 +++++++++++++++++++ 3 files changed, 52 insertions(+), 43 deletions(-) create mode 100644 packages/material_ui/test/utils/finders.dart diff --git a/packages/material_ui/test/bottom_navigation_bar_test.dart b/packages/material_ui/test/bottom_navigation_bar_test.dart index 47e12629a56b..f208c0465a22 100644 --- a/packages/material_ui/test/bottom_navigation_bar_test.dart +++ b/packages/material_ui/test/bottom_navigation_bar_test.dart @@ -17,6 +17,7 @@ import 'package:vector_math/vector_math_64.dart' show Vector3; import 'feedback_tester.dart'; import 'semantics_tester.dart'; +import 'utils/finders.dart'; void main() { testWidgets('BottomNavigationBar callback test', (WidgetTester tester) async { @@ -1713,15 +1714,15 @@ void main() { expect(find.text('A'), findsOneWidget); await tester.longPress(find.text('A')); - expect(find.byTooltip('A tooltip'), findsOneWidget); + expect(findByTooltip('A tooltip'), findsOneWidget); expect(find.text('B'), findsOneWidget); await tester.longPress(find.text('B')); - expect(find.byTooltip('B'), findsNothing); + expect(findByTooltip('B'), findsNothing); expect(find.text('C'), findsOneWidget); await tester.longPress(find.text('C')); - expect(find.byTooltip('C'), findsNothing); + expect(findByTooltip('C'), findsNothing); }); testWidgets('BottomNavigationBar limits width of tiles with long labels', ( diff --git a/packages/material_ui/test/navigation_bar_test.dart b/packages/material_ui/test/navigation_bar_test.dart index 87a4e7a96cc4..b2bfdfe50763 100644 --- a/packages/material_ui/test/navigation_bar_test.dart +++ b/packages/material_ui/test/navigation_bar_test.dart @@ -14,6 +14,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:material_ui/material_ui.dart'; +import 'utils/finders.dart'; void main() { testWidgets('Navigation bar updates destinations when tapped', (WidgetTester tester) async { @@ -440,15 +441,15 @@ void main() { expect(find.text('A'), findsOneWidget); await tester.longPress(find.text('A')); - expect(_findByTooltip('A tooltip'), findsOneWidget); + expect(findByTooltip('A tooltip'), findsOneWidget); expect(find.text('B'), findsOneWidget); await tester.longPress(find.text('B')); - expect(_findByTooltip('B'), findsOneWidget); + expect(findByTooltip('B'), findsOneWidget); expect(find.text('C'), findsOneWidget); await tester.longPress(find.text('C')); - expect(_findByTooltip('C'), findsNothing); + expect(findByTooltip('C'), findsNothing); }); testWidgets('Navigation bar semantics', (WidgetTester tester) async { @@ -1814,40 +1815,3 @@ TextStyle _getLabelStyle(WidgetTester tester, String text) { .text .style!; } - -/// Finds [RawTooltip] or [Tooltip] widgets with the given `message`. -/// -/// ## Sample code -/// -/// ```dart -/// expect(find.byTooltip('Back'), findsOneWidget); -/// expect(find.byTooltip(RegExp('Back.*')), findsNWidgets(2)); -/// ``` -/// -/// If the `skipOffstage` argument is true (the default), then this skips -/// nodes that are [Offstage] or that are from inactive [Route]s. -/// -/// This was copied from flutter_test, which uses flutter/material.dart. -// TODO(justinmc): Port flutter_test to material_ui, then delete this method and -// use that one. -Finder _findByTooltip(Pattern message, {bool skipOffstage = true}) { - return find.byWidgetPredicate((Widget widget) { - // Compare RawTooltip's semantics tooltip with the given message. - // However, Tooltip's message needs to be checked directly if: - // 1. Tooltip.excludeFromSemantics is true, since in this case Tooltip - // provides no semantics tooltip to the underlying RawTooltip. - // 2. Tooltip.message and Tooltip.richMessage are empty, since in this - // case no RawTooltip is created. - if (widget is Tooltip) { - //if (widget.runtimeType == 'Tooltip') { - final String tooltipMessage = widget.message ?? widget.richMessage!.toPlainText(); - if ((widget.excludeFromSemantics ?? false) || tooltipMessage.isEmpty) { - return message is RegExp ? message.hasMatch(tooltipMessage) : tooltipMessage == message; - } - } - return widget is RawTooltip && - (message is RegExp - ? message.hasMatch(widget.semanticsTooltip ?? '') - : widget.semanticsTooltip == message); - }, skipOffstage: skipOffstage); -} diff --git a/packages/material_ui/test/utils/finders.dart b/packages/material_ui/test/utils/finders.dart new file mode 100644 index 000000000000..812f00222279 --- /dev/null +++ b/packages/material_ui/test/utils/finders.dart @@ -0,0 +1,44 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:material_ui/material_ui.dart'; + +/// Finds [RawTooltip] or [Tooltip] widgets with the given `message`. +/// +/// ## Sample code +/// +/// ```dart +/// expect(find.byTooltip('Back'), findsOneWidget); +/// expect(find.byTooltip(RegExp('Back.*')), findsNWidgets(2)); +/// ``` +/// +/// If the `skipOffstage` argument is true (the default), then this skips +/// nodes that are [Offstage] or that are from inactive [Route]s. +/// +/// This was copied from flutter_test, which uses flutter/material.dart. +/// +// TODO(justinmc): Port flutter_test to material_ui, then delete this method and +// use that one. See https://github.com/flutter/flutter/issues/186966 +Finder findByTooltip(Pattern message, {bool skipOffstage = true}) { + return find.byWidgetPredicate((Widget widget) { + // Compare RawTooltip's semantics tooltip with the given message. + // However, Tooltip's message needs to be checked directly if: + // 1. Tooltip.excludeFromSemantics is true, since in this case Tooltip + // provides no semantics tooltip to the underlying RawTooltip. + // 2. Tooltip.message and Tooltip.richMessage are empty, since in this + // case no RawTooltip is created. + if (widget is Tooltip) { + //if (widget.runtimeType == 'Tooltip') { + final String tooltipMessage = widget.message ?? widget.richMessage!.toPlainText(); + if ((widget.excludeFromSemantics ?? false) || tooltipMessage.isEmpty) { + return message is RegExp ? message.hasMatch(tooltipMessage) : tooltipMessage == message; + } + } + return widget is RawTooltip && + (message is RegExp + ? message.hasMatch(widget.semanticsTooltip ?? '') + : widget.semanticsTooltip == message); + }, skipOffstage: skipOffstage); +} From 8f74b21ddf3544eb88ccffe6055f4771d23e6c8d Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:39:39 -0700 Subject: [PATCH 3/4] Move finders.dart into /test directory --- packages/material_ui/test/bottom_navigation_bar_test.dart | 2 +- packages/material_ui/test/{utils => }/finders.dart | 0 packages/material_ui/test/navigation_bar_test.dart | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename packages/material_ui/test/{utils => }/finders.dart (100%) diff --git a/packages/material_ui/test/bottom_navigation_bar_test.dart b/packages/material_ui/test/bottom_navigation_bar_test.dart index f208c0465a22..f811f1db0730 100644 --- a/packages/material_ui/test/bottom_navigation_bar_test.dart +++ b/packages/material_ui/test/bottom_navigation_bar_test.dart @@ -16,8 +16,8 @@ import 'package:material_ui/material_ui.dart'; import 'package:vector_math/vector_math_64.dart' show Vector3; import 'feedback_tester.dart'; +import 'finders.dart'; import 'semantics_tester.dart'; -import 'utils/finders.dart'; void main() { testWidgets('BottomNavigationBar callback test', (WidgetTester tester) async { diff --git a/packages/material_ui/test/utils/finders.dart b/packages/material_ui/test/finders.dart similarity index 100% rename from packages/material_ui/test/utils/finders.dart rename to packages/material_ui/test/finders.dart diff --git a/packages/material_ui/test/navigation_bar_test.dart b/packages/material_ui/test/navigation_bar_test.dart index b2bfdfe50763..63a6b585e75a 100644 --- a/packages/material_ui/test/navigation_bar_test.dart +++ b/packages/material_ui/test/navigation_bar_test.dart @@ -14,7 +14,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:material_ui/material_ui.dart'; -import 'utils/finders.dart'; +import 'finders.dart'; void main() { testWidgets('Navigation bar updates destinations when tapped', (WidgetTester tester) async { From 1fd588937b8303fe8442aa6c3f149879b0aca510 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:46:44 -0700 Subject: [PATCH 4/4] Delete commented out line --- packages/material_ui/test/finders.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/material_ui/test/finders.dart b/packages/material_ui/test/finders.dart index 812f00222279..df70ae699958 100644 --- a/packages/material_ui/test/finders.dart +++ b/packages/material_ui/test/finders.dart @@ -30,7 +30,6 @@ Finder findByTooltip(Pattern message, {bool skipOffstage = true}) { // 2. Tooltip.message and Tooltip.richMessage are empty, since in this // case no RawTooltip is created. if (widget is Tooltip) { - //if (widget.runtimeType == 'Tooltip') { final String tooltipMessage = widget.message ?? widget.richMessage!.toPlainText(); if ((widget.excludeFromSemantics ?? false) || tooltipMessage.isEmpty) { return message is RegExp ? message.hasMatch(tooltipMessage) : tooltipMessage == message;