diff --git a/packages/flutter/test/material/icon_button_test.dart b/packages/flutter/test/material/icon_button_test.dart index eea26984ef..81ea567224 100644 --- a/packages/flutter/test/material/icon_button_test.dart +++ b/packages/flutter/test/material/icon_button_test.dart @@ -790,7 +790,7 @@ void main() { await tester.pumpWidget( wrap( - useMaterial3: false, + useMaterial3: theme.useMaterial3, child: Column( children: [ IconButton( diff --git a/packages/flutter/test/material/ink_sparkle_test.dart b/packages/flutter/test/material/ink_sparkle_test.dart index b0a44de489..1cd3c00689 100644 --- a/packages/flutter/test/material/ink_sparkle_test.dart +++ b/packages/flutter/test/material/ink_sparkle_test.dart @@ -93,23 +93,41 @@ void main() { // Goldens // ///////////// - testWidgetsWithLeakTracking('InkSparkle renders with sparkles when top left of button is tapped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - InkSparkle renders with sparkles when top left of button is tapped', (WidgetTester tester) async { await _runTest(tester, 'top_left', 0.2); }, skip: kIsWeb, // [intended] shaders are not yet supported for web. ); - testWidgetsWithLeakTracking('InkSparkle renders with sparkles when center of button is tapped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material3 - InkSparkle renders with sparkles when top left of button is tapped', (WidgetTester tester) async { + await _runM3Test(tester, 'top_left', 0.2); + }, + skip: kIsWeb, // [intended] shaders are not yet supported for web. + ); + + testWidgetsWithLeakTracking('Material2 - InkSparkle renders with sparkles when center of button is tapped', (WidgetTester tester) async { await _runTest(tester, 'center', 0.5); }, skip: kIsWeb, // [intended] shaders are not yet supported for web. ); - testWidgetsWithLeakTracking('InkSparkle renders with sparkles when bottom right of button is tapped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material3 - InkSparkle renders with sparkles when center of button is tapped', (WidgetTester tester) async { + await _runM3Test(tester, 'center', 0.5); + }, + skip: kIsWeb, // [intended] shaders are not yet supported for web. + ); + + testWidgetsWithLeakTracking('Material2 - InkSparkle renders with sparkles when bottom right of button is tapped', (WidgetTester tester) async { await _runTest(tester, 'bottom_right', 0.8); }, skip: kIsWeb, // [intended] shaders are not yet supported for web. ); + + testWidgetsWithLeakTracking('Material3 - InkSparkle renders with sparkles when bottom right of button is tapped', (WidgetTester tester) async { + await _runM3Test(tester, 'bottom_right', 0.8); + }, + skip: kIsWeb, // [intended] shaders are not yet supported for web. + ); } Future _runTest(WidgetTester tester, String positionName, double distanceFromTopLeft) async { @@ -146,7 +164,46 @@ Future _runTest(WidgetTester tester, String positionName, double distanceF await tester.pump(const Duration(milliseconds: 50)); await expectLater( repaintFinder, - matchesGoldenFile('ink_sparkle.$positionName.$i.png'), + matchesGoldenFile('m2_ink_sparkle.$positionName.$i.png'), + ); + } +} + +Future _runM3Test(WidgetTester tester, String positionName, double distanceFromTopLeft) async { + final Key repaintKey = UniqueKey(); + final Key buttonKey = UniqueKey(); + + await tester.pumpWidget(MaterialApp( + theme: ThemeData(useMaterial3: true), + home: Scaffold( + body: Center( + child: RepaintBoundary( + key: repaintKey, + child: ElevatedButton( + key: buttonKey, + style: ElevatedButton.styleFrom(splashFactory: InkSparkle.constantTurbulenceSeedSplashFactory), + child: const Text('Sparkle!'), + onPressed: () { }, + ), + ), + ), + ), + )); + + final Finder buttonFinder = find.byKey(buttonKey); + final Finder repaintFinder = find.byKey(repaintKey); + final Offset topLeft = tester.getTopLeft(buttonFinder); + final Offset bottomRight = tester.getBottomRight(buttonFinder); + + await _warmUpShader(tester, buttonFinder); + + final Offset target = topLeft + (bottomRight - topLeft) * distanceFromTopLeft; + await tester.tapAt(target); + for (int i = 0; i <= 5; i++) { + await tester.pump(const Duration(milliseconds: 50)); + await expectLater( + repaintFinder, + matchesGoldenFile('m3_ink_sparkle.$positionName.$i.png'), ); } } diff --git a/packages/flutter/test/material/material_test.dart b/packages/flutter/test/material/material_test.dart index 2832acb09e..33bc9c85b2 100644 --- a/packages/flutter/test/material/material_test.dart +++ b/packages/flutter/test/material/material_test.dart @@ -921,7 +921,7 @@ void main() { expect(box, isNot(paints..circle())); }); - testWidgetsWithLeakTracking('border is painted above child by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material2 - border is painted above child by default', (WidgetTester tester) async { final Key painterKey = UniqueKey(); await tester.pumpWidget(MaterialApp( @@ -956,11 +956,50 @@ void main() { await expectLater( find.byKey(painterKey), - matchesGoldenFile('material.border_paint_above.png'), + matchesGoldenFile('m2_material.border_paint_above.png'), ); }); - testWidgetsWithLeakTracking('border is painted below child when specified', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Material3 - border is painted above child by default', (WidgetTester tester) async { + final Key painterKey = UniqueKey(); + + await tester.pumpWidget(MaterialApp( + theme: ThemeData(useMaterial3: true), + home: Scaffold( + body: RepaintBoundary( + key: painterKey, + child: Card( + child: SizedBox( + width: 200, + height: 300, + child: Material( + clipBehavior: Clip.hardEdge, + shape: const RoundedRectangleBorder( + side: BorderSide(color: Colors.grey, width: 6), + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + child: Column( + children: [ + Container( + color: Colors.green, + height: 150, + ), + ], + ), + ), + ), + ), + ), + ), + )); + + await expectLater( + find.byKey(painterKey), + matchesGoldenFile('m3_material.border_paint_above.png'), + ); + }); + + testWidgetsWithLeakTracking('Material2 - border is painted below child when specified', (WidgetTester tester) async { final Key painterKey = UniqueKey(); await tester.pumpWidget(MaterialApp( @@ -996,7 +1035,47 @@ void main() { await expectLater( find.byKey(painterKey), - matchesGoldenFile('material.border_paint_below.png'), + matchesGoldenFile('m2_material.border_paint_below.png'), + ); + }); + + testWidgetsWithLeakTracking('Material3 - border is painted below child when specified', (WidgetTester tester) async { + final Key painterKey = UniqueKey(); + + await tester.pumpWidget(MaterialApp( + theme: ThemeData(useMaterial3: true), + home: Scaffold( + body: RepaintBoundary( + key: painterKey, + child: Card( + child: SizedBox( + width: 200, + height: 300, + child: Material( + clipBehavior: Clip.hardEdge, + shape: const RoundedRectangleBorder( + side: BorderSide(color: Colors.grey, width: 6), + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + borderOnForeground: false, + child: Column( + children: [ + Container( + color: Colors.green, + height: 150, + ), + ], + ), + ), + ), + ), + ), + ), + )); + + await expectLater( + find.byKey(painterKey), + matchesGoldenFile('m3_material.border_paint_below.png'), ); }); }); diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart index b0486a9cfa..a09d980067 100644 --- a/packages/flutter/test/material/page_test.dart +++ b/packages/flutter/test/material/page_test.dart @@ -240,7 +240,7 @@ void main() { expect(find.text('Page 2'), findsNothing); }, variant: TargetPlatformVariant.only(TargetPlatform.android)); - testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when view insets change', (WidgetTester tester) async { + testWidgets('Material2 - test page transition (_ZoomPageTransition) with rasterization re-rasterizes when view insets change', (WidgetTester tester) async { addTearDown(tester.view.reset); tester.view.physicalSize = const Size(1000, 1000); tester.view.viewInsets = FakeViewPadding.zero; @@ -270,7 +270,7 @@ void main() { await tester.pump(); await tester.pump(const Duration(milliseconds: 50)); - await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.small.png')); + await expectLater(find.byKey(key), matchesGoldenFile('m2_zoom_page_transition.small.png')); // Change the view insets. tester.view.viewInsets = const FakeViewPadding(bottom: 500); @@ -278,7 +278,48 @@ void main() { await tester.pump(); await tester.pump(const Duration(milliseconds: 50)); - await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.big.png')); + await expectLater(find.byKey(key), matchesGoldenFile('m2_zoom_page_transition.big.png')); + }, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web. + + testWidgets('Material3 - test page transition (_ZoomPageTransition) with rasterization re-rasterizes when view insets change', (WidgetTester tester) async { + addTearDown(tester.view.reset); + tester.view.physicalSize = const Size(1000, 1000); + tester.view.viewInsets = FakeViewPadding.zero; + + // Intentionally use nested scaffolds to simulate the view insets being + // consumed. + final Key key = GlobalKey(); + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: MaterialApp( + theme: ThemeData(useMaterial3: true), + onGenerateRoute: (RouteSettings settings) { + return MaterialPageRoute( + builder: (BuildContext context) { + return const Scaffold(body: Scaffold( + body: Material(child: SizedBox.shrink()) + )); + }, + ); + }, + ), + ), + ); + + tester.state(find.byType(Navigator)).pushNamed('/next'); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); + + await expectLater(find.byKey(key), matchesGoldenFile('m3_zoom_page_transition.small.png')); + + // Change the view insets. + tester.view.viewInsets = const FakeViewPadding(bottom: 500); + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 50)); + + await expectLater(find.byKey(key), matchesGoldenFile('m3_zoom_page_transition.big.png')); }, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web. testWidgets( diff --git a/packages/flutter/test/material/progress_indicator_test.dart b/packages/flutter/test/material/progress_indicator_test.dart index 875ab00e30..886539bc36 100644 --- a/packages/flutter/test/material/progress_indicator_test.dart +++ b/packages/flutter/test/material/progress_indicator_test.dart @@ -720,7 +720,7 @@ void main() { expect(tester.hasRunningAnimations, isTrue); }); - testWidgets('RefreshProgressIndicator uses expected animation', (WidgetTester tester) async { + testWidgets('Material2 - RefreshProgressIndicator uses expected animation', (WidgetTester tester) async { final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(50, 50)); await tester.pumpFrames(animationSheet.record( @@ -732,7 +732,23 @@ void main() { await expectLater( await animationSheet.collate(20), - matchesGoldenFile('material.refresh_progress_indicator.png'), + matchesGoldenFile('m2_material.refresh_progress_indicator.png'), + ); + }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001 + + testWidgets('Material3 - RefreshProgressIndicator uses expected animation', (WidgetTester tester) async { + final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(50, 50)); + + await tester.pumpFrames(animationSheet.record( + Theme( + data: ThemeData(useMaterial3: true), + child: const _RefreshProgressIndicatorGolden() + ), + ), const Duration(seconds: 3)); + + await expectLater( + await animationSheet.collate(20), + matchesGoldenFile('m3_material.refresh_progress_indicator.png'), ); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001 @@ -1001,7 +1017,7 @@ void main() { handle.dispose(); }); - testWidgets('Indeterminate CircularProgressIndicator uses expected animation', (WidgetTester tester) async { + testWidgets('Material2 - Indeterminate CircularProgressIndicator uses expected animation', (WidgetTester tester) async { final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(40, 40)); await tester.pumpFrames(animationSheet.record( @@ -1019,7 +1035,29 @@ void main() { await expectLater( await animationSheet.collate(20), - matchesGoldenFile('material.circular_progress_indicator.indeterminate.png'), + matchesGoldenFile('m2_material.circular_progress_indicator.indeterminate.png'), + ); + }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001 + + testWidgets('Material3 - Indeterminate CircularProgressIndicator uses expected animation', (WidgetTester tester) async { + final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(40, 40)); + + await tester.pumpFrames(animationSheet.record( + Theme( + data: ThemeData(useMaterial3: true), + child: const Directionality( + textDirection: TextDirection.ltr, + child: Padding( + padding: EdgeInsets.all(4), + child: CircularProgressIndicator(), + ), + ), + ), + ), const Duration(seconds: 2)); + + await expectLater( + await animationSheet.collate(20), + matchesGoldenFile('m3_material.circular_progress_indicator.indeterminate.png'), ); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001