Unverified Commit 313059cd authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Add labeled tappable target guideline and gallery tests (#22824)

parent 3188e5c6
...@@ -8,231 +8,464 @@ void main() { ...@@ -8,231 +8,464 @@ void main() {
testWidgets('backdrop_demo', (WidgetTester tester) async { testWidgets('backdrop_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: BackdropDemo())); await tester.pumpWidget(MaterialApp(home: BackdropDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('bottom_app_bar_demo', (WidgetTester tester) async { testWidgets('bottom_app_bar_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: BottomAppBarDemo())); await tester.pumpWidget(MaterialApp(home: BottomAppBarDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('bottom_navigation_demo', (WidgetTester tester) async { testWidgets('bottom_navigation_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: BottomNavigationDemo())); await tester.pumpWidget(MaterialApp(home: BottomNavigationDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('buttons_demo', (WidgetTester tester) async { testWidgets('buttons_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: ButtonsDemo())); await tester.pumpWidget(MaterialApp(home: ButtonsDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('cards_demo', (WidgetTester tester) async { testWidgets('cards_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: CardsDemo())); await tester.pumpWidget(MaterialApp(home: CardsDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('chip_demo', (WidgetTester tester) async { testWidgets('chip_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: ChipDemo())); await tester.pumpWidget(MaterialApp(home: ChipDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('data_table_demo', (WidgetTester tester) async { testWidgets('data_table_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: DataTableDemo())); await tester.pumpWidget(MaterialApp(home: DataTableDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('date_and_time_picker_demo', (WidgetTester tester) async { testWidgets('date_and_time_picker_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: DateAndTimePickerDemo())); await tester.pumpWidget(MaterialApp(home: DateAndTimePickerDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('dialog_demo', (WidgetTester tester) async { testWidgets('dialog_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: DialogDemo())); await tester.pumpWidget(MaterialApp(home: DialogDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('drawer_demo', (WidgetTester tester) async { testWidgets('drawer_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: DrawerDemo())); await tester.pumpWidget(MaterialApp(home: DrawerDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('elevation_demo', (WidgetTester tester) async { testWidgets('elevation_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: ElevationDemo())); await tester.pumpWidget(MaterialApp(home: ElevationDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('expansion_panels_demo', (WidgetTester tester) async { testWidgets('expansion_panels_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: ExpansionPanelsDemo())); await tester.pumpWidget(MaterialApp(home: ExpansionPanelsDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('grid_list_demo', (WidgetTester tester) async { testWidgets('grid_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: GridListDemo())); await tester.pumpWidget(const MaterialApp(home: GridListDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('icons_demo', (WidgetTester tester) async { testWidgets('icons_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: IconsDemo())); await tester.pumpWidget(MaterialApp(home: IconsDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('leave_behind_demo', (WidgetTester tester) async { testWidgets('leave_behind_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo())); await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('list_demo', (WidgetTester tester) async { testWidgets('list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: ListDemo())); await tester.pumpWidget(const MaterialApp(home: ListDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('menu_demo', (WidgetTester tester) async { testWidgets('menu_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: MenuDemo())); await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async { testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: ModalBottomSheetDemo())); await tester.pumpWidget(MaterialApp(home: ModalBottomSheetDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('overscroll_demo', (WidgetTester tester) async { testWidgets('overscroll_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: OverscrollDemo())); await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('page_selector_demo', (WidgetTester tester) async { testWidgets('page_selector_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: PageSelectorDemo())); await tester.pumpWidget(MaterialApp(home: PageSelectorDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async { testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: PersistentBottomSheetDemo())); await tester.pumpWidget(MaterialApp(home: PersistentBottomSheetDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('progress_indicator_demo', (WidgetTester tester) async { testWidgets('progress_indicator_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: ProgressIndicatorDemo())); await tester.pumpWidget(MaterialApp(home: ProgressIndicatorDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('reorderable_list_demo', (WidgetTester tester) async { testWidgets('reorderable_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo())); await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('scrollable_tabs_demo', (WidgetTester tester) async { testWidgets('scrollable_tabs_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: ScrollableTabsDemo())); await tester.pumpWidget(MaterialApp(home: ScrollableTabsDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('search_demo', (WidgetTester tester) async { testWidgets('search_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: SearchDemo())); await tester.pumpWidget(MaterialApp(home: SearchDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('selection_controls_demo', (WidgetTester tester) async { testWidgets('selection_controls_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: SelectionControlsDemo())); await tester.pumpWidget(MaterialApp(home: SelectionControlsDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('slider_demo', (WidgetTester tester) async { testWidgets('slider_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: SliderDemo())); await tester.pumpWidget(MaterialApp(home: SliderDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('snack_bar_demo', (WidgetTester tester) async { testWidgets('snack_bar_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: SnackBarDemo())); await tester.pumpWidget(const MaterialApp(home: SnackBarDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('tabs_demo', (WidgetTester tester) async { testWidgets('tabs_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: TabsDemo())); await tester.pumpWidget(MaterialApp(home: TabsDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('tabs_fab_demo', (WidgetTester tester) async { testWidgets('tabs_fab_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: TabsFabDemo())); await tester.pumpWidget(MaterialApp(home: TabsFabDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('text_form_field_demo', (WidgetTester tester) async { testWidgets('text_form_field_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo())); await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('tooltip_demo', (WidgetTester tester) async { testWidgets('tooltip_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: TooltipDemo())); await tester.pumpWidget(MaterialApp(home: TooltipDemo()));
expect(tester, meetsGuideline(androidTapTargetGuideline)); await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose(); handle.dispose();
}); });
testWidgets('two_level_list_demo', (WidgetTester tester) async { testWidgets('two_level_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget(MaterialApp(home: TwoLevelListDemo())); 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(); handle.dispose();
}); });
}); });
......
...@@ -124,6 +124,41 @@ class MinimumTapTargetGuideline extends AccessibilityGuideline { ...@@ -124,6 +124,41 @@ class MinimumTapTargetGuideline extends AccessibilityGuideline {
String get description => 'Tappable objects should be at least $size'; 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 /// A guideline which verifies that all nodes that contribute semantics via text
/// meet minimum contrast levels. /// meet minimum contrast levels.
/// ///
...@@ -403,3 +438,7 @@ const AccessibilityGuideline iOSTapTargetGuideline = MinimumTapTargetGuideline._ ...@@ -403,3 +438,7 @@ const AccessibilityGuideline iOSTapTargetGuideline = MinimumTapTargetGuideline._
/// foreground and background colors. The contrast ratio is calculated from /// 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) /// these colors according to the [WCAG](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html#contrast-ratiodef)
const AccessibilityGuideline textContrastGuideline = MinimumTextContrastGuideline._(); 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() { ...@@ -361,6 +361,63 @@ void main() {
handle.dispose(); 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) { Widget _boilerplate(Widget child) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment