diff --git a/examples/api/lib/cupertino/dialog/cupertino_alert_dialog.0.dart b/examples/api/lib/cupertino/dialog/cupertino_alert_dialog.0.dart index 185b4e34a7ec7..eea116cda8934 100644 --- a/examples/api/lib/cupertino/dialog/cupertino_alert_dialog.0.dart +++ b/examples/api/lib/cupertino/dialog/cupertino_alert_dialog.0.dart @@ -23,9 +23,8 @@ class AlertDialogApp extends StatelessWidget { class AlertDialogExample extends StatelessWidget { const AlertDialogExample({super.key}); - // This shows a CupertinoModalPopup which hosts a CupertinoAlertDialog. void _showAlertDialog(BuildContext context) { - showCupertinoModalPopup( + showCupertinoDialog( context: context, builder: (BuildContext context) => CupertinoAlertDialog( title: const Text('Alert'), diff --git a/packages/flutter/test/cupertino/dialog_test.dart b/packages/flutter/test/cupertino/dialog_test.dart index 46c6bfe1c6769..c8337893bbdb6 100644 --- a/packages/flutter/test/cupertino/dialog_test.dart +++ b/packages/flutter/test/cupertino/dialog_test.dart @@ -19,6 +19,69 @@ import 'package:flutter_test/flutter_test.dart'; import '../widgets/semantics_tester.dart'; void main() { + testWidgets('Overall appearance is correct for the light theme', (WidgetTester tester) async { + await tester.pumpWidget( + TestScaffoldApp( + theme: const CupertinoThemeData(brightness: Brightness.light), + dialog: CupertinoAlertDialog( + content: const Text('The content'), + actions: [ + CupertinoDialogAction(child: const Text('One'), onPressed: () {}), + CupertinoDialogAction(child: const Text('Two'), onPressed: () {}), + ], + ), + ), + ); + + await tester.tap(find.text('Go')); + await tester.pumpAndSettle(); + + final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('One'))); + await tester.pumpAndSettle(); + // This golden file also verifies the structure of an alert dialog that + // has a content, no title, and no overscroll for any sections (in contrast + // to cupertinoAlertDialog.dark-theme.png). + await expectLater( + find.byType(CupertinoApp), + matchesGoldenFile('cupertinoAlertDialog.overall-light-theme.png'), + ); + + await gesture.up(); + }); + + testWidgets('Overall appearance is correct for the dark theme', (WidgetTester tester) async { + await tester.pumpWidget( + TestScaffoldApp( + theme: const CupertinoThemeData(brightness: Brightness.dark), + dialog: CupertinoAlertDialog( + title: const Text('The title'), + content: const Text('The content'), + actions: List.generate(20, (int i) => + CupertinoDialogAction( + onPressed: () {}, + child: Text('Button $i'), + ), + ), + ), + ), + ); + + await tester.tap(find.text('Go')); + await tester.pumpAndSettle(); + + final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('Button 0'))); + await tester.pumpAndSettle(); + // This golden file also verifies the structure of an action sheet that + // has both a message and a title, and an overscrolled action section (in + // contrast to cupertinoAlertDialog.light-theme.png). + await expectLater( + find.byType(CupertinoApp), + matchesGoldenFile('cupertinoAlertDialog.overall-dark-theme.png'), + ); + + await gesture.up(); + }); + testWidgets('Alert dialog control test', (WidgetTester tester) async { bool didDelete = false; @@ -181,8 +244,8 @@ void main() { testWidgets('Has semantic annotations', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); - await tester.pumpWidget(const MaterialApp(home: Material( - child: CupertinoAlertDialog( + await tester.pumpWidget(const CupertinoApp( + home: CupertinoAlertDialog( title: Text('The Title'), content: Text('Content'), actions: [ @@ -190,7 +253,7 @@ void main() { CupertinoDialogAction(child: Text('OK')), ], ), - ))); + )); expect( semantics, @@ -506,7 +569,7 @@ void main() { // Check that the title/message section is not displayed expect(actionScrollController.offset, 0.0); - expect(tester.getTopLeft(find.widgetWithText(CupertinoDialogAction, 'One')).dy, equals(277.5)); + expect(tester.getTopLeft(find.widgetWithText(CupertinoDialogAction, 'One')).dy, equals(270.75)); // Check that the button's vertical size is the same. expect( @@ -1160,7 +1223,7 @@ void main() { testWidgets('Dialog widget insets by MediaQuery viewInsets', (WidgetTester tester) async { await tester.pumpWidget( - const MaterialApp( + const CupertinoApp( home: MediaQuery( data: MediaQueryData(), child: CupertinoAlertDialog(content: Placeholder(fallbackHeight: 200.0)), @@ -1171,7 +1234,7 @@ void main() { final Rect placeholderRectWithoutInsets = tester.getRect(find.byType(Placeholder)); await tester.pumpWidget( - const MaterialApp( + const CupertinoApp( home: MediaQuery( data: MediaQueryData(viewInsets: EdgeInsets.fromLTRB(40.0, 30.0, 20.0, 10.0)), child: CupertinoAlertDialog(content: Placeholder(fallbackHeight: 200.0)), @@ -1188,70 +1251,6 @@ void main() { expect(tester.getRect(find.byType(Placeholder)), placeholderRectWithoutInsets.translate(10, 10)); }); - testWidgets('Material2 - Default cupertino dialog golden', (WidgetTester tester) async { - await tester.pumpWidget( - createAppWithButtonThatLaunchesDialog( - useMaterial3: false, - dialogBuilder: (BuildContext context) { - return MediaQuery.withClampedTextScaling( - minScaleFactor: 3.0, - maxScaleFactor: 3.0, - child: const RepaintBoundary( - child: CupertinoAlertDialog( - title: Text('Title'), - content: Text('text'), - actions: [ - CupertinoDialogAction(child: Text('No')), - CupertinoDialogAction(child: Text('OK')), - ], - ), - ), - ); - }, - ), - ); - - await tester.tap(find.text('Go')); - await tester.pumpAndSettle(); - - await expectLater( - find.byType(CupertinoAlertDialog), - matchesGoldenFile('m2_dialog_test.cupertino.default.png'), - ); - }); - - testWidgets('Material3 - Default cupertino dialog golden', (WidgetTester tester) async { - await tester.pumpWidget( - createAppWithButtonThatLaunchesDialog( - useMaterial3: true, - dialogBuilder: (BuildContext context) { - return MediaQuery.withClampedTextScaling( - minScaleFactor: 3.0, - maxScaleFactor: 3.0, - child: const RepaintBoundary( - child: CupertinoAlertDialog( - title: Text('Title'), - content: Text('text'), - actions: [ - CupertinoDialogAction(child: Text('No')), - CupertinoDialogAction(child: Text('OK')), - ], - ), - ), - ); - }, - ), - ); - - await tester.tap(find.text('Go')); - await tester.pumpAndSettle(); - - await expectLater( - find.byType(CupertinoAlertDialog), - matchesGoldenFile('m3_dialog_test.cupertino.default.png'), - ); - }); - testWidgets('showCupertinoDialog - custom barrierLabel', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); @@ -1363,7 +1362,7 @@ void main() { testWidgets('CupertinoAlertDialog scrollbars controllers should be different', (WidgetTester tester) async { // https://github.com/flutter/flutter/pull/81278 await tester.pumpWidget( - const MaterialApp( + const CupertinoApp( home: MediaQuery( data: MediaQueryData(), child: CupertinoAlertDialog( @@ -1565,24 +1564,20 @@ RenderBox findScrollableActionsSectionRenderBox(WidgetTester tester) { Widget createAppWithButtonThatLaunchesDialog({ required WidgetBuilder dialogBuilder, - bool? useMaterial3, }) { - return MaterialApp( - theme: ThemeData(useMaterial3: useMaterial3), - home: Material( - child: Center( - child: Builder(builder: (BuildContext context) { - return ElevatedButton( - onPressed: () { - showDialog( - context: context, - builder: dialogBuilder, - ); - }, - child: const Text('Go'), - ); - }), - ), + return CupertinoApp( + home: Center( + child: Builder(builder: (BuildContext context) { + return CupertinoButton( + onPressed: () { + showCupertinoDialog( + context: context, + builder: dialogBuilder, + ); + }, + child: const Text('Go'), + ); + }), ), ); } @@ -1595,13 +1590,11 @@ Widget boilerplate(Widget child) { } Widget createAppWithCenteredButton(Widget child) { - return MaterialApp( - home: Material( - child: Center( - child: ElevatedButton( - onPressed: null, - child: child, - ), + return CupertinoApp( + home: Center( + child: CupertinoButton( + onPressed: null, + child: child, ), ), ); @@ -1643,3 +1636,52 @@ class _RestorableDialogTestWidget extends StatelessWidget { ); } } + +// Shows an app that has a button with text "Go", and clicking this button +// displays the `dialog` and hides the button. +// +// The `theme` will be applied to the app and determines the background. +class TestScaffoldApp extends StatefulWidget { + const TestScaffoldApp({super.key, required this.theme, required this.dialog}); + final CupertinoThemeData theme; + final Widget dialog; + + @override + TestScaffoldAppState createState() => TestScaffoldAppState(); +} + +class TestScaffoldAppState extends State { + bool _pressedButton = false; + + @override + Widget build(BuildContext context) { + return CupertinoApp( + // Hide the debug banner. Because this CupertinoApp is captured in golden + // test as a whole. The debug banner contains tilted text, whose + // anti-alias might cause false negative result. + // https://github.com/flutter/flutter/pull/150442 + debugShowCheckedModeBanner: false, + theme: widget.theme, + home: Builder(builder: (BuildContext context) => + CupertinoPageScaffold( + child: Center( + child: _pressedButton ? Container() : CupertinoButton( + onPressed: () { + setState(() { + _pressedButton = true; + }); + showCupertinoDialog( + context: context, + builder: (BuildContext context) { + return widget.dialog; + }, + ); + }, + child: const Text('Go'), + ), + ), + ), + ), + ); + } +}