Skip to content

Commit 0ef4638

Browse files
authored
Update ToggleButtons, ExpansionPanel, and ExpandIcon tests for Material 3 (#141868)
Updated unit tests for `ToggleButtons`, `ExpansionPanel`, and `ExpandIcon` to have M2 and M3 versions. More info in #139076
1 parent 5caa8b8 commit 0ef4638

File tree

3 files changed

+419
-22
lines changed

3 files changed

+419
-22
lines changed

packages/flutter/test/material/expand_icon_test.dart

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ void main() {
7373
expect(iconTheme.data.color, equals(Colors.white60));
7474
});
7575

76-
testWidgets('ExpandIcon disabled', (WidgetTester tester) async {
76+
testWidgets('Material2 - ExpandIcon disabled', (WidgetTester tester) async {
7777
IconTheme iconTheme;
78-
// Light mode test
78+
// Test light mode.
7979
await tester.pumpWidget(wrap(
8080
theme: ThemeData(useMaterial3: false),
8181
child: const ExpandIcon(onPressed: null),
@@ -85,7 +85,7 @@ void main() {
8585
iconTheme = tester.firstWidget(find.byType(IconTheme).last);
8686
expect(iconTheme.data.color, equals(Colors.black38));
8787

88-
// Dark mode test
88+
// Test dark mode.
8989
await tester.pumpWidget(wrap(
9090
child: const ExpandIcon(onPressed: null),
9191
theme: ThemeData(useMaterial3: false, brightness: Brightness.dark),
@@ -96,6 +96,37 @@ void main() {
9696
expect(iconTheme.data.color, equals(Colors.white38));
9797
});
9898

99+
testWidgets('Material3 - ExpandIcon disabled', (WidgetTester tester) async {
100+
ThemeData theme = ThemeData();
101+
IconTheme iconTheme;
102+
// Test light mode.
103+
await tester.pumpWidget(wrap(
104+
theme: theme,
105+
child: const ExpandIcon(onPressed: null),
106+
));
107+
await tester.pumpAndSettle();
108+
109+
iconTheme = tester.firstWidget(find.byType(IconTheme).last);
110+
expect(
111+
iconTheme.data.color,
112+
equals(theme.colorScheme.onSurface.withOpacity(0.38)),
113+
);
114+
115+
theme = ThemeData(brightness: Brightness.dark);
116+
// Test dark mode.
117+
await tester.pumpWidget(wrap(
118+
theme: theme,
119+
child: const ExpandIcon(onPressed: null),
120+
));
121+
await tester.pumpAndSettle();
122+
123+
iconTheme = tester.firstWidget(find.byType(IconTheme).last);
124+
expect(
125+
iconTheme.data.color,
126+
equals(theme.colorScheme.onSurface.withOpacity(0.38)),
127+
);
128+
});
129+
99130
testWidgets('ExpandIcon test isExpanded does not trigger callback', (WidgetTester tester) async {
100131
bool expanded = false;
101132

@@ -173,7 +204,7 @@ void main() {
173204
expect(icon.size, 48);
174205
});
175206

176-
testWidgets('ExpandIcon has correct semantic hints', (WidgetTester tester) async {
207+
testWidgets('Material2 - ExpandIcon has correct semantic hints', (WidgetTester tester) async {
177208
final SemanticsHandle handle = tester.ensureSemantics();
178209
const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();
179210
await tester.pumpWidget(wrap(
@@ -194,6 +225,7 @@ void main() {
194225
));
195226

196227
await tester.pumpWidget(wrap(
228+
theme: ThemeData(useMaterial3: false),
197229
child: ExpandIcon(
198230
onPressed: (bool _) { },
199231
),
@@ -210,6 +242,52 @@ void main() {
210242
handle.dispose();
211243
});
212244

245+
testWidgets('Material3 - ExpandIcon has correct semantic hints', (WidgetTester tester) async {
246+
final SemanticsHandle handle = tester.ensureSemantics();
247+
const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();
248+
249+
await tester.pumpWidget(wrap(
250+
child: ExpandIcon(
251+
isExpanded: true,
252+
onPressed: (bool _) { },
253+
),
254+
));
255+
256+
expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics(
257+
onTapHint: localizations.expandedIconTapHint,
258+
children: <Matcher>[
259+
matchesSemantics(
260+
hasTapAction: true,
261+
hasEnabledState: true,
262+
isEnabled: true,
263+
isFocusable: true,
264+
isButton: true,
265+
),
266+
],
267+
));
268+
269+
await tester.pumpWidget(wrap(
270+
child: ExpandIcon(
271+
onPressed: (bool _) { },
272+
),
273+
));
274+
275+
expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics(
276+
onTapHint: localizations.collapsedIconTapHint,
277+
children: <Matcher>[
278+
matchesSemantics(
279+
hasTapAction: true,
280+
hasEnabledState: true,
281+
isEnabled: true,
282+
isFocusable: true,
283+
isButton: true,
284+
),
285+
],
286+
));
287+
288+
handle.dispose();
289+
});
290+
213291
testWidgets('ExpandIcon uses custom icon color and expanded icon color', (WidgetTester tester) async {
214292
bool expanded = false;
215293
IconTheme iconTheme;

packages/flutter/test/material/expansion_panel_test.dart

Lines changed: 147 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ void main() {
178178
expect(box.size.height - oldHeight, greaterThanOrEqualTo(100.0)); // 100 + some margin
179179
});
180180

181-
testWidgets('ExpansionPanelList does not merge header when canTapOnHeader is false', (WidgetTester tester) async {
181+
testWidgets('Material2 - ExpansionPanelList does not merge header when canTapOnHeader is false', (WidgetTester tester) async {
182182
final SemanticsHandle handle = tester.ensureSemantics();
183183
final Key headerKey = UniqueKey();
184184
await tester.pumpWidget(
@@ -226,6 +226,58 @@ void main() {
226226
handle.dispose();
227227
});
228228

229+
testWidgets('Material3 - ExpansionPanelList does not merge header when canTapOnHeader is false', (WidgetTester tester) async {
230+
final SemanticsHandle handle = tester.ensureSemantics();
231+
final Key headerKey = UniqueKey();
232+
await tester.pumpWidget(
233+
MaterialApp(
234+
home: ExpansionPanelListSemanticsTest(headerKey: headerKey),
235+
),
236+
);
237+
238+
// Make sure custom gesture detector widget is clickable.
239+
await tester.tap(find.text('head1'));
240+
await tester.pump();
241+
242+
final ExpansionPanelListSemanticsTestState state =
243+
tester.state(find.byType(ExpansionPanelListSemanticsTest));
244+
expect(state.headerTapped, true);
245+
246+
// Check the expansion icon semantics does not merged with header widget.
247+
final Finder expansionIcon = find.descendant(
248+
of: find.ancestor(
249+
of: find.byKey(headerKey),
250+
matching: find.byType(Row),
251+
),
252+
matching: find.byType(ExpandIcon),
253+
);
254+
255+
expect(tester.getSemantics(expansionIcon), matchesSemantics(
256+
label: 'Expand',
257+
children: <Matcher>[
258+
matchesSemantics(
259+
isButton: true,
260+
hasEnabledState: true,
261+
isEnabled: true,
262+
isFocusable: true,
263+
hasTapAction: true,
264+
),
265+
],
266+
));
267+
268+
// Check custom header widget semantics is preserved.
269+
final Finder headerWidget = find.descendant(
270+
of: find.byKey(headerKey),
271+
matching: find.byType(RichText),
272+
);
273+
expect(tester.getSemantics(headerWidget), matchesSemantics(
274+
label: 'head1',
275+
hasTapAction: true,
276+
));
277+
278+
handle.dispose();
279+
});
280+
229281
testWidgets('Multiple Panel List test', (WidgetTester tester) async {
230282
await tester.pumpWidget(
231283
MaterialApp(
@@ -998,7 +1050,7 @@ void main() {
9981050
await tester.pumpAndSettle();
9991051
});
10001052

1001-
testWidgets('Panel header has semantics, canTapOnHeader = false ', (WidgetTester tester) async {
1053+
testWidgets('Material2 - Panel header has semantics, canTapOnHeader = false', (WidgetTester tester) async {
10021054
const Key expandedKey = Key('expanded');
10031055
const Key collapsedKey = Key('collapsed');
10041056
const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();
@@ -1083,6 +1135,99 @@ void main() {
10831135
handle.dispose();
10841136
});
10851137

1138+
testWidgets('Material3 - Panel header has semantics, canTapOnHeader = false', (WidgetTester tester) async {
1139+
const Key expandedKey = Key('expanded');
1140+
const Key collapsedKey = Key('collapsed');
1141+
const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();
1142+
final SemanticsHandle handle = tester.ensureSemantics();
1143+
final List<ExpansionPanel> demoItems = <ExpansionPanel>[
1144+
ExpansionPanel(
1145+
headerBuilder: (BuildContext context, bool isExpanded) {
1146+
return const Text('Expanded', key: expandedKey);
1147+
},
1148+
body: const SizedBox(height: 100.0),
1149+
isExpanded: true,
1150+
),
1151+
ExpansionPanel(
1152+
headerBuilder: (BuildContext context, bool isExpanded) {
1153+
return const Text('Collapsed', key: collapsedKey);
1154+
},
1155+
body: const SizedBox(height: 100.0),
1156+
),
1157+
];
1158+
1159+
final ExpansionPanelList expansionList = ExpansionPanelList(
1160+
children: demoItems,
1161+
);
1162+
1163+
await tester.pumpWidget(
1164+
MaterialApp(
1165+
home: SingleChildScrollView(
1166+
child: expansionList,
1167+
),
1168+
),
1169+
);
1170+
1171+
// Check the semantics of [ExpandIcon] for expanded panel.
1172+
final Finder expandedIcon = find.descendant(
1173+
of: find.ancestor(
1174+
of: find.byKey(expandedKey),
1175+
matching: find.byType(Row),
1176+
),
1177+
matching: find.byType(ExpandIcon),
1178+
);
1179+
1180+
expect(tester.getSemantics(expandedIcon), matchesSemantics(
1181+
label: 'Collapse',
1182+
onTapHint: localizations.expandedIconTapHint,
1183+
children: <Matcher>[
1184+
matchesSemantics(
1185+
isButton: true,
1186+
hasEnabledState: true,
1187+
isEnabled: true,
1188+
isFocusable: true,
1189+
hasTapAction: true,
1190+
),
1191+
],
1192+
));
1193+
1194+
// Check the semantics of the header widget for expanded panel.
1195+
final Finder expandedHeader = find.byKey(expandedKey);
1196+
expect(tester.getSemantics(expandedHeader), matchesSemantics(
1197+
label: 'Expanded',
1198+
));
1199+
1200+
// Check the semantics of [ExpandIcon] for collapsed panel.
1201+
final Finder collapsedIcon = find.descendant(
1202+
of: find.ancestor(
1203+
of: find.byKey(collapsedKey),
1204+
matching: find.byType(Row),
1205+
),
1206+
matching: find.byType(ExpandIcon),
1207+
);
1208+
expect(tester.getSemantics(collapsedIcon), matchesSemantics(
1209+
label: 'Expand',
1210+
onTapHint: localizations.collapsedIconTapHint,
1211+
children: <Matcher>[
1212+
matchesSemantics(
1213+
isButton: true,
1214+
hasEnabledState: true,
1215+
isEnabled: true,
1216+
isFocusable: true,
1217+
hasTapAction: true,
1218+
),
1219+
],
1220+
));
1221+
1222+
// Check the semantics of the header widget for expanded panel.
1223+
final Finder collapsedHeader = find.byKey(collapsedKey);
1224+
expect(tester.getSemantics(collapsedHeader), matchesSemantics(
1225+
label: 'Collapsed',
1226+
));
1227+
1228+
handle.dispose();
1229+
});
1230+
10861231
testWidgets('Panel header has semantics, canTapOnHeader = true', (WidgetTester tester) async {
10871232
const Key expandedKey = Key('expanded');
10881233
const Key collapsedKey = Key('collapsed');

0 commit comments

Comments
 (0)