accessibility_test.dart 34.1 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 15 16 17 18 19 20 21 22 23 24
class TestMaterialApp extends StatelessWidget {
  const TestMaterialApp({ super.key, required this.home });

  final Widget home;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(useMaterial3: false),
      home: home,
    );
  }
}

25 26 27 28
void main() {
  group('All material demos meet recommended tap target sizes', () {
    testWidgets('backdrop_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
29
      await tester.pumpWidget(const TestMaterialApp(home: BackdropDemo()));
30
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
31 32 33 34 35
      handle.dispose();
    });

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

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

    testWidgets('buttons_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
50
      await tester.pumpWidget(const TestMaterialApp(home: ButtonsDemo()));
51
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
52 53 54 55 56
      handle.dispose();
    });

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

    testWidgets('chip_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
64
      await tester.pumpWidget(const TestMaterialApp(home: ChipDemo()));
65
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
66
      handle.dispose();
67
    }, skip: true); // https://github.com/flutter/flutter/issues/42455
68 69 70

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    testWidgets('tabs_fab_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
232
      await tester.pumpWidget(const TestMaterialApp(home: TabsFabDemo()));
233
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
234 235 236 237 238
      handle.dispose();
    });

    testWidgets('text_form_field_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
239
      await tester.pumpWidget(const TestMaterialApp(home: TextFormFieldDemo()));
240
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
241 242 243 244 245
      handle.dispose();
    });

    testWidgets('tooltip_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
246
      await tester.pumpWidget(const TestMaterialApp(home: TooltipDemo()));
247
      await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
248 249 250
      handle.dispose();
    });

251
    testWidgets('expansion_tile_list_demo', (WidgetTester tester) async {
252
      final SemanticsHandle handle = tester.ensureSemantics();
253
      await tester.pumpWidget(const TestMaterialApp(home: ExpansionTileListDemo()));
254 255 256 257 258 259 260 261
      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();
262
      await tester.pumpWidget(const TestMaterialApp(home: BackdropDemo()));
263 264
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
265
    });
266 267 268

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

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

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

    testWidgets('cards_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
290
      await tester.pumpWidget(const TestMaterialApp(home: CardsDemo()));
291 292
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
293
    });
294 295 296

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

    testWidgets('data_table_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
304
      await tester.pumpWidget(const TestMaterialApp(home: DataTableDemo()));
305 306
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
307
    }, skip: true); // DataTables are not accessible, https://github.com/flutter/flutter/issues/10830
308 309 310

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

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

    testWidgets('drawer_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
325
      await tester.pumpWidget(const TestMaterialApp(home: DrawerDemo()));
326 327 328 329 330 331
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('elevation_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
332
      await tester.pumpWidget(const TestMaterialApp(home: ElevationDemo()));
333 334
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
335
    });
336 337 338

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

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

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

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

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

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

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

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

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

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

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

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

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

    testWidgets('search_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
430
      await tester.pumpWidget(const TestMaterialApp(home: SearchDemo()));
431 432 433 434 435 436
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('selection_controls_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
437
      await tester.pumpWidget(const TestMaterialApp(home: SelectionControlsDemo()));
438 439
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
440
    });
441 442 443

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

    testWidgets('snack_bar_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
451
      await tester.pumpWidget(const TestMaterialApp(home: SnackBarDemo()));
452 453 454 455 456 457
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('tabs_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
458
      await tester.pumpWidget(const TestMaterialApp(home: TabsDemo()));
459 460 461 462 463 464
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

    testWidgets('tabs_fab_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
465
      await tester.pumpWidget(const TestMaterialApp(home: TabsFabDemo()));
466 467
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
468
    });
469 470 471

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

    testWidgets('tooltip_demo', (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
479
      await tester.pumpWidget(const TestMaterialApp(home: TooltipDemo()));
480 481 482 483
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
      handle.dispose();
    });

484
    testWidgets('expansion_tile_list_demo', (WidgetTester tester) async {
485
      final SemanticsHandle handle = tester.ensureSemantics();
486
      await tester.pumpWidget(const TestMaterialApp(home: ExpansionTileListDemo()));
487
      await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
488 489 490 491 492
      handle.dispose();
    });
  });

  group('All material demos meet text contrast guidelines', () {
493
    final List<ThemeData> themes = <ThemeData>[
494
      kLightGalleryTheme,
495
      kDarkGalleryTheme,
496 497 498 499
    ];

    const List<String> themeNames = <String>[
      'kLightGalleryTheme',
500
      'kDarkGalleryTheme',
501 502 503 504 505 506 507 508
    ];

    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();
509
        await tester.pumpWidget(MaterialApp(theme: theme, home: const BackdropDemo()));
510 511 512 513 514 515
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

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

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

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

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

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

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

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

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

      testWidgets('drawer_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
572
        await tester.pumpWidget(MaterialApp(theme: theme, home: const DrawerDemo()));
573 574 575 576 577 578
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('elevation_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
579
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ElevationDemo()));
580 581 582 583 584 585
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('expansion_panels_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
586
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ExpansionPanelsDemo()));
587 588 589 590 591 592 593 594 595 596 597 598 599
        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();
600
        await tester.pumpWidget(MaterialApp(theme: theme, home: const IconsDemo()));
601 602
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
603
      });
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627

      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();
628
        await tester.pumpWidget(
629
          MaterialApp(theme: theme, home: const ModalBottomSheetDemo())
630
        );
631 632
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
633
      });
634

635 636 637 638 639 640
      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();
      });
641 642 643

      testWidgets('page_selector_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
644
        await tester.pumpWidget(MaterialApp(theme: theme, home: const PageSelectorDemo()));
645 646 647 648 649 650
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

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

      testWidgets('progress_indicator_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
660
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ProgressIndicatorDemo()));
661 662 663 664 665 666 667 668 669 670 671 672 673
        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();
674
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ScrollableTabsDemo()));
675 676 677 678 679 680
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

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

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

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

      testWidgets('snack_bar_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
702 703 704
        await tester.pumpWidget(
          MaterialApp(theme: theme, home: const SnackBarDemo())
        );
705 706
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
707
      });
708 709 710

      testWidgets('tabs_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
711
        await tester.pumpWidget(MaterialApp(theme: theme, home: const TabsDemo()));
712 713 714 715 716 717
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

      testWidgets('tabs_fab_demo $themeName', (WidgetTester tester) async {
        final SemanticsHandle handle = tester.ensureSemantics();
718
        await tester.pumpWidget(MaterialApp(theme: theme, home: const TabsFabDemo()));
719 720 721 722 723 724 725 726 727 728 729 730 731
        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();
732
        await tester.pumpWidget(MaterialApp(theme: theme, home: const TooltipDemo()));
733 734 735 736
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });

737
      testWidgets('expansion_tile_list_demo $themeName', (WidgetTester tester) async {
738
        final SemanticsHandle handle = tester.ensureSemantics();
739
        await tester.pumpWidget(MaterialApp(theme: theme, home: const ExpansionTileListDemo()));
740 741 742 743
        await expectLater(tester, meetsGuideline(textContrastGuideline));
        handle.dispose();
      });
    }
744
  });
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775

  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));
    });
  });
776
}