mirror of
https://github.com/flutter/flutter.git
synced 2026-02-12 22:03:04 +08:00
Update SnackBar tests for M2/M3 (#130717)
This PR updates unit tests for `SnackBar` to have M2 and M3 versions. More info in https://github.com/flutter/flutter/issues/127064
This commit is contained in:
parent
edcaa335d1
commit
e29f2b98af
@ -10,6 +10,7 @@ library;
|
||||
import 'dart:async';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -302,7 +303,7 @@ void main() {
|
||||
expect(tapCount, equals(1));
|
||||
});
|
||||
|
||||
testWidgets('Light theme SnackBar has dark background', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - Light theme SnackBar has dark background', (WidgetTester tester) async {
|
||||
final ThemeData lightTheme = ThemeData.light(useMaterial3: false);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -344,6 +345,45 @@ void main() {
|
||||
expect(renderModel.color, equals(const Color(0xFF333333)));
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Light theme SnackBar has dark background', (WidgetTester tester) async {
|
||||
final ThemeData lightTheme = ThemeData.light(useMaterial3: true);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: lightTheme,
|
||||
home: Scaffold(
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: const Text('I am a snack bar.'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(
|
||||
label: 'ACTION',
|
||||
onPressed: () { },
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('X'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750));
|
||||
|
||||
final Finder material = find.widgetWithText(Material, 'I am a snack bar.').first;
|
||||
final RenderPhysicalModel renderModel = tester.renderObject(material);
|
||||
|
||||
expect(renderModel.color, equals(lightTheme.colorScheme.inverseSurface));
|
||||
});
|
||||
|
||||
testWidgets('Dark theme SnackBar has light background', (WidgetTester tester) async {
|
||||
final ThemeData darkTheme = ThemeData.dark();
|
||||
await tester.pumpWidget(
|
||||
@ -383,7 +423,7 @@ void main() {
|
||||
expect(renderModel.color, equals(darkTheme.colorScheme.onSurface));
|
||||
});
|
||||
|
||||
testWidgets('Dark theme SnackBar has primary text buttons', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - Dark theme SnackBar has primary text buttons', (WidgetTester tester) async {
|
||||
final ThemeData darkTheme = ThemeData.dark(useMaterial3: false);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -422,6 +462,45 @@ void main() {
|
||||
expect(buttonTextStyle.color, equals(darkTheme.colorScheme.primary));
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Dark theme SnackBar has primary text buttons', (WidgetTester tester) async {
|
||||
final ThemeData darkTheme = ThemeData.dark(useMaterial3: true);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: darkTheme,
|
||||
home: Scaffold(
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: const Text('I am a snack bar.'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(
|
||||
label: 'ACTION',
|
||||
onPressed: () { },
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('X'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750));
|
||||
|
||||
final TextStyle buttonTextStyle = tester.widget<RichText>(
|
||||
find.descendant(of: find.text('ACTION'), matching: find.byType(RichText))
|
||||
).text.style!;
|
||||
expect(buttonTextStyle.color, equals(darkTheme.colorScheme.inversePrimary));
|
||||
});
|
||||
|
||||
testWidgets('SnackBar should inherit theme data from its ancestor.', (WidgetTester tester) async {
|
||||
final SliderThemeData sliderTheme = SliderThemeData.fromPrimaryColors(
|
||||
primaryColor: Colors.black,
|
||||
@ -767,9 +846,7 @@ void main() {
|
||||
expect(snackBarBottomRight.dx, (800 + width) / 2); // Device width is 800.
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Snackbar width customization takes preference of widget over theme',
|
||||
(WidgetTester tester) async {
|
||||
testWidgets('Snackbar width customization takes preference of widget over theme', (WidgetTester tester) async {
|
||||
const double themeWidth = 200.0;
|
||||
const double widgetWidth = 400.0;
|
||||
await tester.pumpWidget(
|
||||
@ -812,9 +889,10 @@ void main() {
|
||||
expect(snackBarBottomRight.dx, (800 + widgetWidth) / 2); // Device width is 800.
|
||||
});
|
||||
|
||||
testWidgets('Snackbar labels can be colored as MaterialColor (Material 2)', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - Snackbar labels can be colored as MaterialColor', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: Scaffold(
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
@ -856,8 +934,7 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Snackbar labels can be colored as MaterialColor (Material 3)',
|
||||
(WidgetTester tester) async {
|
||||
testWidgets('Material3 - Snackbar labels can be colored as MaterialColor', (WidgetTester tester) async {
|
||||
const MaterialColor usedColor = Colors.teal;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -960,7 +1037,7 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('SnackBar button text alignment', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - SnackBar button text alignment', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: MediaQuery(
|
||||
@ -1008,8 +1085,56 @@ void main() {
|
||||
expect(snackBarBottomRight.dy - actionTextBottomRight.dy, 17.0 + 40.0); // margin + bottom padding
|
||||
});
|
||||
|
||||
testWidgets('Material3 - SnackBar button text alignment', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(
|
||||
padding: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
top: 20.0,
|
||||
right: 30.0,
|
||||
bottom: 40.0,
|
||||
),
|
||||
),
|
||||
child: Scaffold(
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: const Text('I am a snack bar.'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () { }),
|
||||
));
|
||||
},
|
||||
child: const Text('X'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750)); // Animation last frame.
|
||||
|
||||
final Offset textBottomLeft = tester.getBottomLeft(find.text('I am a snack bar.'));
|
||||
final Offset textBottomRight = tester.getBottomRight(find.text('I am a snack bar.'));
|
||||
final Offset actionTextBottomLeft = tester.getBottomLeft(find.text('ACTION'));
|
||||
final Offset actionTextBottomRight = tester.getBottomRight(find.text('ACTION'));
|
||||
final Offset snackBarBottomLeft = tester.getBottomLeft(find.byType(SnackBar));
|
||||
final Offset snackBarBottomRight = tester.getBottomRight(find.byType(SnackBar));
|
||||
|
||||
expect(textBottomLeft.dx - snackBarBottomLeft.dx, 24.0 + 10.0); // margin + left padding
|
||||
expect(snackBarBottomLeft.dy - textBottomLeft.dy, 14.0 + 40.0); // margin + bottom padding
|
||||
expect(actionTextBottomLeft.dx - textBottomRight.dx, 24.0 + 12.0); // action padding + margin
|
||||
expect(snackBarBottomRight.dx - actionTextBottomRight.dx, 24.0 + 12.0 + 30.0); // action (padding + margin) + right padding
|
||||
expect(snackBarBottomRight.dy - actionTextBottomRight.dy, 14.0 + 40.0); // margin + bottom padding
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Custom padding between SnackBar and its contents when set to SnackBarBehavior.fixed',
|
||||
'Material2 - Custom padding between SnackBar and its contents when set to SnackBarBehavior.fixed',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
@ -1065,6 +1190,63 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Material3 - Custom padding between SnackBar and its contents when set to SnackBarBehavior.fixed',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(
|
||||
padding: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
top: 20.0,
|
||||
right: 30.0,
|
||||
bottom: 40.0,
|
||||
),
|
||||
),
|
||||
child: Scaffold(
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Animutation'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.block), label: 'Zombo.com'),
|
||||
],
|
||||
),
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: const Text('I am a snack bar.'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
|
||||
));
|
||||
},
|
||||
child: const Text('X'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750)); // Animation last frame.
|
||||
|
||||
final Offset textBottomLeft = tester.getBottomLeft(find.text('I am a snack bar.'));
|
||||
final Offset textBottomRight = tester.getBottomRight(find.text('I am a snack bar.'));
|
||||
final Offset actionTextBottomLeft = tester.getBottomLeft(find.text('ACTION'));
|
||||
final Offset actionTextBottomRight = tester.getBottomRight(find.text('ACTION'));
|
||||
final Offset snackBarBottomLeft = tester.getBottomLeft(find.byType(SnackBar));
|
||||
final Offset snackBarBottomRight = tester.getBottomRight(find.byType(SnackBar));
|
||||
|
||||
expect(textBottomLeft.dx - snackBarBottomLeft.dx, 24.0 + 10.0); // margin + left padding
|
||||
expect(snackBarBottomLeft.dy - textBottomLeft.dy, 14.0); // margin (with no bottom padding)
|
||||
expect(actionTextBottomLeft.dx - textBottomRight.dx, 24.0 + 12.0); // action padding + margin
|
||||
expect(snackBarBottomRight.dx - actionTextBottomRight.dx, 24.0 + 12.0 + 30.0); // action (padding + margin) + right padding
|
||||
expect(snackBarBottomRight.dy - actionTextBottomRight.dy, 14.0); // margin (with no bottom padding)
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('SnackBar should push FloatingActionButton above', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: MediaQuery(
|
||||
@ -1120,7 +1302,7 @@ void main() {
|
||||
expect(fabRect.bottomRight.dy, snackBarTopRight.dy - defaultFabPadding);
|
||||
});
|
||||
|
||||
testWidgets('Floating SnackBar button text alignment', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - Floating SnackBar button text alignment', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(
|
||||
useMaterial3: false,
|
||||
@ -1171,8 +1353,59 @@ void main() {
|
||||
expect(snackBarBottomRight.dy - actionTextBottomRight.dy, 27.0); // margin (with no bottom padding)
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Floating SnackBar button text alignment', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
snackBarTheme: const SnackBarThemeData(behavior: SnackBarBehavior.floating),
|
||||
),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(
|
||||
padding: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
top: 20.0,
|
||||
right: 30.0,
|
||||
bottom: 40.0,
|
||||
),
|
||||
),
|
||||
child: Scaffold(
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: const Text('I am a snack bar.'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
|
||||
));
|
||||
},
|
||||
child: const Text('X'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750)); // Animation last frame.
|
||||
|
||||
final Offset textBottomLeft = tester.getBottomLeft(find.text('I am a snack bar.'));
|
||||
final Offset textBottomRight = tester.getBottomRight(find.text('I am a snack bar.'));
|
||||
final Offset actionTextBottomLeft = tester.getBottomLeft(find.text('ACTION'));
|
||||
final Offset actionTextBottomRight = tester.getBottomRight(find.text('ACTION'));
|
||||
final Offset snackBarBottomLeft = tester.getBottomLeft(find.byType(SnackBar));
|
||||
final Offset snackBarBottomRight = tester.getBottomRight(find.byType(SnackBar));
|
||||
|
||||
expect(textBottomLeft.dx - snackBarBottomLeft.dx, 31.0 + 10.0); // margin + left padding
|
||||
expect(snackBarBottomLeft.dy - textBottomLeft.dy, 24.0); // margin (with no bottom padding)
|
||||
expect(actionTextBottomLeft.dx - textBottomRight.dx, 16.0 + 8.0); // action padding + margin
|
||||
expect(snackBarBottomRight.dx - actionTextBottomRight.dx, 31.0 + 30.0 + 8.0); // margin + right (padding + margin)
|
||||
expect(snackBarBottomRight.dy - actionTextBottomRight.dy, 24.0); // margin (with no bottom padding)
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Custom padding between SnackBar and its contents when set to SnackBarBehavior.floating',
|
||||
'Material2 - Custom padding between SnackBar and its contents when set to SnackBarBehavior.floating',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(
|
||||
@ -1231,6 +1464,66 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Material3 - Custom padding between SnackBar and its contents when set to SnackBarBehavior.floating',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
snackBarTheme: const SnackBarThemeData(behavior: SnackBarBehavior.floating),
|
||||
),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(
|
||||
padding: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
top: 20.0,
|
||||
right: 30.0,
|
||||
bottom: 40.0,
|
||||
),
|
||||
),
|
||||
child: Scaffold(
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Animutation'),
|
||||
BottomNavigationBarItem(icon: Icon(Icons.block), label: 'Zombo.com'),
|
||||
],
|
||||
),
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: const Text('I am a snack bar.'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
|
||||
));
|
||||
},
|
||||
child: const Text('X'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750)); // Animation last frame.
|
||||
|
||||
final Offset textBottomLeft = tester.getBottomLeft(find.text('I am a snack bar.'));
|
||||
final Offset textBottomRight = tester.getBottomRight(find.text('I am a snack bar.'));
|
||||
final Offset actionTextBottomLeft = tester.getBottomLeft(find.text('ACTION'));
|
||||
final Offset actionTextBottomRight = tester.getBottomRight(find.text('ACTION'));
|
||||
final Offset snackBarBottomLeft = tester.getBottomLeft(find.byType(SnackBar));
|
||||
final Offset snackBarBottomRight = tester.getBottomRight(find.byType(SnackBar));
|
||||
|
||||
expect(textBottomLeft.dx - snackBarBottomLeft.dx, 31.0 + 10.0); // margin + left padding
|
||||
expect(snackBarBottomLeft.dy - textBottomLeft.dy, 24.0); // margin (with no bottom padding)
|
||||
expect(actionTextBottomLeft.dx - textBottomRight.dx, 16.0 + 8.0); // action (margin + padding)
|
||||
expect(snackBarBottomRight.dx - actionTextBottomRight.dx, 31.0 + 30.0 + 8.0); // margin + right (padding + margin)
|
||||
expect(snackBarBottomRight.dy - actionTextBottomRight.dy, 24.0); // margin (with no bottom padding)
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('SnackBarClosedReason', (WidgetTester tester) async {
|
||||
final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
|
||||
bool actionPressed = false;
|
||||
@ -1858,16 +2151,12 @@ void main() {
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
}
|
||||
|
||||
void expectSnackBarNotVisibleError(WidgetTester tester) {
|
||||
final AssertionError exception = tester.takeException() as AssertionError;
|
||||
const String message = 'Floating SnackBar presented off screen.\n'
|
||||
'A SnackBar with behavior property set to SnackBarBehavior.floating is fully '
|
||||
'or partially off screen because some or all the widgets provided to '
|
||||
'Scaffold.floatingActionButton, Scaffold.persistentFooterButtons and '
|
||||
'Scaffold.bottomNavigationBar take up too much vertical space.\n'
|
||||
'Consider constraining the size of these widgets to allow room for the SnackBar to be visible.';
|
||||
expect(exception.message, message);
|
||||
}
|
||||
const String offScreenMessage = 'Floating SnackBar presented off screen.\n'
|
||||
'A SnackBar with behavior property set to SnackBarBehavior.floating is fully '
|
||||
'or partially off screen because some or all the widgets provided to '
|
||||
'Scaffold.floatingActionButton, Scaffold.persistentFooterButtons and '
|
||||
'Scaffold.bottomNavigationBar take up too much vertical space.\n'
|
||||
'Consider constraining the size of these widgets to allow room for the SnackBar to be visible.';
|
||||
|
||||
testWidgets('Snackbar with SnackBarBehavior.floating will assert when offset too high by a large Scaffold.floatingActionButton', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/84263
|
||||
@ -1891,12 +2180,14 @@ void main() {
|
||||
// Run with the Snackbar fully off screen.
|
||||
await boilerplate(fabHeight: spaceAboveSnackBar + mediumFabHeight * 2);
|
||||
await openFloatingSnackBar(tester);
|
||||
expectSnackBarNotVisibleError(tester);
|
||||
AssertionError exception = tester.takeException() as AssertionError;
|
||||
expect(exception.message, offScreenMessage);
|
||||
|
||||
// Run with the Snackbar partially off screen.
|
||||
await boilerplate(fabHeight: spaceAboveSnackBar + mediumFabHeight + 10);
|
||||
await openFloatingSnackBar(tester);
|
||||
expectSnackBarNotVisibleError(tester);
|
||||
exception = tester.takeException() as AssertionError;
|
||||
expect(exception.message, offScreenMessage);
|
||||
|
||||
// Run with the Snackbar fully visible right on the top of the screen.
|
||||
await boilerplate(fabHeight: spaceAboveSnackBar + mediumFabHeight);
|
||||
@ -1904,7 +2195,7 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('Snackbar with SnackBarBehavior.floating will assert when offset too high by a large Scaffold.persistentFooterButtons', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - Snackbar with SnackBarBehavior.floating will assert when offset too high by a large Scaffold.persistentFooterButtons', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/84263
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -1917,10 +2208,36 @@ void main() {
|
||||
|
||||
await openFloatingSnackBar(tester);
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
expectSnackBarNotVisibleError(tester);
|
||||
|
||||
final AssertionError exception = tester.takeException() as AssertionError;
|
||||
expect(exception.message, offScreenMessage);
|
||||
});
|
||||
|
||||
testWidgets('Snackbar with SnackBarBehavior.floating will assert when offset too high by a large Scaffold.bottomNavigationBar', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - Snackbar with SnackBarBehavior.floating will assert when offset too high by a large Scaffold.persistentFooterButtons', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/84263
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
persistentFooterButtons: <Widget>[SizedBox(height: 1000)],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final FlutterExceptionHandler? handler = FlutterError.onError;
|
||||
final List<String> errorMessages = <String>[];
|
||||
FlutterError.onError = (FlutterErrorDetails details) {
|
||||
errorMessages.add(details.exceptionAsString());
|
||||
};
|
||||
addTearDown(() => FlutterError.onError = handler);
|
||||
|
||||
await openFloatingSnackBar(tester);
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
expect(errorMessages.contains(offScreenMessage), isTrue);
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Snackbar with SnackBarBehavior.floating will assert when offset too high by a large Scaffold.bottomNavigationBar', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/84263
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -1933,7 +2250,32 @@ void main() {
|
||||
|
||||
await openFloatingSnackBar(tester);
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
expectSnackBarNotVisibleError(tester);
|
||||
final AssertionError exception = tester.takeException() as AssertionError;
|
||||
expect(exception.message, offScreenMessage);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Snackbar with SnackBarBehavior.floating will assert when offset too high by a large Scaffold.bottomNavigationBar', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/84263
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
bottomNavigationBar: SizedBox(height: 1000),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final FlutterExceptionHandler? handler = FlutterError.onError;
|
||||
final List<String> errorMessages = <String>[];
|
||||
FlutterError.onError = (FlutterErrorDetails details) {
|
||||
errorMessages.add(details.exceptionAsString());
|
||||
};
|
||||
addTearDown(() => FlutterError.onError = handler);
|
||||
|
||||
await openFloatingSnackBar(tester);
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
expect(errorMessages.contains(offScreenMessage), isTrue);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
@ -2155,7 +2497,7 @@ void main() {
|
||||
expect(find.text(snackBarText), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('SnackBars should be shown above the bottomSheet', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - SnackBars should be shown above the bottomSheet', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: const Scaffold(
|
||||
@ -2178,7 +2520,33 @@ void main() {
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('snack_bar.goldenTest.workWithBottomSheet.png'));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m2_snack_bar.goldenTest.workWithBottomSheet.png'));
|
||||
});
|
||||
|
||||
testWidgets('Material3 - SnackBars should be shown above the bottomSheet', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
bottomSheet: SizedBox(
|
||||
width: 200,
|
||||
height: 50,
|
||||
child: ColoredBox(
|
||||
color: Colors.pink,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
|
||||
scaffoldMessengerState.showSnackBar(SnackBar(
|
||||
content: const Text('I love Flutter!'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m3_snack_bar.goldenTest.workWithBottomSheet.png'));
|
||||
});
|
||||
|
||||
testWidgets('ScaffoldMessenger does not duplicate a SnackBar when presenting a MaterialBanner.', (WidgetTester tester) async {
|
||||
@ -2238,7 +2606,7 @@ void main() {
|
||||
expect(find.text(materialBannerText), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('ScaffoldMessenger presents SnackBars to only the root Scaffold when Scaffolds are nested.', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - ScaffoldMessenger presents SnackBars to only the root Scaffold when Scaffolds are nested.', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: Scaffold(
|
||||
@ -2265,12 +2633,48 @@ void main() {
|
||||
// overlapping the FAB.
|
||||
await expectLater(
|
||||
find.byType(MaterialApp),
|
||||
matchesGoldenFile('snack_bar.scaffold.nested.png'),
|
||||
matchesGoldenFile('m2_snack_bar.scaffold.nested.png'),
|
||||
);
|
||||
final Offset snackBarTopRight = tester.getTopRight(find.byType(SnackBar));
|
||||
expect(snackBarTopRight.dy, 465.0);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - ScaffoldMessenger presents SnackBars to only the root Scaffold when Scaffolds are nested.', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: Scaffold(
|
||||
body: const Scaffold(),
|
||||
floatingActionButton: FloatingActionButton(onPressed: () {}),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state<ScaffoldMessengerState>(
|
||||
find.byType(ScaffoldMessenger),
|
||||
);
|
||||
scaffoldMessengerState.showSnackBar(SnackBar(
|
||||
content: const Text('ScaffoldMessenger'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(SnackBar), findsOneWidget);
|
||||
// The FloatingActionButton helps us identify which Scaffold has the
|
||||
// SnackBar here. Since the outer Scaffold contains a FAB, the SnackBar
|
||||
// should be above it. If the inner Scaffold had the SnackBar, it would be
|
||||
// overlapping the FAB.
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m3_snack_bar.scaffold.nested.png'));
|
||||
final Offset snackBarTopRight = tester.getTopRight(find.byType(SnackBar));
|
||||
|
||||
// TODO(bleroux): https://github.com/flutter/flutter/issues/99933
|
||||
// A bug in the HTML renderer and/or Chrome 96+ causes a
|
||||
// discrepancy in the paragraph height.
|
||||
const bool hasIssue99933 = kIsWeb && !bool.fromEnvironment('FLUTTER_WEB_USE_SKIA');
|
||||
expect(snackBarTopRight.dy, hasIssue99933 ? 464.0 : 465.0);
|
||||
});
|
||||
|
||||
|
||||
testWidgets('ScaffoldMessengerState clearSnackBars works as expected', (WidgetTester tester) async {
|
||||
final List<String> snackBars = <String>['Hello Snackbar', 'Hi Snackbar', 'Bye Snackbar'];
|
||||
int snackBarCounter = 0;
|
||||
@ -2438,8 +2842,7 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
testWidgets('Snackbar by default clips BackdropFilter', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - Snackbar by default clips BackdropFilter', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/98205
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
@ -2469,7 +2872,40 @@ void main() {
|
||||
await tester.tap(find.text('I am a snack bar.'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('snack_bar.goldenTest.backdropFilter.png'));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m2_snack_bar.goldenTest.backdropFilter.png'));
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Snackbar by default clips BackdropFilter', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/98205
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: Scaffold(
|
||||
body: const Scaffold(),
|
||||
floatingActionButton: FloatingActionButton(onPressed: () {}),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state<ScaffoldMessengerState>(
|
||||
find.byType(ScaffoldMessenger),
|
||||
);
|
||||
scaffoldMessengerState.showSnackBar(SnackBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
content: BackdropFilter(
|
||||
filter: ImageFilter.blur(
|
||||
sigmaX: 20.0,
|
||||
sigmaY: 20.0,
|
||||
),
|
||||
child: const Text('I am a snack bar.'),
|
||||
),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
|
||||
behavior: SnackBarBehavior.fixed,
|
||||
));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('I am a snack bar.'));
|
||||
await tester.pump(); // start animation
|
||||
await tester.pump(const Duration(milliseconds: 750));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m3_snack_bar.goldenTest.backdropFilter.png'));
|
||||
});
|
||||
|
||||
testWidgets('Floating snackbar can display optional icon', (WidgetTester tester) async {
|
||||
@ -2504,7 +2940,7 @@ void main() {
|
||||
'snack_bar.goldenTest.floatingWithActionWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Fixed width snackbar can display optional icon', (WidgetTester tester) async {
|
||||
testWidgets('Material2 - Fixed width snackbar can display optional icon', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: const Scaffold(
|
||||
@ -2528,10 +2964,37 @@ void main() {
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('snack_bar.goldenTest.fixedWithActionWithIcon.png'));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m2_snack_bar.goldenTest.fixedWithActionWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Fixed snackbar can display optional icon without action', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - Fixed width snackbar can display optional icon', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
bottomSheet: SizedBox(
|
||||
width: 200,
|
||||
height: 50,
|
||||
child: ColoredBox(
|
||||
color: Colors.pink,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
|
||||
scaffoldMessengerState.showSnackBar(SnackBar(
|
||||
content: const Text('Go get a snack'),
|
||||
duration: const Duration(seconds: 2),
|
||||
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
|
||||
showCloseIcon: true,
|
||||
behavior: SnackBarBehavior.fixed,
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m3_snack_bar.goldenTest.fixedWithActionWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Fixed snackbar can display optional icon without action', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: const Scaffold(
|
||||
@ -2556,11 +3019,38 @@ void main() {
|
||||
);
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('snack_bar.goldenTest.fixedWithIcon.png'));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m2_snack_bar.goldenTest.fixedWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Floating width snackbar can display optional icon without action', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - Fixed snackbar can display optional icon without action', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
bottomSheet: SizedBox(
|
||||
width: 200,
|
||||
height: 50,
|
||||
child: ColoredBox(
|
||||
color: Colors.pink,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
|
||||
scaffoldMessengerState.showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('I wonder if there are snacks nearby?'),
|
||||
duration: Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.fixed,
|
||||
showCloseIcon: true,
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m3_snack_bar.goldenTest.fixedWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Floating width snackbar can display optional icon without action', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: const Scaffold(
|
||||
@ -2583,11 +3073,36 @@ void main() {
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp),
|
||||
matchesGoldenFile('snack_bar.goldenTest.floatingWithIcon.png'));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m2_snack_bar.goldenTest.floatingWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Floating multi-line snackbar with icon is aligned correctly', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - Floating width snackbar can display optional icon without action', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
bottomSheet: SizedBox(
|
||||
width: 200,
|
||||
height: 50,
|
||||
child: ColoredBox(
|
||||
color: Colors.pink,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
|
||||
scaffoldMessengerState.showSnackBar(const SnackBar(
|
||||
content: Text('Must go get a snack!'),
|
||||
duration: Duration(seconds: 2),
|
||||
showCloseIcon: true,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m3_snack_bar.goldenTest.floatingWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Floating multi-line snackbar with icon is aligned correctly', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: const Scaffold(
|
||||
@ -2611,11 +3126,37 @@ void main() {
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp),
|
||||
matchesGoldenFile('snack_bar.goldenTest.multiLineWithIcon.png'));
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m2_snack_bar.goldenTest.multiLineWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Floating multi-line snackbar with icon and actionOverflowThreshold=1 is aligned correctly', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - Floating multi-line snackbar with icon is aligned correctly', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
bottomSheet: SizedBox(
|
||||
width: 200,
|
||||
height: 50,
|
||||
child: ColoredBox(
|
||||
color: Colors.pink,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
|
||||
scaffoldMessengerState.showSnackBar(const SnackBar(
|
||||
content: Text(
|
||||
'This is a really long snackbar message. So long, it spans across more than one line!'),
|
||||
duration: Duration(seconds: 2),
|
||||
showCloseIcon: true,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
|
||||
|
||||
await expectLater(find.byType(MaterialApp), matchesGoldenFile('m3_snack_bar.goldenTest.multiLineWithIcon.png'));
|
||||
});
|
||||
|
||||
testWidgets('Material2 - Floating multi-line snackbar with icon and actionOverflowThreshold=1 is aligned correctly', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: const Scaffold(
|
||||
@ -2639,8 +3180,40 @@ void main() {
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate in.
|
||||
|
||||
await expectLater(find.byType(MaterialApp),
|
||||
matchesGoldenFile('snack_bar.goldenTest.multiLineWithIconWithZeroActionOverflowThreshold.png'));
|
||||
await expectLater(
|
||||
find.byType(MaterialApp),
|
||||
matchesGoldenFile('m2_snack_bar.goldenTest.multiLineWithIconWithZeroActionOverflowThreshold.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Floating multi-line snackbar with icon and actionOverflowThreshold=1 is aligned correctly', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
bottomSheet: SizedBox(
|
||||
width: 200,
|
||||
height: 50,
|
||||
child: ColoredBox(
|
||||
color: Colors.pink,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
|
||||
scaffoldMessengerState.showSnackBar(const SnackBar(
|
||||
content: Text('This is a really long snackbar message. So long, it spans across more than one line!'),
|
||||
duration: Duration(seconds: 2),
|
||||
showCloseIcon: true,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
actionOverflowThreshold: 1,
|
||||
));
|
||||
await tester.pumpAndSettle(); // Have the SnackBar fully animate in.
|
||||
|
||||
await expectLater(
|
||||
find.byType(MaterialApp),
|
||||
matchesGoldenFile('m3_snack_bar.goldenTest.multiLineWithIconWithZeroActionOverflowThreshold.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user