accessibility_test.dart 33.6 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'package:flutter/material.dart';
import 'package:flutter_gallery/demo/all.dart';
7
import 'package:flutter_gallery/gallery/app.dart';
8
import 'package:flutter_gallery/gallery/themes.dart';
9
import 'package:flutter_test/flutter_test.dart';
10 11 12 13 14

void main() {
  group('All material demos meet recommended tap target sizes', () {
    testWidgets('backdrop_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
15
      await tester.pumpWidget(const MaterialApp(home: BackdropDemo()));
16
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
17 18 19 20 21
      handle.dispose();
    });

    testWidgets('bottom_app_bar_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
22
      await tester.pumpWidget(const MaterialApp(home: BottomAppBarDemo()));
23
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
24 25 26 27 28
      handle.dispose();
    });

    testWidgets('bottom_navigation_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
29
      await tester.pumpWidget(const MaterialApp(home: BottomNavigationDemo()));
30
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
31 32 33 34 35
      handle.dispose();
    });

    testWidgets('buttons_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
36
      await tester.pumpWidget(const MaterialApp(home: ButtonsDemo()));
37
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
38 39 40 41 42
      handle.dispose();
    });

    testWidgets('cards_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
43
      await tester.pumpWidget(const MaterialApp(home: CardsDemo()));
44
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
45 46 47 48 49
      handle.dispose();
    });

    testWidgets('chip_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
50
      await tester.pumpWidget(const MaterialApp(home: ChipDemo()));
51
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
52
      handle.dispose();
53
    }, skip: true); // https://github.com/flutter/flutter/issues/42455
54 55 56

    testWidgets('data_table_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
57
      await tester.pumpWidget(const MaterialApp(home: DataTableDemo()));
58
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
59 60 61 62 63
      handle.dispose();
    });

    testWidgets('date_and_time_picker_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
64
      await tester.pumpWidget(const MaterialApp(home: DateAndTimePickerDemo()));
65
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
66
      handle.dispose();
67
    });
