diff --git a/.ci/targets/web_dart_unit_tests.yaml b/.ci/targets/web_dart_unit_tests.yaml index 16cdf1771bb0..a60208450f26 100644 --- a/.ci/targets/web_dart_unit_tests.yaml +++ b/.ci/targets/web_dart_unit_tests.yaml @@ -7,5 +7,6 @@ tasks: args: [ "dart-test", "--platform=chrome", + "--package-tags=script/configs/web_dart_unit_test_tags.yaml", "--exclude=script/configs/dart_unit_tests_exceptions.yaml" ] diff --git a/packages/material_ui/dart_test.yaml b/packages/material_ui/dart_test.yaml new file mode 100644 index 000000000000..f3c317bcfaec --- /dev/null +++ b/packages/material_ui/dart_test.yaml @@ -0,0 +1,2 @@ +tags: + reduced-web-test-set: \ No newline at end of file diff --git a/packages/material_ui/example/dart_test.yaml b/packages/material_ui/example/dart_test.yaml new file mode 100644 index 000000000000..1462a6c0c0e2 --- /dev/null +++ b/packages/material_ui/example/dart_test.yaml @@ -0,0 +1,2 @@ +tags: + reduced-web-test-set: diff --git a/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.2_test.dart b/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.2_test.dart index 258c468a1652..d4e703d0fe02 100644 --- a/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.2_test.dart +++ b/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.2_test.dart @@ -95,5 +95,6 @@ void main() { expect(find.text('Paste'), findsNothing); expect(find.text('Select all'), findsNothing); }, + tags: 'reduced-web-test-set', ); } diff --git a/packages/material_ui/example/test/context_menu/selectable_region_toolbar_builder.0_test.dart b/packages/material_ui/example/test/context_menu/selectable_region_toolbar_builder.0_test.dart index 247a0eb1513a..f40ead43f23f 100644 --- a/packages/material_ui/example/test/context_menu/selectable_region_toolbar_builder.0_test.dart +++ b/packages/material_ui/example/test/context_menu/selectable_region_toolbar_builder.0_test.dart @@ -68,5 +68,5 @@ void main() { await tester.pumpAndSettle(); expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - }); + }, tags: 'reduced-web-test-set'); } diff --git a/packages/material_ui/example/test/selection_area/selection_area.2_test.dart b/packages/material_ui/example/test/selection_area/selection_area.2_test.dart index e08387b50dd6..2042b00da760 100644 --- a/packages/material_ui/example/test/selection_area/selection_area.2_test.dart +++ b/packages/material_ui/example/test/selection_area/selection_area.2_test.dart @@ -298,5 +298,6 @@ void main() { isNull, ); }, + tags: 'reduced-web-test-set', ); } diff --git a/packages/material_ui/example/test/text_form_field/text_form_field.1_test.dart b/packages/material_ui/example/test/text_form_field/text_form_field.1_test.dart index a0d3b579c0ca..9b43d8ac7adb 100644 --- a/packages/material_ui/example/test/text_form_field/text_form_field.1_test.dart +++ b/packages/material_ui/example/test/text_form_field/text_form_field.1_test.dart @@ -65,5 +65,5 @@ void main() { } else { expect(getFocuses(), const [true, false, false, false, false]); } - }); + }, tags: 'reduced-web-test-set'); } diff --git a/packages/material_ui/test/action_chip_test.dart b/packages/material_ui/test/action_chip_test.dart index c9e24a9d9dc5..1c517df9c8ed 100644 --- a/packages/material_ui/test/action_chip_test.dart +++ b/packages/material_ui/test/action_chip_test.dart @@ -527,7 +527,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('ActionChip mouse cursor behavior', (WidgetTester tester) async { const SystemMouseCursor customCursor = SystemMouseCursors.grab; diff --git a/packages/material_ui/test/back_button_test.dart b/packages/material_ui/test/back_button_test.dart index e8e03ff6b4ea..a351b083eca2 100644 --- a/packages/material_ui/test/back_button_test.dart +++ b/packages/material_ui/test/back_button_test.dart @@ -122,7 +122,7 @@ void main() { expect(macOSIcon.icon == androidIcon.icon, kIsWeb ? isTrue : isFalse); expect(macOSIcon.icon == iOSIcon.icon, isTrue); expect(windowsIcon.icon == androidIcon.icon, isTrue); - }); + }, tags: 'reduced-web-test-set'); testWidgets('BackButton color', (WidgetTester tester) async { await tester.pumpWidget( @@ -399,7 +399,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('CloseButton has expected default mouse cursor on hover', ( WidgetTester tester, @@ -421,7 +421,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('BackButton has expected mouse cursor when explicitly configured', ( WidgetTester tester, diff --git a/packages/material_ui/test/checkbox_list_tile_test.dart b/packages/material_ui/test/checkbox_list_tile_test.dart index 6bde4a97a3ea..7f56619f45ac 100644 --- a/packages/material_ui/test/checkbox_list_tile_test.dart +++ b/packages/material_ui/test/checkbox_list_tile_test.dart @@ -650,7 +650,7 @@ void main() { ); await tester.pumpAndSettle(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('CheckboxListTile respects fillColor in enabled/disabled states', ( WidgetTester tester, @@ -1039,6 +1039,7 @@ void main() { await gesture4.up(); await tester.pumpAndSettle(); }, + tags: 'reduced-web-test-set', ); testWidgets('CheckboxListTile respects splashRadius', (WidgetTester tester) async { diff --git a/packages/material_ui/test/checkbox_test.dart b/packages/material_ui/test/checkbox_test.dart index ba1dd7808dff..882bcf0c477f 100644 --- a/packages/material_ui/test/checkbox_test.dart +++ b/packages/material_ui/test/checkbox_test.dart @@ -1062,7 +1062,7 @@ void main() { await tester.sendKeyEvent(LogicalKeyboardKey.space); await tester.pumpAndSettle(); expect(value, isTrue); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'Material3 - Checkbox visual density cannot be overridden by ThemeData.visualDensity', @@ -1328,7 +1328,7 @@ void main() { ); await tester.pumpAndSettle(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Checkbox fill color resolves in enabled/disabled states', ( WidgetTester tester, @@ -2383,6 +2383,7 @@ void main() { TargetPlatform.iOS, TargetPlatform.macOS, }), + tags: 'reduced-web-test-set', ); testWidgets('Material2 - Checkbox respects fillColor when it is unchecked', ( diff --git a/packages/material_ui/test/chip_test.dart b/packages/material_ui/test/chip_test.dart index 07a73c7b9d7a..9699a7598a13 100644 --- a/packages/material_ui/test/chip_test.dart +++ b/packages/material_ui/test/chip_test.dart @@ -2229,7 +2229,7 @@ void main() { expect(getSelectProgress(tester), equals(0.0)); expect(getAvatarDrawerProgress(tester), equals(1.0)); expect(getDeleteDrawerProgress(tester), equals(0.0)); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Material2 - Selection without avatar works as expected on RawChip', ( WidgetTester tester, @@ -2390,7 +2390,7 @@ void main() { expect(getSelectProgress(tester), equals(0.0)); expect(getAvatarDrawerProgress(tester), equals(0.0)); expect(getDeleteDrawerProgress(tester), equals(0.0)); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Material2 - Activation works as expected on RawChip', (WidgetTester tester) async { var selected = false; @@ -2503,7 +2503,7 @@ void main() { expect(getAvatarDrawerProgress(tester), equals(1.0)); expect(getDeleteDrawerProgress(tester), equals(0.0)); await tester.pumpAndSettle(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Chip uses ThemeData chip theme if present', (WidgetTester tester) async { final theme = ThemeData(chipTheme: const ChipThemeData(backgroundColor: Color(0xffff0000))); @@ -2876,7 +2876,7 @@ void main() { ), ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('delete', (WidgetTester tester) async { final semanticsTester = SemanticsTester(tester); @@ -2940,7 +2940,7 @@ void main() { ), ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('with onPressed', (WidgetTester tester) async { final semanticsTester = SemanticsTester(tester); @@ -2994,7 +2994,7 @@ void main() { ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('with onSelected', (WidgetTester tester) async { final semanticsTester = SemanticsTester(tester); @@ -3117,7 +3117,7 @@ void main() { ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('disabled', (WidgetTester tester) async { final semanticsTester = SemanticsTester(tester); @@ -3169,7 +3169,7 @@ void main() { ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('tapEnabled explicitly false', (WidgetTester tester) async { final semanticsTester = SemanticsTester(tester); @@ -3218,7 +3218,7 @@ void main() { ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('enabled when tapEnabled and canTap', (WidgetTester tester) async { final semanticsTester = SemanticsTester(tester); @@ -3273,7 +3273,7 @@ void main() { ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('disabled when tapEnabled but not canTap', (WidgetTester tester) async { final semanticsTester = SemanticsTester(tester); @@ -3322,7 +3322,7 @@ void main() { ); semanticsTester.dispose(); - }); + }, tags: 'reduced-web-test-set'); }); testWidgets('can be tapped outside of chip delete icon', (WidgetTester tester) async { diff --git a/packages/material_ui/test/choice_chip_test.dart b/packages/material_ui/test/choice_chip_test.dart index e2c84f5b5a6b..b6815ec2c177 100644 --- a/packages/material_ui/test/choice_chip_test.dart +++ b/packages/material_ui/test/choice_chip_test.dart @@ -791,7 +791,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('ChoiceChip mouse cursor behavior', (WidgetTester tester) async { const SystemMouseCursor customCursor = SystemMouseCursors.grab; diff --git a/packages/material_ui/test/data_table_test.dart b/packages/material_ui/test/data_table_test.dart index e3d9a7b7ac14..ab51281c3535 100644 --- a/packages/material_ui/test/data_table_test.dart +++ b/packages/material_ui/test/data_table_test.dart @@ -2105,7 +2105,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.copy, ); - }); + }, tags: 'reduced-web-test-set'); // This is a regression test for https://github.com/flutter/flutter/issues/114470. testWidgets('DataTable text styles are merged with default text style', ( diff --git a/packages/material_ui/test/date_picker_theme_test.dart b/packages/material_ui/test/date_picker_theme_test.dart index 5934277038a9..86c300e425b0 100644 --- a/packages/material_ui/test/date_picker_theme_test.dart +++ b/packages/material_ui/test/date_picker_theme_test.dart @@ -1062,7 +1062,7 @@ void main() { ..circle() // Selected day decoration. ..circle(color: dayOverlayColor.resolve({WidgetState.focused})), ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('DatePickerDialog resolves DatePickerTheme.yearOverlayColor states', ( WidgetTester tester, @@ -1216,7 +1216,7 @@ void main() { ..circle(color: rangeSelectionOverlayColor.resolve({WidgetState.pressed})), ); } - }); + }, tags: 'reduced-web-test-set'); testWidgets('YearPicker maintains default year shape at textScaleFactor 1, 1.5, 2', ( WidgetTester tester, diff --git a/packages/material_ui/test/drawer_button_test.dart b/packages/material_ui/test/drawer_button_test.dart index d87d430bad99..952ea8e8e971 100644 --- a/packages/material_ui/test/drawer_button_test.dart +++ b/packages/material_ui/test/drawer_button_test.dart @@ -311,7 +311,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('EndDrawerButton has expected default mouse cursor on hover', ( WidgetTester tester, @@ -334,7 +334,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('DrawerButton has expected mouse cursor when explicitly configured', ( WidgetTester tester, diff --git a/packages/material_ui/test/dropdown_form_field_test.dart b/packages/material_ui/test/dropdown_form_field_test.dart index 4b6deb5f8f6c..ade35fda44b3 100644 --- a/packages/material_ui/test/dropdown_form_field_test.dart +++ b/packages/material_ui/test/dropdown_form_field_test.dart @@ -1497,7 +1497,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('DropdownButtonFormField has expected mouse cursor when explicitly configured', ( WidgetTester tester, diff --git a/packages/material_ui/test/dropdown_menu_test.dart b/packages/material_ui/test/dropdown_menu_test.dart index e0e253e93e32..a33606bb13b7 100644 --- a/packages/material_ui/test/dropdown_menu_test.dart +++ b/packages/material_ui/test/dropdown_menu_test.dart @@ -3018,7 +3018,7 @@ void main() { await tester.tap(findMenuItemText('Item 0')); await tester.pumpAndSettle(); expect(controller.text, 'Item 0 $longText'); - }); + }, tags: 'reduced-web-test-set'); testWidgets('DropdownMenuEntry.labelWidget is Text that specifies maxLines 1 or 2', ( WidgetTester tester, @@ -3080,7 +3080,7 @@ void main() { await tester.tap(find.byType(TextField)); await tester.pumpAndSettle(); expect(controller.text, ''); // nothing selected - }); + }, tags: 'reduced-web-test-set'); // Regression test for https://github.com/flutter/flutter/issues/131350. testWidgets('DropdownMenuEntry.leadingIcon default layout', (WidgetTester tester) async { @@ -3750,7 +3750,7 @@ void main() { textDirection: TextDirection.ltr, ), ); - }); + }, tags: 'reduced-web-test-set'); // This is a regression test for https://github.com/flutter/flutter/issues/151854. testWidgets('scrollToHighlight does not scroll parent', (WidgetTester tester) async { @@ -4450,7 +4450,7 @@ void main() { ); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('restorationId is passed to inner TextField', (WidgetTester tester) async { const restorationId = 'dropdown_menu'; diff --git a/packages/material_ui/test/dropdown_test.dart b/packages/material_ui/test/dropdown_test.dart index 1e8d2d6b2451..ca0798a8af37 100644 --- a/packages/material_ui/test/dropdown_test.dart +++ b/packages/material_ui/test/dropdown_test.dart @@ -4007,7 +4007,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('DropdownButton changes mouse cursor when hovered as expected', ( WidgetTester tester, @@ -4080,7 +4080,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('DropdownButton has expected mouse cursor when explicitly configured', ( WidgetTester tester, diff --git a/packages/material_ui/test/elevated_button_test.dart b/packages/material_ui/test/elevated_button_test.dart index 2ebc99bb070a..c9063999b43e 100644 --- a/packages/material_ui/test/elevated_button_test.dart +++ b/packages/material_ui/test/elevated_button_test.dart @@ -1629,30 +1629,33 @@ void main() { } }); - testWidgets('ElevatedButton uses InkSparkle only for Android non-web when useMaterial3 is true', ( - WidgetTester tester, - ) async { - final theme = ThemeData(); + testWidgets( + 'ElevatedButton uses InkSparkle only for Android non-web when useMaterial3 is true', + (WidgetTester tester) async { + final theme = ThemeData(); - await tester.pumpWidget( - MaterialApp( - theme: theme, - home: Center( - child: ElevatedButton(onPressed: () {}, child: const Text('button')), + await tester.pumpWidget( + MaterialApp( + theme: theme, + home: Center( + child: ElevatedButton(onPressed: () {}, child: const Text('button')), + ), ), - ), - ); + ); - final InkWell buttonInkWell = tester.widget( - find.descendant(of: find.byType(ElevatedButton), matching: find.byType(InkWell)), - ); + final InkWell buttonInkWell = tester.widget( + find.descendant(of: find.byType(ElevatedButton), matching: find.byType(InkWell)), + ); - if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { - expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); - } else { - expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); - } - }, variant: TargetPlatformVariant.all()); + if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { + expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); + } else { + expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); + } + }, + variant: TargetPlatformVariant.all(), + tags: 'reduced-web-test-set', + ); testWidgets('ElevatedButton uses InkRipple when useMaterial3 is false', ( WidgetTester tester, @@ -1892,7 +1895,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('ElevatedButton in SelectionArea changes mouse cursor when hovered', ( WidgetTester tester, diff --git a/packages/material_ui/test/filled_button_test.dart b/packages/material_ui/test/filled_button_test.dart index eae0fc9e7984..544e81842ae6 100644 --- a/packages/material_ui/test/filled_button_test.dart +++ b/packages/material_ui/test/filled_button_test.dart @@ -1342,7 +1342,7 @@ void main() { final tallerWidget = iconRect.height > labelRect.height ? iconRect : labelRect; expect(paddingRect.top, closeOnWeb(tallerWidget.top - 6.5)); expect(paddingRect.bottom, closeOnWeb(tallerWidget.bottom + 13.5)); - }); + }, tags: 'reduced-web-test-set'); group('Default FilledButton padding for textScaleFactor, textDirection', () { const buttonKey = ValueKey('button'); @@ -1763,30 +1763,33 @@ void main() { } }); - testWidgets('FilledButton uses InkSparkle only for Android non-web when useMaterial3 is true', ( - WidgetTester tester, - ) async { - final theme = ThemeData(); + testWidgets( + 'FilledButton uses InkSparkle only for Android non-web when useMaterial3 is true', + (WidgetTester tester) async { + final theme = ThemeData(); - await tester.pumpWidget( - MaterialApp( - theme: theme, - home: Center( - child: FilledButton(onPressed: () {}, child: const Text('button')), + await tester.pumpWidget( + MaterialApp( + theme: theme, + home: Center( + child: FilledButton(onPressed: () {}, child: const Text('button')), + ), ), - ), - ); + ); - final InkWell buttonInkWell = tester.widget( - find.descendant(of: find.byType(FilledButton), matching: find.byType(InkWell)), - ); + final InkWell buttonInkWell = tester.widget( + find.descendant(of: find.byType(FilledButton), matching: find.byType(InkWell)), + ); - if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { - expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); - } else { - expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); - } - }, variant: TargetPlatformVariant.all()); + if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { + expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); + } else { + expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); + } + }, + variant: TargetPlatformVariant.all(), + tags: 'reduced-web-test-set', + ); testWidgets('FilledButton.icon does not overflow', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/77815 @@ -2006,7 +2009,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('FilledButton in SelectionArea changes mouse cursor when hovered', ( WidgetTester tester, diff --git a/packages/material_ui/test/filter_chip_test.dart b/packages/material_ui/test/filter_chip_test.dart index d9748fc7860e..325cb7543e13 100644 --- a/packages/material_ui/test/filter_chip_test.dart +++ b/packages/material_ui/test/filter_chip_test.dart @@ -1290,7 +1290,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('FilterChip mouse cursor behavior', (WidgetTester tester) async { const SystemMouseCursor customCursor = SystemMouseCursors.grab; diff --git a/packages/material_ui/test/floating_action_button_test.dart b/packages/material_ui/test/floating_action_button_test.dart index b91a5fed47ea..0176cf54b814 100644 --- a/packages/material_ui/test/floating_action_button_test.dart +++ b/packages/material_ui/test/floating_action_button_test.dart @@ -898,7 +898,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Floating Action Button has no clip by default', (WidgetTester tester) async { final focusNode = FocusNode(); diff --git a/packages/material_ui/test/icon_button_test.dart b/packages/material_ui/test/icon_button_test.dart index 3b58f4ba535e..52e02c09c426 100644 --- a/packages/material_ui/test/icon_button_test.dart +++ b/packages/material_ui/test/icon_button_test.dart @@ -833,7 +833,7 @@ void main() { expect(focusNode1.hasPrimaryFocus, !kIsWeb); expect(focusNode2.hasPrimaryFocus, isFalse); - }); + }, tags: 'reduced-web-test-set'); group('feedback', () { late FeedbackTester feedback; @@ -994,7 +994,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('disabled IconButton has basic mouse cursor', (WidgetTester tester) async { await tester.pumpWidget( @@ -3375,61 +3375,64 @@ void main() { expect(onLongPressed, false); }); - testWidgets('does not draw focus color when focused by semantics on the web', ( - WidgetTester tester, - ) async { - // Regression test for https://github.com/flutter/flutter/issues/158527. + testWidgets( + 'does not draw focus color when focused by semantics on the web', + (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/158527. - final focusNode = FocusNode(); - addTearDown(focusNode.dispose); + final focusNode = FocusNode(); + addTearDown(focusNode.dispose); - const Color focusColor = Colors.orange; + const Color focusColor = Colors.orange; - await tester.pumpWidget( - MaterialApp( - home: Center( - child: IconButton( - focusColor: focusColor, - focusNode: focusNode, - icon: const Icon(Icons.headphones), - onPressed: () {}, + await tester.pumpWidget( + MaterialApp( + home: Center( + child: IconButton( + focusColor: focusColor, + focusNode: focusNode, + icon: const Icon(Icons.headphones), + onPressed: () {}, + ), ), ), - ), - ); + ); - // Make sure we are in "traditional mode" where the button could potentially draw focus highlights. - await tester.sendKeyEvent(LogicalKeyboardKey.enter); - await tester.pumpAndSettle(); - expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.traditional)); + // Make sure we are in "traditional mode" where the button could potentially draw focus highlights. + await tester.sendKeyEvent(LogicalKeyboardKey.enter); + await tester.pumpAndSettle(); + expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.traditional)); - expect(focusNode.hasFocus, isFalse); + expect(focusNode.hasFocus, isFalse); - // Focus on it with semantics. - tester.platformDispatcher.onSemanticsActionEvent!( - SemanticsActionEvent( - type: SemanticsAction.focus, - viewId: tester.view.viewId, - nodeId: tester.semantics.find(find.byIcon(Icons.headphones)).id, - ), - ); - await tester.pumpAndSettle(); + // Focus on it with semantics. + tester.platformDispatcher.onSemanticsActionEvent!( + SemanticsActionEvent( + type: SemanticsAction.focus, + viewId: tester.view.viewId, + nodeId: tester.semantics.find(find.byIcon(Icons.headphones)).id, + ), + ); + await tester.pumpAndSettle(); - // Make sure no focus highlight was drawn. - final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) { - return object.runtimeType.toString() == '_RenderInkFeatures'; - }); - expect(focusNode.hasFocus, isTrue); - expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.touch)); - expect(inkFeatures, isNot(paints..rect(color: focusColor))); + // Make sure no focus highlight was drawn. + final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) { + return object.runtimeType.toString() == '_RenderInkFeatures'; + }); + expect(focusNode.hasFocus, isTrue); + expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.touch)); + expect(inkFeatures, isNot(paints..rect(color: focusColor))); - // Check that focus highlight is drawn in traditional mode. - await tester.sendKeyEvent(LogicalKeyboardKey.enter); - await tester.pumpAndSettle(); - expect(focusNode.hasFocus, isTrue); - expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.traditional)); - expect(inkFeatures, paints..rect(color: focusColor)); - }, skip: !isBrowser); // [intended] tests web-specific behavior. + // Check that focus highlight is drawn in traditional mode. + await tester.sendKeyEvent(LogicalKeyboardKey.enter); + await tester.pumpAndSettle(); + expect(focusNode.hasFocus, isTrue); + expect(FocusManager.instance.highlightMode, equals(FocusHighlightMode.traditional)); + expect(inkFeatures, paints..rect(color: focusColor)); + }, + tags: 'reduced-web-test-set', + skip: !isBrowser, // [intended] tests web-specific behavior. + ); testWidgets("IconButton's outline should be behind its child", (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/167431 diff --git a/packages/material_ui/test/ink_paint_test.dart b/packages/material_ui/test/ink_paint_test.dart index e2707a77dbe4..96faea686d6a 100644 --- a/packages/material_ui/test/ink_paint_test.dart +++ b/packages/material_ui/test/ink_paint_test.dart @@ -153,7 +153,7 @@ void main() { ); await gesture.up(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('The InkWell widget renders an ink ripple', (WidgetTester tester) async { const highlightColor = Color(0xAAFF0000); diff --git a/packages/material_ui/test/ink_splash_test.dart b/packages/material_ui/test/ink_splash_test.dart index 996a86d52c5d..3df2edd4bac8 100644 --- a/packages/material_ui/test/ink_splash_test.dart +++ b/packages/material_ui/test/ink_splash_test.dart @@ -126,7 +126,7 @@ void main() { await gesture.up(); await tester.pumpAndSettle(); } - }); + }, tags: 'reduced-web-test-set'); // Regression test for https://github.com/flutter/flutter/issues/136441. testWidgets('PageView item can dispose when widget with NoSplash.splashFactory is tapped', ( diff --git a/packages/material_ui/test/ink_well_test.dart b/packages/material_ui/test/ink_well_test.dart index 28f045711ce5..c5d6b09271dd 100644 --- a/packages/material_ui/test/ink_well_test.dart +++ b/packages/material_ui/test/ink_well_test.dart @@ -1230,7 +1230,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('InkResponse containing selectable text changes mouse cursor when hovered', ( WidgetTester tester, @@ -1258,7 +1258,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); group('feedback', () { late FeedbackTester feedback; diff --git a/packages/material_ui/test/input_chip_test.dart b/packages/material_ui/test/input_chip_test.dart index ba6dca69f01b..0bb6ac35b2dc 100644 --- a/packages/material_ui/test/input_chip_test.dart +++ b/packages/material_ui/test/input_chip_test.dart @@ -631,7 +631,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('InputChip mouse cursor behavior', (WidgetTester tester) async { const SystemMouseCursor customCursor = SystemMouseCursors.grab; diff --git a/packages/material_ui/test/input_decorator_test.dart b/packages/material_ui/test/input_decorator_test.dart index 4c4529dc4f0a..bca37c3a8d8e 100644 --- a/packages/material_ui/test/input_decorator_test.dart +++ b/packages/material_ui/test/input_decorator_test.dart @@ -15221,7 +15221,7 @@ void main() { // Ideographic (incorrect) value is 50.299999713897705 expect(tester.getBottomLeft(find.text('hint')).dy, isBrowser ? 45.75 : 47.75); - }); + }, tags: 'reduced-web-test-set'); testWidgets('InputDecorator floating label Y coordinate', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/54028 diff --git a/packages/material_ui/test/list_tile_test.dart b/packages/material_ui/test/list_tile_test.dart index 39bc0d034523..9d395b23b7c0 100644 --- a/packages/material_ui/test/list_tile_test.dart +++ b/packages/material_ui/test/list_tile_test.dart @@ -2775,7 +2775,7 @@ void main() { 'See also:\n' 'https://api.flutter.dev/flutter/material/ListTile-class.html#material.ListTile.4\n', ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('trailing', (WidgetTester tester) async { // Test a trailing widget that exceeds the list tile width. @@ -2802,7 +2802,7 @@ void main() { 'See also:\n' 'https://api.flutter.dev/flutter/material/ListTile-class.html#material.ListTile.4\n', ); - }); + }, tags: 'reduced-web-test-set'); }); group('Material 2', () { diff --git a/packages/material_ui/test/material_button_test.dart b/packages/material_ui/test/material_button_test.dart index 504ce70fa218..8ed9b0f8c3c9 100644 --- a/packages/material_ui/test/material_button_test.dart +++ b/packages/material_ui/test/material_button_test.dart @@ -483,7 +483,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); // This test is very similar to the '...explicit splashColor and highlightColor' test // in icon_button_test.dart. If you change this one, you may want to also change that one. diff --git a/packages/material_ui/test/menu_anchor_test.dart b/packages/material_ui/test/menu_anchor_test.dart index f54165756b32..6d7ed6b022e7 100644 --- a/packages/material_ui/test/menu_anchor_test.dart +++ b/packages/material_ui/test/menu_anchor_test.dart @@ -2477,7 +2477,7 @@ void main() { await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); await tester.pump(); expect(focusedMenu, equals('MenuItemButton(Text("Submenu item 1"))')); - }); + }, tags: 'reduced-web-test-set'); }); group('Accelerators', () { @@ -4508,7 +4508,7 @@ void main() { ); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('MenuItemButton semantics respects label', (WidgetTester tester) async { final semantics = SemanticsTester(tester); @@ -4578,7 +4578,7 @@ void main() { ); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('SubmenuButton expanded/collapsed state', (WidgetTester tester) async { final semantics = SemanticsTester(tester); @@ -4742,7 +4742,7 @@ void main() { ); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Animated SubmenuButton expanded/collapsed state', (WidgetTester tester) async { final semantics = SemanticsTester(tester); @@ -5486,7 +5486,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('MenuItemButton has expected default mouse cursor on hover', ( WidgetTester tester, @@ -5530,7 +5530,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('CheckboxMenuButton has expected default mouse cursor on hover', ( WidgetTester tester, @@ -5566,7 +5566,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('RadioMenuButton has expected default mouse cursor on hover', ( WidgetTester tester, @@ -5603,7 +5603,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('MenuItemButton has expected mouse cursor when explicitly configured', ( WidgetTester tester, diff --git a/packages/material_ui/test/navigation_bar_test.dart b/packages/material_ui/test/navigation_bar_test.dart index 63a6b585e75a..5459b39cf292 100644 --- a/packages/material_ui/test/navigation_bar_test.dart +++ b/packages/material_ui/test/navigation_bar_test.dart @@ -557,7 +557,7 @@ void main() { hasFocusAction: true, ), ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Navigation bar disabled semantics', (WidgetTester tester) async { Widget widget({int selectedIndex = 0}) { return _buildWidget( @@ -584,7 +584,7 @@ void main() { isButton: true, ), ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Navigation bar semantics with some labels hidden', (WidgetTester tester) async { Widget widget({int selectedIndex = 0}) { @@ -663,7 +663,7 @@ void main() { hasFocusAction: true, ), ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Navigation bar does not grow with text scale factor', (WidgetTester tester) async { const animationMilliseconds = 800; @@ -1214,7 +1214,7 @@ void main() { ..circle() ..circle(color: focusColor)), ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('NavigationBar.labelPadding overrides NavigationDestination.label padding', ( WidgetTester tester, diff --git a/packages/material_ui/test/navigation_bar_theme_test.dart b/packages/material_ui/test/navigation_bar_theme_test.dart index 38a78326660c..07d065b7f495 100644 --- a/packages/material_ui/test/navigation_bar_theme_test.dart +++ b/packages/material_ui/test/navigation_bar_theme_test.dart @@ -335,6 +335,7 @@ void main() { ..circle(color: focusColor)), ); }, + tags: 'reduced-web-test-set', ); } diff --git a/packages/material_ui/test/outlined_button_test.dart b/packages/material_ui/test/outlined_button_test.dart index 82d58e6019e7..70b1b11b2cdb 100644 --- a/packages/material_ui/test/outlined_button_test.dart +++ b/packages/material_ui/test/outlined_button_test.dart @@ -1858,30 +1858,33 @@ void main() { } }); - testWidgets('OutlinedButton uses InkSparkle only for Android non-web when useMaterial3 is true', ( - WidgetTester tester, - ) async { - final theme = ThemeData(); + testWidgets( + 'OutlinedButton uses InkSparkle only for Android non-web when useMaterial3 is true', + (WidgetTester tester) async { + final theme = ThemeData(); - await tester.pumpWidget( - MaterialApp( - theme: theme, - home: Center( - child: OutlinedButton(onPressed: () {}, child: const Text('button')), + await tester.pumpWidget( + MaterialApp( + theme: theme, + home: Center( + child: OutlinedButton(onPressed: () {}, child: const Text('button')), + ), ), - ), - ); + ); - final InkWell buttonInkWell = tester.widget( - find.descendant(of: find.byType(OutlinedButton), matching: find.byType(InkWell)), - ); + final InkWell buttonInkWell = tester.widget( + find.descendant(of: find.byType(OutlinedButton), matching: find.byType(InkWell)), + ); - if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { - expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); - } else { - expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); - } - }, variant: TargetPlatformVariant.all()); + if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { + expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); + } else { + expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); + } + }, + variant: TargetPlatformVariant.all(), + tags: 'reduced-web-test-set', + ); testWidgets('OutlinedButton uses InkRipple when useMaterial3 is false', ( WidgetTester tester, @@ -2121,7 +2124,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('OutlinedButton in SelectionArea changes mouse cursor when hovered', ( WidgetTester tester, diff --git a/packages/material_ui/test/popup_menu_test.dart b/packages/material_ui/test/popup_menu_test.dart index c93792da530d..4f2f1f4c6fa3 100644 --- a/packages/material_ui/test/popup_menu_test.dart +++ b/packages/material_ui/test/popup_menu_test.dart @@ -2568,7 +2568,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('PopupMenuItem changes mouse cursor when hovered', (WidgetTester tester) async { const Key key = ValueKey(1); @@ -2662,7 +2662,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('CheckedPopupMenuItem changes mouse cursor when hovered', ( WidgetTester tester, @@ -2764,7 +2764,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('PopupMenu in AppBar does not overlap with the status bar', ( WidgetTester tester, diff --git a/packages/material_ui/test/popup_menu_theme_test.dart b/packages/material_ui/test/popup_menu_theme_test.dart index aa46762f2700..bb284a69ae2b 100644 --- a/packages/material_ui/test/popup_menu_theme_test.dart +++ b/packages/material_ui/test/popup_menu_theme_test.dart @@ -250,7 +250,7 @@ void main() { find.byType(SingleChildScrollView), ); expect(popupMenu.padding, const EdgeInsets.symmetric(vertical: 8.0)); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Popup menu uses values from PopupMenuThemeData', (WidgetTester tester) async { final PopupMenuThemeData popupMenuTheme = _popupMenuThemeM3(); @@ -583,7 +583,7 @@ void main() { find.byType(SingleChildScrollView), ); expect(popupMenu.padding, const EdgeInsets.symmetric(vertical: 8.0)); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Popup menu uses values from PopupMenuThemeData', (WidgetTester tester) async { final PopupMenuThemeData popupMenuTheme = _popupMenuThemeM2(); diff --git a/packages/material_ui/test/radio_list_tile_test.dart b/packages/material_ui/test/radio_list_tile_test.dart index 6566e2e35bb7..0f9036aaf36e 100644 --- a/packages/material_ui/test/radio_list_tile_test.dart +++ b/packages/material_ui/test/radio_list_tile_test.dart @@ -901,7 +901,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('RadioListTile respects fillColor in enabled/disabled states', ( WidgetTester tester, diff --git a/packages/material_ui/test/radio_test.dart b/packages/material_ui/test/radio_test.dart index e04305792972..24edcb21163c 100644 --- a/packages/material_ui/test/radio_test.dart +++ b/packages/material_ui/test/radio_test.dart @@ -1005,7 +1005,7 @@ void main() { expect(groupValue, equals(2)); focusNode2.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Radio responds to density changes.', (WidgetTester tester) async { const key = Key('test'); @@ -1130,7 +1130,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Radio button fill color resolves in enabled/disabled states', ( WidgetTester tester, diff --git a/packages/material_ui/test/raw_material_button_test.dart b/packages/material_ui/test/raw_material_button_test.dart index 86a2d230dce4..314eae31e7e2 100644 --- a/packages/material_ui/test/raw_material_button_test.dart +++ b/packages/material_ui/test/raw_material_button_test.dart @@ -110,7 +110,7 @@ void main() { expect(pressed, isTrue); focusNode.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('materialTapTargetSize.padded expands hit test area', (WidgetTester tester) async { var pressed = 0; @@ -651,5 +651,5 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); } diff --git a/packages/material_ui/test/scaffold_test.dart b/packages/material_ui/test/scaffold_test.dart index 45831f55e18b..c00ccaf4effa 100644 --- a/packages/material_ui/test/scaffold_test.dart +++ b/packages/material_ui/test/scaffold_test.dart @@ -1096,6 +1096,7 @@ void main() { TargetPlatform.android, TargetPlatform.fuchsia, }), + tags: 'reduced-web-test-set', ); testWidgets( @@ -2565,7 +2566,7 @@ void main() { ' Builder\n', ); await tester.pumpAndSettle(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Call to Scaffold.geometryOf() without context', (WidgetTester tester) async { ValueListenable? geometry; @@ -2631,7 +2632,7 @@ void main() { ' Builder\n', ); await tester.pumpAndSettle(); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'FloatingActionButton always keeps the same position regardless of extendBodyBehindAppBar', diff --git a/packages/material_ui/test/scrollbar_test.dart b/packages/material_ui/test/scrollbar_test.dart index acb13a21f973..24854684d03f 100644 --- a/packages/material_ui/test/scrollbar_test.dart +++ b/packages/material_ui/test/scrollbar_test.dart @@ -1730,7 +1730,7 @@ void main() { ); scrollController.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'Scrollbar.thumbVisibility triggers assertion when multiple ScrollPositions are attached.', diff --git a/packages/material_ui/test/search_anchor_test.dart b/packages/material_ui/test/search_anchor_test.dart index d810d74dce07..29c04f138ac0 100644 --- a/packages/material_ui/test/search_anchor_test.dart +++ b/packages/material_ui/test/search_anchor_test.dart @@ -3795,7 +3795,7 @@ void main() { expect(find.byType(EditableText), findsOneWidget); final EditableText editableText = tester.widget(find.byType(EditableText)); expect(editableText.scrollPadding, scrollPadding); - }); + }, tags: 'reduced-web-test-set'); group('contextMenuBuilder', () { setUp(() async { @@ -3854,7 +3854,7 @@ void main() { await tester.pumpAndSettle(); expect(find.byType(Placeholder), findsOneWidget); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'iOS uses the system context menu by default if supported', diff --git a/packages/material_ui/test/search_test.dart b/packages/material_ui/test/search_test.dart index 412b2d9a7539..36c859ef076b 100644 --- a/packages/material_ui/test/search_test.dart +++ b/packages/material_ui/test/search_test.dart @@ -682,7 +682,7 @@ void main() { await tester.pumpAndSettle(); expect(find.byWidget(flexibleSpace), findsOneWidget); - }); + }, tags: 'reduced-web-test-set'); group('contributes semantics with custom flexibleSpace', () { const Widget flexibleSpace = Text('FlexibleSpace'); @@ -888,6 +888,7 @@ void main() { TargetPlatform.iOS, TargetPlatform.macOS, }), + tags: 'reduced-web-test-set', ); }); diff --git a/packages/material_ui/test/segmented_button_test.dart b/packages/material_ui/test/segmented_button_test.dart index 250bc9700df1..cbb62c85d9b7 100644 --- a/packages/material_ui/test/segmented_button_test.dart +++ b/packages/material_ui/test/segmented_button_test.dart @@ -1536,7 +1536,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('SegmentedButton has expected mouse cursor when explicitly configured', ( WidgetTester tester, diff --git a/packages/material_ui/test/selectable_text_test.dart b/packages/material_ui/test/selectable_text_test.dart index 1f80b02a937e..069d37216926 100644 --- a/packages/material_ui/test/selectable_text_test.dart +++ b/packages/material_ui/test/selectable_text_test.dart @@ -5019,7 +5019,7 @@ void main() { ); expect(state.selectionOverlay!.handlesAreVisible, isFalse); } - }); + }, tags: 'reduced-web-test-set'); testWidgets('onSelectionChanged is called when selection changes', (WidgetTester tester) async { var onSelectionChangedCallCount = 0; diff --git a/packages/material_ui/test/selection_area_test.dart b/packages/material_ui/test/selection_area_test.dart index e9116ab58ee2..c1fc4240e593 100644 --- a/packages/material_ui/test/selection_area_test.dart +++ b/packages/material_ui/test/selection_area_test.dart @@ -172,6 +172,7 @@ void main() { TargetPlatform.android, TargetPlatform.iOS, }.contains(defaultTargetPlatform), + tags: 'reduced-web-test-set', ); testWidgets( @@ -553,6 +554,7 @@ void main() { expect(paragraph.selections[0], const TextSelection(baseOffset: 8, extentOffset: 22)); }, variant: TargetPlatformVariant.only(TargetPlatform.android), + tags: 'reduced-web-test-set', skip: !kIsWeb, // [intended] on native both selection handles can be dragged at a time. ); diff --git a/packages/material_ui/test/stepper_test.dart b/packages/material_ui/test/stepper_test.dart index da20f9de7e98..538fe7cbd37b 100644 --- a/packages/material_ui/test/stepper_test.dart +++ b/packages/material_ui/test/stepper_test.dart @@ -532,7 +532,7 @@ void main() { 'https://material.io/archive/guidelines/components/steppers.html#steppers-usage', ), ); - }); + }, tags: 'reduced-web-test-set'); ///https://github.com/flutter/flutter/issues/16920 testWidgets('Stepper icons size test', (WidgetTester tester) async { diff --git a/packages/material_ui/test/switch_test.dart b/packages/material_ui/test/switch_test.dart index 0cf34e74849b..7c642531a87f 100644 --- a/packages/material_ui/test/switch_test.dart +++ b/packages/material_ui/test/switch_test.dart @@ -1254,7 +1254,7 @@ void main() { await gesture.removePointer(location: tester.getCenter(find.byType(Switch))); await tester.pump(); } - }); + }, tags: 'reduced-web-test-set'); testWidgets('Switch.adaptive default thumb/track color and size(Cupertino)', ( WidgetTester tester, @@ -2058,7 +2058,7 @@ void main() { await tester.sendKeyEvent(LogicalKeyboardKey.space); await tester.pumpAndSettle(); expect(value, isTrue); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Switch changes mouse cursor when hovered', (WidgetTester tester) async { // Test Switch.adaptive() constructor diff --git a/packages/material_ui/test/tabs_test.dart b/packages/material_ui/test/tabs_test.dart index d3412668ffb3..2de74361d9fa 100644 --- a/packages/material_ui/test/tabs_test.dart +++ b/packages/material_ui/test/tabs_test.dart @@ -4332,7 +4332,7 @@ void main() { expect(semantics, hasSemantics(expectedSemantics)); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('correct scrolling semantics', (WidgetTester tester) async { final semantics = SemanticsTester(tester); @@ -4411,7 +4411,7 @@ void main() { expect(semantics, includesNodeWith(label: tab10title, flags: hiddenFlags)); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('TabBar etc with zero tabs', (WidgetTester tester) async { final TabController controller = createTabController(vsync: const TestVSync(), length: 0); @@ -4617,7 +4617,7 @@ void main() { expect(semantics, hasSemantics(expectedSemantics)); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets('can be notified of TabBar onTap behavior', (WidgetTester tester) async { var tabIndex = -1; @@ -6469,7 +6469,7 @@ void main() { ); semantics.dispose(); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'Change the TabController should make both TabBar and TabBarView return to the initial index.', diff --git a/packages/material_ui/test/text_button_test.dart b/packages/material_ui/test/text_button_test.dart index 5675a0a0abe9..bcbde0ec7bc8 100644 --- a/packages/material_ui/test/text_button_test.dart +++ b/packages/material_ui/test/text_button_test.dart @@ -1572,30 +1572,33 @@ void main() { } }); - testWidgets('TextButton uses InkSparkle only for Android non-web when useMaterial3 is true', ( - WidgetTester tester, - ) async { - final theme = ThemeData(); + testWidgets( + 'TextButton uses InkSparkle only for Android non-web when useMaterial3 is true', + (WidgetTester tester) async { + final theme = ThemeData(); - await tester.pumpWidget( - MaterialApp( - theme: theme, - home: Center( - child: TextButton(onPressed: () {}, child: const Text('button')), + await tester.pumpWidget( + MaterialApp( + theme: theme, + home: Center( + child: TextButton(onPressed: () {}, child: const Text('button')), + ), ), - ), - ); + ); - final InkWell buttonInkWell = tester.widget( - find.descendant(of: find.byType(TextButton), matching: find.byType(InkWell)), - ); + final InkWell buttonInkWell = tester.widget( + find.descendant(of: find.byType(TextButton), matching: find.byType(InkWell)), + ); - if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { - expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); - } else { - expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); - } - }, variant: TargetPlatformVariant.all()); + if (debugDefaultTargetPlatformOverride! == TargetPlatform.android && !kIsWeb) { + expect(buttonInkWell.splashFactory, equals(InkSparkle.splashFactory)); + } else { + expect(buttonInkWell.splashFactory, equals(InkRipple.splashFactory)); + } + }, + variant: TargetPlatformVariant.all(), + tags: 'reduced-web-test-set', + ); testWidgets('TextButton uses InkRipple when useMaterial3 is false', (WidgetTester tester) async { final theme = ThemeData(useMaterial3: false); @@ -1833,7 +1836,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('TextButton in SelectionArea changes mouse cursor when hovered', ( WidgetTester tester, diff --git a/packages/material_ui/test/text_field_test.dart b/packages/material_ui/test/text_field_test.dart index 7b2e24e5b8ea..50cf4a20c592 100644 --- a/packages/material_ui/test/text_field_test.dart +++ b/packages/material_ui/test/text_field_test.dart @@ -103,7 +103,7 @@ void main() { await tester.longPress(textFinder); await tester.pumpAndSettle(); expect(findLiveTextButton(), findsNothing); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'text field selection toolbar should hide when the user starts typing', @@ -2077,7 +2077,7 @@ void main() { expect(find.text('Copy'), isContextMenuProvidedByPlatform ? findsNothing : findsOneWidget); expect(find.text('Paste'), findsNothing); expect(find.text('Cut'), findsNothing); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'does not paint toolbar when no options available', @@ -2255,7 +2255,7 @@ void main() { await tester.pump(); // On web, we always have a client connection to the engine. expect(tester.testTextInput.hasAnyClients, isBrowser ? isTrue : isFalse); - }); + }, tags: 'reduced-web-test-set'); testWidgets('Dynamically switching to non read only should open input connection', ( WidgetTester tester, @@ -2287,7 +2287,7 @@ void main() { entry.markNeedsBuild(); await tester.pump(); expect(tester.testTextInput.hasAnyClients, true); - }); + }, tags: 'reduced-web-test-set'); testWidgets('enableInteractiveSelection = false, long-press', (WidgetTester tester) async { final TextEditingController controller = _textEditingController(); @@ -3591,6 +3591,7 @@ void main() { }, skip: !kIsWeb, // [intended] on web only one selection handle can be dragged at a time. variant: TargetPlatformVariant.only(TargetPlatform.android), + tags: 'reduced-web-test-set', ); testWidgets( @@ -14792,7 +14793,7 @@ void main() { ); expect(state.selectionOverlay!.handlesAreVisible, isFalse); } - }); + }, tags: 'reduced-web-test-set'); testWidgets('Tapping selection handles toggles the toolbar', (WidgetTester tester) async { final TextEditingController controller = _textEditingController(text: 'abc def ghi'); @@ -15450,7 +15451,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets( 'Text selection menu does not change mouse cursor when hovered', @@ -15866,7 +15867,7 @@ void main() { state.updateEditingValue(const TextEditingValue(text: '侬好啊旁友')); expect(state.currentTextEditingValue.text, '侬好啊旁友'); expect(state.currentTextEditingValue.composing, TextRange.empty); - }); + }, tags: 'reduced-web-test-set'); }); testWidgets('TextField does not leak touch events when deadline has exceeded', ( @@ -17965,40 +17966,45 @@ void main() { expect(focusNode.hasPrimaryFocus, isFalse); }, variant: TargetPlatformVariant.desktop()); - testWidgets("Tapping outside doesn't lose focus on mobile", (WidgetTester tester) async { - final focusNode = FocusNode(debugLabel: 'Test Node'); - addTearDown(focusNode.dispose); - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: Center( - child: SizedBox.square( - dimension: 100.0, - child: Opacity( - opacity: 0.5, - child: TextField( - autofocus: true, - focusNode: focusNode, - decoration: const InputDecoration( - hintText: 'Placeholder', - border: OutlineInputBorder(), + testWidgets( + "Tapping outside doesn't lose focus on mobile", + (WidgetTester tester) async { + final focusNode = FocusNode(debugLabel: 'Test Node'); + addTearDown(focusNode.dispose); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: SizedBox.square( + dimension: 100.0, + child: Opacity( + opacity: 0.5, + child: TextField( + autofocus: true, + focusNode: focusNode, + decoration: const InputDecoration( + hintText: 'Placeholder', + border: OutlineInputBorder(), + ), ), ), ), ), ), ), - ), - ); - await tester.pump(); - expect(focusNode.hasPrimaryFocus, isTrue); + ); + await tester.pump(); + expect(focusNode.hasPrimaryFocus, isTrue); - await tester.tapAt(const Offset(10, 10)); - await tester.pump(); + await tester.tapAt(const Offset(10, 10)); + await tester.pump(); - // Focus is lost on mobile browsers, but not mobile apps. - expect(focusNode.hasPrimaryFocus, kIsWeb ? isFalse : isTrue); - }, variant: TargetPlatformVariant.mobile()); + // Focus is lost on mobile browsers, but not mobile apps. + expect(focusNode.hasPrimaryFocus, kIsWeb ? isFalse : isTrue); + }, + variant: TargetPlatformVariant.mobile(), + tags: 'reduced-web-test-set', + ); testWidgets( "Tapping on toolbar doesn't lose focus", @@ -18152,6 +18158,7 @@ void main() { } }, variant: TargetPlatformVariant.all(), + tags: 'reduced-web-test-set', ); } }); diff --git a/packages/material_ui/test/theme_data_test.dart b/packages/material_ui/test/theme_data_test.dart index ca97ec327c0f..1dd49df831be 100644 --- a/packages/material_ui/test/theme_data_test.dart +++ b/packages/material_ui/test/theme_data_test.dart @@ -949,29 +949,32 @@ void main() { expect(theme.applyElevationOverlayColor, isTrue); }); - testWidgets('splashFactory is InkSparkle only for Android non-web when useMaterial3 is true', ( - WidgetTester tester, - ) async { - final theme = ThemeData(); + testWidgets( + 'splashFactory is InkSparkle only for Android non-web when useMaterial3 is true', + (WidgetTester tester) async { + final theme = ThemeData(); - // Basic check that this theme is in fact using material 3. - expect(theme.useMaterial3, true); + // Basic check that this theme is in fact using material 3. + expect(theme.useMaterial3, true); - switch (debugDefaultTargetPlatformOverride!) { - case TargetPlatform.android: - if (kIsWeb) { + switch (debugDefaultTargetPlatformOverride!) { + case TargetPlatform.android: + if (kIsWeb) { + expect(theme.splashFactory, equals(InkRipple.splashFactory)); + } else { + expect(theme.splashFactory, equals(InkSparkle.splashFactory)); + } + case TargetPlatform.iOS: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: expect(theme.splashFactory, equals(InkRipple.splashFactory)); - } else { - expect(theme.splashFactory, equals(InkSparkle.splashFactory)); - } - case TargetPlatform.iOS: - case TargetPlatform.fuchsia: - case TargetPlatform.linux: - case TargetPlatform.macOS: - case TargetPlatform.windows: - expect(theme.splashFactory, equals(InkRipple.splashFactory)); - } - }, variant: TargetPlatformVariant.all()); + } + }, + variant: TargetPlatformVariant.all(), + tags: 'reduced-web-test-set', + ); testWidgets( 'splashFactory is InkSplash for every platform scenario, including Android non-web, when useMaterial3 is false', diff --git a/packages/material_ui/test/toggle_buttons_test.dart b/packages/material_ui/test/toggle_buttons_test.dart index f2230a2e05b2..251df6044628 100644 --- a/packages/material_ui/test/toggle_buttons_test.dart +++ b/packages/material_ui/test/toggle_buttons_test.dart @@ -1775,7 +1775,7 @@ void main() { RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic, ); - }); + }, tags: 'reduced-web-test-set'); testWidgets('ToggleButtons focus, hover, and highlight elevations are 0', ( WidgetTester tester, diff --git a/script/configs/web_dart_unit_test_tags.yaml b/script/configs/web_dart_unit_test_tags.yaml new file mode 100644 index 000000000000..f56c1f163c44 --- /dev/null +++ b/script/configs/web_dart_unit_test_tags.yaml @@ -0,0 +1,5 @@ +# Maps package names to test tag selectors for the web dart unit tests. +# +# Packages listed here will only run tests matching the specified tag. +# Note: Only one tag per package is supported. +material_ui: reduced-web-test-set diff --git a/script/tool/lib/src/dart_test_command.dart b/script/tool/lib/src/dart_test_command.dart index e6bce495452e..87cb21262ef2 100644 --- a/script/tool/lib/src/dart_test_command.dart +++ b/script/tool/lib/src/dart_test_command.dart @@ -14,6 +14,7 @@ import 'common/pub_utils.dart'; import 'common/repository_package.dart'; const int _exitUnknownTestPlatform = 3; +const int _exitNoTestsRan = 79; enum _TestPlatform { // Must run in the command-line VM. @@ -41,9 +42,18 @@ class DartTestCommand extends PackageLoopingCommand { '("vm" in most cases, "chrome" for web plugin implementations).', ); argParser.addFlag(kWebWasmFlag, help: 'Compile to WebAssembly rather than JavaScript'); + argParser.addOption( + _packageTagsFlag, + help: + 'Path to a YAML file that maps package names to tags to run for that ' + 'package.', + ); } static const String _platformFlag = 'platform'; + static const String _packageTagsFlag = 'package-tags'; + + Map? _packageTags; @override final String name = 'dart-test'; @@ -69,6 +79,11 @@ class DartTestCommand extends PackageLoopingCommand { isPackageSupportFile(path); } + @override + Future initializeRun() async { + _initializePackageTags(); + } + @override Future runForPackage(RepositoryPackage package) async { if (!package.testDirectory.existsSync()) { @@ -115,24 +130,29 @@ class DartTestCommand extends PackageLoopingCommand { // Whether to run web tests compiled to wasm. final bool wasm = platform != 'vm' && getBoolArg(kWebWasmFlag); - bool passed; + final String? tag = _getTagForPackage(package); + final int exitCode; if (package.requiresFlutter()) { - passed = await _runFlutterTests(package, platform: platform, wasm: wasm); + exitCode = await _runFlutterTests(package, platform: platform, wasm: wasm, tag: tag); } else { - passed = await _runDartTests(package, platform: platform, wasm: wasm); + exitCode = await _runDartTests(package, platform: platform, wasm: wasm, tag: tag); } - return passed ? PackageResult.success() : PackageResult.fail(); + if (tag != null && exitCode == _exitNoTestsRan) { + return PackageResult.skip('No tests match the requested tag selector.'); + } + return exitCode == 0 ? PackageResult.success() : PackageResult.fail(); } - /// Runs the Dart tests for a Flutter package, returning true on success. - Future _runFlutterTests( + /// Runs the Dart tests for a Flutter package, returning the process exit code. + Future _runFlutterTests( RepositoryPackage package, { String? platform, bool wasm = false, + String? tag, }) async { final String experiment = getStringArg(kEnableExperiment); - final int exitCode = await processRunner.runAndStream(flutterCommand, [ + return processRunner.runAndStream(flutterCommand, [ 'test', '--color', if (experiment.isNotEmpty) '--enable-experiment=$experiment', @@ -140,34 +160,100 @@ class DartTestCommand extends PackageLoopingCommand { // setting it is deprecated, so pass nothing in that case. if (platform != null && platform != 'vm') '--platform=$platform', if (wasm) '--wasm', + if (tag != null) '--tags=$tag', ], workingDir: package.directory); - return exitCode == 0; } - /// Runs the Dart tests for a non-Flutter package, returning true on success. - Future _runDartTests( + /// Runs the Dart tests for a non-Flutter package, returning the process exit code. + Future _runDartTests( RepositoryPackage package, { String? platform, bool wasm = false, + String? tag, }) async { // Unlike `flutter test`, `dart run test` does not automatically get // packages if (!await runPubGet(package, processRunner, super.platform)) { printError('Unable to fetch dependencies.'); - return false; + return 1; } final String experiment = getStringArg(kEnableExperiment); - final int exitCode = await processRunner.runAndStream('dart', [ + return processRunner.runAndStream('dart', [ 'run', if (experiment.isNotEmpty) '--enable-experiment=$experiment', 'test', if (platform != null) '--platform=$platform', if (wasm) '--compiler=dart2wasm', + if (tag != null) '--tags=$tag', ], workingDir: package.directory); + } + + /// Parses the `--package-tags` argument and populates the `_packageTags` + /// map with the resulting package names to tags. + void _initializePackageTags() { + final packageTags = {}; + final String? arg = getNullableStringArg(_packageTagsFlag); + + if (arg == null || arg.isEmpty) { + _packageTags = packageTags; + return; + } + + final File file = packagesDir.fileSystem.file(arg); + if (!file.existsSync()) { + printError('The package tags file "$arg" does not exist.'); + throw ToolExit(exitInvalidArguments); + } + + final Object? yaml = loadYaml(file.readAsStringSync()); + // Treat an empty or comment-only file as an empty map (no package tags). + if (yaml == null) { + _packageTags = packageTags; + return; + } + if (yaml is YamlMap) { + for (final MapEntry entry in yaml.entries) { + final pkg = entry.key.toString(); + final dynamic val = entry.value; + if (val != null) { + packageTags[pkg] = val.toString(); + } + } + } else { + printError('The package tags file "$arg" is not a valid YAML map.'); + throw ToolExit(exitInvalidArguments); + } + _packageTags = packageTags; + return; + } + + /// Returns the tag to apply for [package] based on `--package-tags`, or null + /// if none. + /// + /// This checks the package's [RepositoryPackage.displayName], and falls back + /// to checking the [RepositoryPackage.displayName] of any enclosing packages + /// up the directory tree. This allows tagging an entire plugin (including its + /// nested examples) by simply tagging the enclosing package. + String? _getTagForPackage(RepositoryPackage package) { + final Map? packageTags = _packageTags; + if (packageTags != null && packageTags.isNotEmpty) { + final candidates = {package.displayName}; + RepositoryPackage? enclosing = package.getEnclosingPackage(); + while (enclosing != null) { + candidates.add(enclosing.displayName); + enclosing = enclosing.getEnclosingPackage(); + } + + for (final candidate in candidates) { + if (packageTags.containsKey(candidate)) { + return packageTags[candidate]; + } + } + } - return exitCode == 0; + return null; } /// Returns the required test environment, or null if none is specified. diff --git a/script/tool/test/dart_test_command_test.dart b/script/tool/test/dart_test_command_test.dart index 4e9a461f9272..c48cf8f10dba 100644 --- a/script/tool/test/dart_test_command_test.dart +++ b/script/tool/test/dart_test_command_test.dart @@ -732,6 +732,109 @@ test_on: !vm && firefox ); }); + test('skips packages where no tests match tag (exit code 79)', () async { + createFakePlugin('plugin1', packagesDir, extraFiles: ['test/empty_test.dart']); + createFakePlugin('plugin2', packagesDir, extraFiles: ['test/empty_test.dart']); + + processRunner.mockProcessesForExecutable[getFlutterCommand(mockPlatform)] = [ + FakeProcessInfo(MockProcess(exitCode: 79), [ + 'test', + ]), // plugin 1 has no matching tests + FakeProcessInfo(MockProcess(), ['test']), // plugin 2 test passes + ]; + + final File configFile = packagesDir.fileSystem.file('config.yaml'); + configFile.writeAsStringSync(''' +plugin1: reduced-web-test-set +plugin2: reduced-web-test-set +'''); + + final List output = await runCapturingPrint(runner, [ + 'dart-test', + '--package-tags=${configFile.path}', + ]); + + expect( + output, + containsAllInOrder([ + contains('SKIPPING: No tests match the requested tag selector.'), + contains('plugin1 - skipped'), + contains('plugin2 - ran'), + ]), + ); + }); + + test('package-tags flag applies tags only to matching packages', () async { + final RepositoryPackage pluginA = createFakePlugin( + 'a', + packagesDir, + extraFiles: ['test/empty_test.dart', 'example/test/empty_test.dart'], + ); + final RepositoryPackage packageB = createFakePackage( + 'b', + packagesDir, + extraFiles: ['test/empty_test.dart'], + ); + + final File configFile = packagesDir.fileSystem.file('config.yaml'); + configFile.writeAsStringSync(''' +a: reduced-web-test-set +'''); + + await runCapturingPrint(runner, ['dart-test', '--package-tags=${configFile.path}']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall(getFlutterCommand(mockPlatform), const [ + 'test', + '--color', + '--tags=reduced-web-test-set', + ], pluginA.path), + ProcessCall(getFlutterCommand(mockPlatform), const [ + 'test', + '--color', + '--tags=reduced-web-test-set', + ], getExampleDir(pluginA).path), + ProcessCall('dart', const ['pub', 'get'], packageB.path), + ProcessCall('dart', const ['run', 'test'], packageB.path), + ]), + ); + }); + + test('package-tags flag fails if configuration file does not exist', () async { + createFakePlugin('a', packagesDir, extraFiles: ['test/empty_test.dart']); + + Error? commandError; + final List output = await runCapturingPrint(runner, [ + 'dart-test', + '--package-tags=non_existent_file.yaml', + ], errorHandler: (Error e) => commandError = e); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('The package tags file "non_existent_file.yaml" does not exist.'), + ]), + ); + }); + + test('package-tags flag fails if configuration file is not a YAML map', () async { + createFakePlugin('a', packagesDir, extraFiles: ['test/empty_test.dart']); + final File configFile = packagesDir.fileSystem.file('invalid.yaml'); + configFile.writeAsStringSync('- item1\n- item2'); + + Error? commandError; + final List output = await runCapturingPrint(runner, [ + 'dart-test', + '--package-tags=${configFile.path}', + ], errorHandler: (Error e) => commandError = e); + + expect(commandError, isA()); + expect(output, containsAllInOrder([contains('is not a valid YAML map.')])); + }); + group('file filtering', () { test('runs command for changes to Dart source', () async { createFakePackage('package_a', packagesDir);