mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Add labeled tappable target guideline and gallery tests (#22824)
This commit is contained in:
parent
3188e5c6cf
commit
313059cdb6
@ -8,231 +8,464 @@ void main() {
|
||||
testWidgets('backdrop_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: BackdropDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('bottom_app_bar_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: BottomAppBarDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('bottom_navigation_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: BottomNavigationDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('buttons_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ButtonsDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('cards_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: CardsDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('chip_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ChipDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('data_table_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DataTableDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('date_and_time_picker_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DateAndTimePickerDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('dialog_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DialogDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('drawer_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DrawerDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('elevation_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ElevationDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('expansion_panels_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ExpansionPanelsDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('grid_list_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: GridListDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('icons_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: IconsDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('leave_behind_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('list_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: ListDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('menu_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ModalBottomSheetDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('overscroll_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('page_selector_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: PageSelectorDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: PersistentBottomSheetDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('progress_indicator_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ProgressIndicatorDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('reorderable_list_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('scrollable_tabs_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ScrollableTabsDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('search_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: SearchDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('selection_controls_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: SelectionControlsDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('slider_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: SliderDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('snack_bar_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: SnackBarDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('tabs_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: TabsDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('tabs_fab_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: TabsFabDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('text_form_field_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('tooltip_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: TooltipDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('two_level_list_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: TwoLevelListDemo()));
|
||||
expect(tester, meetsGuideline(androidTapTargetGuideline));
|
||||
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();
|
||||
await tester.pumpWidget(MaterialApp(home: BackdropDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('bottom_app_bar_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: BottomAppBarDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('bottom_navigation_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: BottomNavigationDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('buttons_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ButtonsDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('cards_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: CardsDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('chip_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ChipDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('data_table_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DataTableDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('date_and_time_picker_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DateAndTimePickerDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('dialog_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DialogDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('drawer_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: DrawerDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('elevation_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ElevationDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('expansion_panels_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ExpansionPanelsDemo()));
|
||||
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();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('icons_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: IconsDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('leave_behind_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('list_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: ListDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('menu_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ModalBottomSheetDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('overscroll_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('page_selector_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: PageSelectorDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: PersistentBottomSheetDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('progress_indicator_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ProgressIndicatorDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('reorderable_list_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('scrollable_tabs_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: ScrollableTabsDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('search_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: SearchDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('selection_controls_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: SelectionControlsDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('slider_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: SliderDemo()));
|
||||
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();
|
||||
await tester.pumpWidget(MaterialApp(home: TabsDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('tabs_fab_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: TabsFabDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
}, skip: true);
|
||||
|
||||
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();
|
||||
}, skip: true);
|
||||
|
||||
testWidgets('tooltip_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: TooltipDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('two_level_list_demo', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(MaterialApp(home: TwoLevelListDemo()));
|
||||
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
|
||||
handle.dispose();
|
||||
});
|
||||
});
|
||||
|
@ -124,6 +124,41 @@ class MinimumTapTargetGuideline extends AccessibilityGuideline {
|
||||
String get description => 'Tappable objects should be at least $size';
|
||||
}
|
||||
|
||||
/// A guideline which enforces that all nodes with a tap or long press action
|
||||
/// also have a label.
|
||||
@visibleForTesting
|
||||
class LabeledTapTargetGuideline extends AccessibilityGuideline {
|
||||
const LabeledTapTargetGuideline._();
|
||||
|
||||
@override
|
||||
String get description => 'Tappable widgets should have a semantic label';
|
||||
|
||||
@override
|
||||
FutureOr<Evaluation> evaluate(WidgetTester tester) {
|
||||
final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner.rootSemanticsNode;
|
||||
Evaluation traverse(SemanticsNode node) {
|
||||
Evaluation result = const Evaluation.pass();
|
||||
node.visitChildren((SemanticsNode child) {
|
||||
result += traverse(child);
|
||||
return true;
|
||||
});
|
||||
if (node.isMergedIntoParent)
|
||||
return result;
|
||||
final SemanticsData data = node.getSemanticsData();
|
||||
// Skip node if it has no actions, or is marked as hidden.
|
||||
if (!data.hasAction(ui.SemanticsAction.longPress) && !data.hasAction(ui.SemanticsAction.tap))
|
||||
return result;
|
||||
if (data.label == null || data.label.isEmpty) {
|
||||
result += Evaluation.fail(
|
||||
'$node: expected tappable node to have semantic label, but none was found\n',
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return traverse(root);
|
||||
}
|
||||
}
|
||||
|
||||
/// A guideline which verifies that all nodes that contribute semantics via text
|
||||
/// meet minimum contrast levels.
|
||||
///
|
||||
@ -403,3 +438,7 @@ const AccessibilityGuideline iOSTapTargetGuideline = MinimumTapTargetGuideline._
|
||||
/// foreground and background colors. The contrast ratio is calculated from
|
||||
/// these colors according to the [WCAG](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html#contrast-ratiodef)
|
||||
const AccessibilityGuideline textContrastGuideline = MinimumTextContrastGuideline._();
|
||||
|
||||
/// A guideline which enforces that all nodes with a tap or long press action
|
||||
/// also have a label.
|
||||
const AccessibilityGuideline labeledTapTargetGuideline = LabeledTapTargetGuideline._();
|
||||
|
@ -361,6 +361,63 @@ void main() {
|
||||
handle.dispose();
|
||||
});
|
||||
});
|
||||
|
||||
group('Labeled tappable node guideline', () {
|
||||
testWidgets('Passes when node is labeled', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(_boilerplate(Semantics(
|
||||
container: true,
|
||||
child: const SizedBox(width: 10.0, height: 10.0),
|
||||
onTap: () {},
|
||||
label: 'test',
|
||||
)));
|
||||
final Evaluation result = await labeledTapTargetGuideline.evaluate(tester);
|
||||
expect(result.passed, true);
|
||||
handle.dispose();
|
||||
});
|
||||
testWidgets('Fails if long-press has no label', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(_boilerplate(Semantics(
|
||||
container: true,
|
||||
child: const SizedBox(width: 10.0, height: 10.0),
|
||||
onLongPress: () {},
|
||||
label: '',
|
||||
)));
|
||||
final Evaluation result = await labeledTapTargetGuideline.evaluate(tester);
|
||||
expect(result.passed, false);
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Fails if tap has no label', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(_boilerplate(Semantics(
|
||||
container: true,
|
||||
child: const SizedBox(width: 10.0, height: 10.0),
|
||||
onTap: () {},
|
||||
label: '',
|
||||
)));
|
||||
final Evaluation result = await labeledTapTargetGuideline.evaluate(tester);
|
||||
expect(result.passed, false);
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Passes if tap is merged into labeled node', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(_boilerplate(Semantics(
|
||||
container: true,
|
||||
onLongPress: () {},
|
||||
label: '',
|
||||
child: Semantics(
|
||||
label: 'test',
|
||||
child: const SizedBox(width: 10.0, height: 10.0),
|
||||
),
|
||||
)));
|
||||
final Evaluation result = await labeledTapTargetGuideline.evaluate(tester);
|
||||
expect(result.passed, true);
|
||||
handle.dispose();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Widget _boilerplate(Widget child) {
|
||||
|
Loading…
Reference in New Issue
Block a user