68 69 70

    testWidgets('dialog_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
71
      await tester.pumpWidget(const MaterialApp(home: DialogDemo()));
72
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
73 74 75 76 77
      handle.dispose();
    });

    testWidgets('drawer_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
78
      await tester.pumpWidget(const MaterialApp(home: DrawerDemo()));
79
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
80 81 82 83 84
      handle.dispose();
    });

    testWidgets('elevation_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
85
      await tester.pumpWidget(const MaterialApp(home: ElevationDemo()));
86
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
87 88 89 90 91
      handle.dispose();
    });

    testWidgets('expansion_panels_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
92
      await tester.pumpWidget(const MaterialApp(home: ExpansionPanelsDemo()));
93
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
94 95 96 97 98
      handle.dispose();
    });

    testWidgets('grid_list_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
99
      await tester.pumpWidget(const MaterialApp(home: GridListDemo()));
100
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
101 102 103 104 105
      handle.dispose();
    });

    testWidgets('icons_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
106
      await tester.pumpWidget(const MaterialApp(home: IconsDemo()));
107
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
108 109 110 111
      handle.dispose();
    });

    testWidgets('leave_behind_demo', (WidgetTester tester) async {
112
      final SemanticsHandle handle = tester.ensureSemantics();
113
      await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
114
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
115 116 117 118
      handle.dispose();
    });

    testWidgets('list_demo', (WidgetTester tester) async {
119
      final SemanticsHandle handle = tester.ensureSemantics();
120
      await tester.pumpWidget(const MaterialApp(home: ListDemo()));
121
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
122 123 124 125
      handle.dispose();
    });

    testWidgets('menu_demo', (WidgetTester tester) async {
126
      final SemanticsHandle handle = tester.ensureSemantics();
127
      await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
128
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
129 130 131 132
      handle.dispose();
    });

    testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async {
133
      final SemanticsHandle handle = tester.ensureSemantics();
134
      await tester.pumpWidget(const MaterialApp(home: ModalBottomSheetDemo()));
135
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
136 137 138 139
      handle.dispose();
    });

    testWidgets('overscroll_demo', (WidgetTester tester) async {
140
      final SemanticsHandle handle = tester.ensureSemantics();
141
      await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
142
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
143 144 145 146
      handle.dispose();
    });

    testWidgets('page_selector_demo', (WidgetTester tester) async {
147
      final SemanticsHandle handle = tester.ensureSemantics();
148
      await tester.pumpWidget(const MaterialApp(home: PageSelectorDemo()));
149
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
150 151 152 153
      handle.dispose();
    });

    testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async {
154
      final SemanticsHandle handle = tester.ensureSemantics();
155
      await tester.pumpWidget(const MaterialApp(home: PersistentBottomSheetDemo()));
156
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
157 158 159 160
      handle.dispose();
    });

    testWidgets('progress_indicator_demo', (WidgetTester tester) async {
161
      final SemanticsHandle handle = tester.ensureSemantics();
162
      await tester.pumpWidget(const MaterialApp(home: ProgressIndicatorDemo()));
163
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
164 165 166 167
      handle.dispose();
    });

    testWidgets('reorderable_list_demo', (WidgetTester tester) async {
168
      final SemanticsHandle handle = tester.ensureSemantics();
169
      await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
170
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
171 172 173 174
      handle.dispose();
    });

    testWidgets('scrollable_tabs_demo', (WidgetTester tester) async {
175
      final SemanticsHandle handle = tester.ensureSemantics();
176
      await tester.pumpWidget(const MaterialApp(home: ScrollableTabsDemo()));
177
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
178 179 180 181 182
      handle.dispose();
    });

    testWidgets('search_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
183
      await tester.pumpWidget(const MaterialApp(home: SearchDemo()));
184
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
185 186 187 188 189
      handle.dispose();
    });

    testWidgets('selection_controls_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
190
      await tester.pumpWidget(const MaterialApp(home: SelectionControlsDemo()));
191
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
192 193 194 195 196
      handle.dispose();
    });

    testWidgets('slider_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
197
      await tester.pumpWidget(const MaterialApp(home: SliderDemo()));
198
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
199 200 201 202 203
      handle.dispose();
    });

    testWidgets('snack_bar_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
204
      await tester.pumpWidget(const MaterialApp(home: SnackBarDemo()));
205
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
206 207 208 209 210
      handle.dispose();
    });

    testWidgets('tabs_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
211
      await tester.pumpWidget(const MaterialApp(home: TabsDemo()));
212
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
213 214 215 216 217
      handle.dispose();
    });

    testWidgets('tabs_fab_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
218
      await tester.pumpWidget(const MaterialApp(home: TabsFabDemo()));
219
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
220 221 222 223 224
      handle.dispose();
    });

    testWidgets('text_form_field_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
225
      await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
226
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
227 228 229 230 231
      handle.dispose();
    });

    testWidgets('tooltip_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
232
      await tester.pumpWidget(const MaterialApp(home: TooltipDemo()));
233
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
234 235 236
      handle.dispose();
    });

237
    testWidgets('expansion_tile_list_demo', (WidgetTester tester) async {
238
      final SemanticsHandle handle = tester.ensureSemantics();
239
      await tester.pumpWidget(const MaterialApp(home: ExpansionTileListDemo()));
240 241 242 243 244 245 246 247
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
      handle.dispose();
    });
  });

  group('All material demos have labeled tap targets', () {
    testWidgets('backdrop_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
248
      await tester.pumpWidget(const MaterialApp(home: BackdropDemo()));
249 250
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
251
    });
252 253 254

    testWidgets('bottom_app_bar_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
255
      await tester.pumpWidget(const MaterialApp(home: BottomAppBarDemo()));
256 257
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
258
    });
259 260 261

    testWidgets('bottom_navigation_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
262
      await tester.pumpWidget(const MaterialApp(home: BottomNavigationDemo()));
263 264 265 266 267 268
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('buttons_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
269
      await tester.pumpWidget(const MaterialApp(home: ButtonsDemo()));
270 271
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
272
    });
273 274 275

    testWidgets('cards_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
276
      await tester.pumpWidget(const MaterialApp(home: CardsDemo()));
277 278
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
279
    });
280 281 282

    testWidgets('chip_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
283
      await tester.pumpWidget(const MaterialApp(home: ChipDemo()));
284 285 286 287 288 289
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('data_table_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
290
      await tester.pumpWidget(const MaterialApp(home: DataTableDemo()));
291 292
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
293
    }, skip: true); // DataTables are not accessible, https://github.com/flutter/flutter/issues/10830
294 295 296

    testWidgets('date_and_time_picker_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
297
      await tester.pumpWidget(const MaterialApp(home: DateAndTimePickerDemo()));
298 299 300 301 302 303
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('dialog_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
304
      await tester.pumpWidget(const MaterialApp(home: DialogDemo()));
305 306 307 308 309 310
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('drawer_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
311
      await tester.pumpWidget(const MaterialApp(home: DrawerDemo()));
312 313 314 315 316 317
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('elevation_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
318
      await tester.pumpWidget(const MaterialApp(home: ElevationDemo()));
319 320
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
321
    });
322 323 324

    testWidgets('expansion_panels_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
325
      await tester.pumpWidget(const MaterialApp(home: ExpansionPanelsDemo()));
326 327 328 329 330 331 332 333 334
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('grid_list_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
      await tester.pumpWidget(const MaterialApp(home: GridListDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
335
    });
336 337 338

    testWidgets('icons_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
339
      await tester.pumpWidget(const MaterialApp(home: IconsDemo()));
340 341 342 343 344
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('leave_behind_demo', (WidgetTester tester) async {
345
      final SemanticsHandle handle = tester.ensureSemantics();
346 347 348 349 350 351
      await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('list_demo', (WidgetTester tester) async {
352
      final SemanticsHandle handle = tester.ensureSemantics();
353 354 355 356 357 358
      await tester.pumpWidget(const MaterialApp(home: ListDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('menu_demo', (WidgetTester tester) async {
359
      final SemanticsHandle handle = tester.ensureSemantics();
360 361 362 363 364 365
      await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async {
366
      final SemanticsHandle handle = tester.ensureSemantics();
367
      await tester.pumpWidget(const MaterialApp(home: ModalBottomSheetDemo()));
368 369 370 371 372
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('overscroll_demo', (WidgetTester tester) async {
373
      final SemanticsHandle handle = tester.ensureSemantics();
374 375 376 377 378 379
      await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('page_selector_demo', (WidgetTester tester) async {
380
      final SemanticsHandle handle = tester.ensureSemantics();
381
      await tester.pumpWidget(const MaterialApp(home: PageSelectorDemo()));
382 383 384 385 386
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async {
387
      final SemanticsHandle handle = tester.ensureSemantics();
388
      await tester.pumpWidget(const MaterialApp(home: PersistentBottomSheetDemo()));
389 390 391 392 393
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('progress_indicator_demo', (WidgetTester tester) async {
394
      final SemanticsHandle handle = tester.ensureSemantics();
395
      await tester.pumpWidget(const MaterialApp(home: ProgressIndicatorDemo()));
396 397 398 399 400
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('reorderable_list_demo', (WidgetTester tester) async {
401
      final SemanticsHandle handle = tester.ensureSemantics();
402 403 404 405 406 407
      await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('scrollable_tabs_demo', (WidgetTester tester) async {
408
      final SemanticsHandle handle = tester.ensureSemantics();
409
      await tester.pumpWidget(const MaterialApp(home: ScrollableTabsDemo()));
410 411
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
412
    });
413 414 415

    testWidgets('search_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
416
      await tester.pumpWidget(const MaterialApp(home: SearchDemo()));
417 418 419 420 421 422
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('selection_controls_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
423
      await tester.pumpWidget(const MaterialApp(home: SelectionControlsDemo()));
424 425
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
426
    });
427 428 429

    testWidgets('slider_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
430
      await tester.pumpWidget(const MaterialApp(home: SliderDemo()));
431 432 433 434 435 436 437 438 439 440 441 442 443
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('snack_bar_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
      await tester.pumpWidget(const MaterialApp(home: SnackBarDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('tabs_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
444
      await tester.pumpWidget(const MaterialApp(home: TabsDemo()));
445 446 447 448 449 450
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('tabs_fab_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
451
      await tester.pumpWidget(const MaterialApp(home: TabsFabDemo()));
452 453
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
454
    });
455 456 457 458 459 460

    testWidgets('text_form_field_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
      await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
461
    });
462 463 464

    testWidgets('tooltip_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
465
      await tester.pumpWidget(const MaterialApp(home: TooltipDemo()));
466 467 468 469
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

470
    testWidgets('expansion_tile_list_demo', (WidgetTester tester) async {
471
      final SemanticsHandle handle = tester.ensureSemantics();
472
      await tester.pumpWidget(const MaterialApp(home: ExpansionTileListDemo()));
473
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
474 475 476 477 478
      handle.dispose();
    });
  });

  group('All material demos meet text contrast guidelines', () {
479
    final List<ThemeData> themes = <ThemeData>[
480
      kLightGalleryTheme,
481
      kDarkGalleryTheme,
482 483 484 485
    ];

    const List<String> themeNames = <String>[
      'kLightGalleryTheme',
486
      'kDarkGalleryTheme',
487 488 489 490 491 492 493 494
    ];

    for (int themeIndex = 0; themeIndex < themes.length; themeIndex += 1) {
      final ThemeData theme = themes[themeIndex];
      final String themeName = themeNames[themeIndex];

      testWidgets('backdrop_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
495
        await tester.pumpWidget(MaterialApp(theme: theme, home: const BackdropDemo()));
496 497 498 499 500 501
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('bottom_app_bar_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
502
        await tester.pumpWidget(MaterialApp(theme: theme, home: const BottomAppBarDemo()));
503 504
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
505
      });
506 507 508

      testWidgets('bottom_navigation_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
509
        await tester.pumpWidget(MaterialApp(theme: theme, home: const BottomNavigationDemo()));
510 511 512 513 514 515
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('buttons_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
516
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ButtonsDemo()));
517 518
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
519
      });
520 521 522

      testWidgets('cards_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
523
        await tester.pumpWidget(MaterialApp(theme: theme, home: const CardsDemo()));
524 525
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
526
      });
527 528 529

      testWidgets('chip_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
530
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ChipDemo()));
531 532
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
533
      });
534 535 536

      testWidgets('data_table_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
537
        await tester.pumpWidget(MaterialApp(theme: theme, home: const DataTableDemo()));
538 539
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
540
      });
541 542 543

      testWidgets('date_and_time_picker_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
544
        await tester.pumpWidget(MaterialApp(theme: theme, home: const DateAndTimePickerDemo()));
545 546
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
547
      });
548 549 550

      testWidgets('dialog_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
551
        await tester.pumpWidget(MaterialApp(theme: theme, home: const DialogDemo()));
552 553
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
554
      });
555 556 557

      testWidgets('drawer_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
558
        await tester.pumpWidget(MaterialApp(theme: theme, home: const DrawerDemo()));
559 560 561 562 563 564
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('elevation_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
565
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ElevationDemo()));
566 567 568 569 570 571
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('expansion_panels_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
572
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ExpansionPanelsDemo()));
573 574 575 576 577 578 579 580 581 582 583 584 585
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('grid_list_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
        await tester.pumpWidget(MaterialApp(theme: theme, home: const GridListDemo()));
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('icons_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
586
        await tester.pumpWidget(MaterialApp(theme: theme, home: const IconsDemo()));
587 588
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
589
      });
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613

      testWidgets('leave_behind_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
        await tester.pumpWidget(MaterialApp(theme: theme, home: const LeaveBehindDemo()));
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('list_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ListDemo()));
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('menu_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
        await tester.pumpWidget(MaterialApp(theme: theme, home: const MenuDemo()));
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('modal_bottom_sheet_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
614
        await tester.pumpWidget(
615
          MaterialApp(theme: theme, home: const ModalBottomSheetDemo())
616
        );
617 618
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
619
      });
620

621 622 623 624 625 626
      testWidgets('overscroll_demo', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
        await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });
627 628 629

      testWidgets('page_selector_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
630
        await tester.pumpWidget(MaterialApp(theme: theme, home: const PageSelectorDemo()));
631 632 633 634 635 636
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('persistent_bottom_sheet_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
637
        await tester.pumpWidget(
638
          MaterialApp(theme: theme, home: const PersistentBottomSheetDemo())
639
        );
640 641
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
642
      });
643 644 645

      testWidgets('progress_indicator_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
646
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ProgressIndicatorDemo()));
647 648 649 650 651 652 653 654 655 656 657 658 659
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('reorderable_list_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ReorderableListDemo()));
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('scrollable_tabs_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
660
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ScrollableTabsDemo()));
661 662 663 664 665 666
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('search_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
667
        await tester.pumpWidget(MaterialApp(theme: theme, home: const SearchDemo()));
668 669
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
670
      });
671 672 673

      testWidgets('selection_controls_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
674
        await tester.pumpWidget(MaterialApp(theme: theme, home: const SelectionControlsDemo()));
675 676 677 678 679 680
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('slider_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
681
        await tester.pumpWidget(MaterialApp(theme: theme, home: const SliderDemo()));
682 683 684 685 686 687
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('snack_bar_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
688 689 690
        await tester.pumpWidget(
          MaterialApp(theme: theme, home: const SnackBarDemo())
        );
691 692
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
693
      });
694 695 696

      testWidgets('tabs_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
697
        await tester.pumpWidget(MaterialApp(theme: theme, home: const TabsDemo()));
698 699 700 701 702 703
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('tabs_fab_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
704
        await tester.pumpWidget(MaterialApp(theme: theme, home: const TabsFabDemo()));
705 706 707 708 709 710 711 712 713 714 715 716 717
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('text_form_field_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
        await tester.pumpWidget(MaterialApp(theme: theme, home: const TextFormFieldDemo()));
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('tooltip_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
718
        await tester.pumpWidget(MaterialApp(theme: theme, home: const TooltipDemo()));
719 720 721 722
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

723
      testWidgets('expansion_tile_list_demo $themeName', (WidgetTester tester) async {
724
        final SemanticsHandle handle = tester.ensureSemantics();
725
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ExpansionTileListDemo()));
726 727 728 729
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });
    }
730
  });
731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761

  group('Gallery home page meets text contrast guidelines', () {
    testWidgets('options menu', (WidgetTester tester) async {
      await tester.pumpWidget(const GalleryApp(testMode: true));
      await tester.tap(find.byTooltip('Toggle options page'));
      await tester.pumpAndSettle();
      await expectLater(tester, meetsGuideline(textContrastGuideline));
    });

    testWidgets('options menu - dark theme', (WidgetTester tester) async {
      await tester.pumpWidget(const GalleryApp(testMode: true));
      await tester.tap(find.byTooltip('Toggle options page'));
      await tester.pumpAndSettle();

      // Toggle dark mode.
      final Finder themeToggleContainer = find.ancestor(
        of: find.text('Theme'),
        matching: find.byType(Container),
      );
      final Finder themeMenuButton = find.descendant(
        of: themeToggleContainer,
        matching: find.byIcon(Icons.arrow_drop_down),
      );
      await tester.tap(themeMenuButton);
      await tester.pumpAndSettle();
      await tester.tap(find.text('Dark'));
      await tester.pumpAndSettle();

      await expectLater(tester, meetsGuideline(textContrastGuideline));
    });
  });
762
}