From 9b281bec206e90e564fcc66289cdcea8982070f3 Mon Sep 17 00:00:00 2001 From: hangyu Date: Wed, 7 Aug 2024 17:19:12 -0700 Subject: [PATCH] Add drawer and navigation drawer in a11y assessment app, also run `dart format` under a11y_assessments/ (#153034) --- dev/a11y_assessments/lib/main.dart | 44 ++--- .../lib/use_cases/auto_complete.dart | 7 +- dev/a11y_assessments/lib/use_cases/badge.dart | 1 - .../lib/use_cases/check_box_list_tile.dart | 1 - .../lib/use_cases/date_picker.dart | 2 - .../lib/use_cases/dialog.dart | 1 - .../lib/use_cases/drawer.dart | 88 +++++++++ .../lib/use_cases/expansion_tile.dart | 5 +- .../lib/use_cases/material_banner.dart | 4 +- .../lib/use_cases/navigation_bar.dart | 1 - .../lib/use_cases/navigation_drawer.dart | 117 +++++++++++ .../lib/use_cases/navigation_rail.dart | 183 ++++++++++++++++++ .../lib/use_cases/radio_list_tile.dart | 1 - .../lib/use_cases/slider.dart | 1 - .../lib/use_cases/text_button.dart | 5 +- .../lib/use_cases/text_field.dart | 1 - .../lib/use_cases/text_field_password.dart | 1 - .../lib/use_cases/use_cases.dart | 6 + .../test/accessibility_guideline_test.dart | 6 +- .../test/check_box_list_tile_test.dart | 3 +- dev/a11y_assessments/test/drawer_test.dart | 23 +++ dev/a11y_assessments/test/home_page_test.dart | 178 +++++++++++------ .../test/navigation_drawer_test.dart | 23 +++ .../test/navigation_rail_test.dart | 17 ++ .../test/radio_list_tile_test.dart | 3 +- dev/a11y_assessments/test/slider_test.dart | 6 +- dev/a11y_assessments/test/snack_bar_test.dart | 2 +- .../test/text_button_test.dart | 3 +- .../test/text_field_password_test.dart | 4 +- .../test/text_field_test.dart | 6 +- 30 files changed, 631 insertions(+), 112 deletions(-) create mode 100644 dev/a11y_assessments/lib/use_cases/drawer.dart create mode 100644 dev/a11y_assessments/lib/use_cases/navigation_drawer.dart create mode 100644 dev/a11y_assessments/lib/use_cases/navigation_rail.dart create mode 100644 dev/a11y_assessments/test/drawer_test.dart create mode 100644 dev/a11y_assessments/test/navigation_drawer_test.dart create mode 100644 dev/a11y_assessments/test/navigation_rail_test.dart diff --git a/dev/a11y_assessments/lib/main.dart b/dev/a11y_assessments/lib/main.dart index 96cd0f17d3..bcff75b2ff 100644 --- a/dev/a11y_assessments/lib/main.dart +++ b/dev/a11y_assessments/lib/main.dart @@ -21,28 +21,27 @@ class App extends StatelessWidget { @override Widget build(BuildContext context) { final ThemeData lightTheme = ThemeData( - colorScheme: ColorScheme.fromSeed( - seedColor: const Color(0xff6750a4), - contrastLevel: MediaQuery.highContrastOf(context) ? 1.0 : 0.0, + colorScheme: ColorScheme.fromSeed( + seedColor: const Color(0xff6750a4), + contrastLevel: MediaQuery.highContrastOf(context) ? 1.0 : 0.0, )); final ThemeData darkTheme = ThemeData( - colorScheme: ColorScheme.fromSeed( - brightness: Brightness.dark, - seedColor: const Color(0xff6750a4), - contrastLevel: MediaQuery.highContrastOf(context) ? 1.0 : 0.0, + colorScheme: ColorScheme.fromSeed( + brightness: Brightness.dark, + seedColor: const Color(0xff6750a4), + contrastLevel: MediaQuery.highContrastOf(context) ? 1.0 : 0.0, )); - final Map routes = Map.fromEntries( - useCases.map((UseCase useCase) => MapEntry(useCase.route, useCase.build)), + final Map routes = + Map.fromEntries( + useCases.map((UseCase useCase) => + MapEntry(useCase.route, useCase.build)), ); return MaterialApp( title: 'Accessibility Assessments', theme: lightTheme, darkTheme: darkTheme, - routes: { - '/': (_) => const HomePage(), - ...routes - }, + routes: {'/': (_) => const HomePage(), ...routes}, ); } } @@ -65,17 +64,14 @@ class HomePageState extends State { Widget _buildUseCaseItem(int index, UseCase useCase) { return Padding( - padding: const EdgeInsets.all(10), - child: Builder( - builder: (BuildContext context) { - return TextButton( - key: Key(useCase.name), - onPressed: () => Navigator.of(context).pushNamed(useCase.route), - child: Text(useCase.name), - ); - } - ) - ); + padding: const EdgeInsets.all(10), + child: Builder(builder: (BuildContext context) { + return TextButton( + key: Key(useCase.name), + onPressed: () => Navigator.of(context).pushNamed(useCase.route), + child: Text(useCase.name), + ); + })); } @override diff --git a/dev/a11y_assessments/lib/use_cases/auto_complete.dart b/dev/a11y_assessments/lib/use_cases/auto_complete.dart index ec82f5509b..64ec8564db 100644 --- a/dev/a11y_assessments/lib/use_cases/auto_complete.dart +++ b/dev/a11y_assessments/lib/use_cases/auto_complete.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class AutoCompleteUseCase extends UseCase { - @override String get name => 'AutoComplete'; @@ -32,7 +31,11 @@ class _MainWidgetState extends State<_MainWidget> { 'lemon', ]; - static Widget _fieldViewBuilder(BuildContext context, TextEditingController textEditingController, FocusNode focusNode, VoidCallback onFieldSubmitted) { + static Widget _fieldViewBuilder( + BuildContext context, + TextEditingController textEditingController, + FocusNode focusNode, + VoidCallback onFieldSubmitted) { return TextFormField( focusNode: focusNode, controller: textEditingController, diff --git a/dev/a11y_assessments/lib/use_cases/badge.dart b/dev/a11y_assessments/lib/use_cases/badge.dart index c39f1dccda..901ba823d8 100644 --- a/dev/a11y_assessments/lib/use_cases/badge.dart +++ b/dev/a11y_assessments/lib/use_cases/badge.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class BadgeUseCase extends UseCase { - @override String get name => 'Badge'; diff --git a/dev/a11y_assessments/lib/use_cases/check_box_list_tile.dart b/dev/a11y_assessments/lib/use_cases/check_box_list_tile.dart index 678b10ab0f..f3a60d90a8 100644 --- a/dev/a11y_assessments/lib/use_cases/check_box_list_tile.dart +++ b/dev/a11y_assessments/lib/use_cases/check_box_list_tile.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class CheckBoxListTile extends UseCase { - @override String get name => 'CheckBoxListTile'; diff --git a/dev/a11y_assessments/lib/use_cases/date_picker.dart b/dev/a11y_assessments/lib/use_cases/date_picker.dart index 0a6b1e8556..e41f721393 100644 --- a/dev/a11y_assessments/lib/use_cases/date_picker.dart +++ b/dev/a11y_assessments/lib/use_cases/date_picker.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class DatePickerUseCase extends UseCase { - @override String get name => 'DatePicker'; @@ -26,7 +25,6 @@ class _MainWidget extends StatefulWidget { } class _MainWidgetState extends State<_MainWidget> { - @override Widget build(BuildContext context) { return Scaffold( diff --git a/dev/a11y_assessments/lib/use_cases/dialog.dart b/dev/a11y_assessments/lib/use_cases/dialog.dart index aa54105601..dbde1a4a67 100644 --- a/dev/a11y_assessments/lib/use_cases/dialog.dart +++ b/dev/a11y_assessments/lib/use_cases/dialog.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class DialogUseCase extends UseCase { - @override String get name => 'Dialog'; diff --git a/dev/a11y_assessments/lib/use_cases/drawer.dart b/dev/a11y_assessments/lib/use_cases/drawer.dart new file mode 100644 index 0000000000..af9bea2d73 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/drawer.dart @@ -0,0 +1,88 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class DrawerUseCase extends UseCase { + @override + String get name => 'drawer'; + + @override + String get route => '/drawer'; + + @override + Widget build(BuildContext context) => const DrawerExample(); +} + +class DrawerExample extends StatefulWidget { + const DrawerExample({super.key}); + + @override + State createState() => _DrawerExampleState(); +} + +class _DrawerExampleState extends State { + String selectedPage = ''; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Drawer Example'), + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + ), + endDrawer: Drawer( + child: ListView( + padding: EdgeInsets.zero, + children: [ + const DrawerHeader( + decoration: BoxDecoration( + color: Colors.blue, + ), + child: Text( + 'Drawer Header', + style: TextStyle( + color: Colors.white, + fontSize: 24, + ), + ), + ), + ListTile( + leading: const Icon(Icons.message), + title: const Text('Messages'), + onTap: () { + setState(() { + selectedPage = 'Messages'; + }); + }, + ), + ListTile( + leading: const Icon(Icons.account_circle), + title: const Text('Profile'), + onTap: () { + setState(() { + selectedPage = 'Profile'; + }); + }, + ), + ListTile( + leading: const Icon(Icons.settings), + title: const Text('Settings'), + onTap: () { + setState(() { + selectedPage = 'Settings'; + }); + }, + ), + ], + ), + ), + body: Center( + child: Text('Page: $selectedPage'), + ), + ); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/expansion_tile.dart b/dev/a11y_assessments/lib/use_cases/expansion_tile.dart index 2a4cc8d137..bf451c4693 100644 --- a/dev/a11y_assessments/lib/use_cases/expansion_tile.dart +++ b/dev/a11y_assessments/lib/use_cases/expansion_tile.dart @@ -17,7 +17,6 @@ class ExpansionTileUseCase extends UseCase { Widget build(BuildContext context) => const ExpansionTileExample(); } - class ExpansionTileExample extends StatefulWidget { const ExpansionTileExample({super.key}); @@ -48,7 +47,9 @@ class _ExpansionTileExampleState extends State { title: const Text('ExpansionTile 2'), subtitle: const Text('Custom expansion arrow icon'), trailing: Icon( - _customTileExpanded ? Icons.arrow_drop_down_circle : Icons.arrow_drop_down, + _customTileExpanded + ? Icons.arrow_drop_down_circle + : Icons.arrow_drop_down, ), children: const [ ListTile(title: Text('This is tile number 2')), diff --git a/dev/a11y_assessments/lib/use_cases/material_banner.dart b/dev/a11y_assessments/lib/use_cases/material_banner.dart index 28f7106cd0..6888419ed6 100644 --- a/dev/a11y_assessments/lib/use_cases/material_banner.dart +++ b/dev/a11y_assessments/lib/use_cases/material_banner.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class MaterialBannerUseCase extends UseCase { - @override String get name => 'MaterialBanner'; @@ -27,7 +26,8 @@ class MainWidget extends StatefulWidget { class MainWidgetState extends State { double currentSliderValue = 20; - ScaffoldFeatureController? controller; + ScaffoldFeatureController? + controller; @override Widget build(BuildContext context) { diff --git a/dev/a11y_assessments/lib/use_cases/navigation_bar.dart b/dev/a11y_assessments/lib/use_cases/navigation_bar.dart index 6dc4fad2e2..6299ec2b69 100644 --- a/dev/a11y_assessments/lib/use_cases/navigation_bar.dart +++ b/dev/a11y_assessments/lib/use_cases/navigation_bar.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class NavigationBarUseCase extends UseCase { - @override String get name => 'NavigationBar'; diff --git a/dev/a11y_assessments/lib/use_cases/navigation_drawer.dart b/dev/a11y_assessments/lib/use_cases/navigation_drawer.dart new file mode 100644 index 0000000000..e59d45bf43 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/navigation_drawer.dart @@ -0,0 +1,117 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class ExampleDestination { + const ExampleDestination(this.label, this.icon, this.selectedIcon); + + final String label; + final Widget icon; + final Widget selectedIcon; +} + +const List destinations = [ + ExampleDestination( + 'Messages', Icon(Icons.widgets_outlined), Icon(Icons.widgets)), + ExampleDestination( + 'Profile', Icon(Icons.format_paint_outlined), Icon(Icons.format_paint)), + ExampleDestination( + 'Settings', Icon(Icons.settings_outlined), Icon(Icons.settings)), +]; + +class NavigationDrawerUseCase extends UseCase { + @override + String get name => 'NavigationDrawer'; + + @override + String get route => '/navigation-drawer'; + + @override + Widget build(BuildContext context) => const NavigationDrawerExample(); +} + +class NavigationDrawerExample extends StatefulWidget { + const NavigationDrawerExample({super.key}); + + @override + State createState() => + _NavigationDrawerExampleState(); +} + +class _NavigationDrawerExampleState extends State { + final GlobalKey scaffoldKey = GlobalKey(); + + int screenIndex = 0; + late bool showNavigationDrawer; + + void handleScreenChanged(int selectedScreen) { + setState(() { + screenIndex = selectedScreen; + }); + } + + void openDrawer() { + scaffoldKey.currentState!.openEndDrawer(); + } + + Widget buildDrawerScaffold(BuildContext context) { + return Scaffold( + key: scaffoldKey, + appBar: AppBar( + title: const Text('Navigation Drawer Example'), + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + ), + body: SafeArea( + bottom: false, + top: false, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text('Page Index = $screenIndex'), + ElevatedButton( + onPressed: openDrawer, + child: const Text('Open Drawer'), + ), + ], + ), + ), + ), + endDrawer: NavigationDrawer( + onDestinationSelected: handleScreenChanged, + selectedIndex: screenIndex, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(28, 16, 16, 10), + child: Text( + 'Header', + style: Theme.of(context).textTheme.titleSmall, + ), + ), + ...destinations.map( + (ExampleDestination destination) { + return NavigationDrawerDestination( + label: Text(destination.label), + icon: destination.icon, + selectedIcon: destination.selectedIcon, + ); + }, + ), + const Padding( + padding: EdgeInsets.fromLTRB(28, 16, 28, 10), + child: Divider(), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return buildDrawerScaffold(context); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/navigation_rail.dart b/dev/a11y_assessments/lib/use_cases/navigation_rail.dart new file mode 100644 index 0000000000..d5a69ae3d0 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/navigation_rail.dart @@ -0,0 +1,183 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class NavigationRailUseCase extends UseCase { + @override + String get name => 'NavigationRail'; + + @override + String get route => '/navigation-rail'; + + @override + Widget build(BuildContext context) => const NavRailExample(); +} + +class NavRailExample extends StatefulWidget { + const NavRailExample({super.key}); + + @override + State createState() => _NavRailExampleState(); +} + +class _NavRailExampleState extends State { + int _selectedIndex = 0; + NavigationRailLabelType labelType = NavigationRailLabelType.all; + bool showLeading = false; + bool showTrailing = false; + double groupAlignment = -1.0; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Row( + children: [ + NavigationRail( + selectedIndex: _selectedIndex, + groupAlignment: groupAlignment, + onDestinationSelected: (int index) { + setState(() { + _selectedIndex = index; + }); + }, + labelType: labelType, + leading: showLeading + ? FloatingActionButton( + elevation: 0, + onPressed: () { + // Add your onPressed code here! + }, + child: const Icon(Icons.add), + ) + : const SizedBox(), + trailing: showTrailing + ? IconButton( + onPressed: () { + // Add your onPressed code here! + }, + icon: const Icon(Icons.more_horiz_rounded), + ) + : const SizedBox(), + destinations: const [ + NavigationRailDestination( + icon: Icon(Icons.favorite_border), + selectedIcon: Icon(Icons.favorite), + label: Text('First'), + ), + NavigationRailDestination( + icon: Icon(Icons.bookmark_border), + selectedIcon: Icon(Icons.book), + label: Text('Second'), + ), + NavigationRailDestination( + icon: Icon(Icons.star_border), + selectedIcon: Icon(Icons.star), + label: Text('Third'), + ), + ], + ), + const VerticalDivider(thickness: 1, width: 1), + // This is the main content. + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('selectedIndex: $_selectedIndex'), + const SizedBox(height: 20), + Text('Label type: ${labelType.name}'), + const SizedBox(height: 10), + OverflowBar( + spacing: 10.0, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + labelType = NavigationRailLabelType.none; + }); + }, + child: const Text('None'), + ), + ElevatedButton( + onPressed: () { + setState(() { + labelType = NavigationRailLabelType.selected; + }); + }, + child: const Text('Selected'), + ), + ElevatedButton( + onPressed: () { + setState(() { + labelType = NavigationRailLabelType.all; + }); + }, + child: const Text('All'), + ), + ], + ), + const SizedBox(height: 20), + Text('Group alignment: $groupAlignment'), + const SizedBox(height: 10), + OverflowBar( + spacing: 10.0, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + groupAlignment = -1.0; + }); + }, + child: const Text('Top'), + ), + ElevatedButton( + onPressed: () { + setState(() { + groupAlignment = 0.0; + }); + }, + child: const Text('Center'), + ), + ElevatedButton( + onPressed: () { + setState(() { + groupAlignment = 1.0; + }); + }, + child: const Text('Bottom'), + ), + ], + ), + const SizedBox(height: 20), + OverflowBar( + spacing: 10.0, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + showLeading = !showLeading; + }); + }, + child: Text(showLeading ? 'Hide Leading' : 'Show Leading'), + ), + ElevatedButton( + onPressed: () { + setState(() { + showTrailing = !showTrailing; + }); + }, + child: Text(showTrailing ? 'Hide Trailing' : 'Show Trailing'), + ), + ], + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/radio_list_tile.dart b/dev/a11y_assessments/lib/use_cases/radio_list_tile.dart index 9bcf120009..aea5e53665 100644 --- a/dev/a11y_assessments/lib/use_cases/radio_list_tile.dart +++ b/dev/a11y_assessments/lib/use_cases/radio_list_tile.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class RadioListTileUseCase extends UseCase { - @override String get name => 'RadioListTile'; diff --git a/dev/a11y_assessments/lib/use_cases/slider.dart b/dev/a11y_assessments/lib/use_cases/slider.dart index 01eeb02620..f6b79f10df 100644 --- a/dev/a11y_assessments/lib/use_cases/slider.dart +++ b/dev/a11y_assessments/lib/use_cases/slider.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class SliderUseCase extends UseCase { - @override String get name => 'Slider'; diff --git a/dev/a11y_assessments/lib/use_cases/text_button.dart b/dev/a11y_assessments/lib/use_cases/text_button.dart index 4932d53d2f..54b95e2da2 100644 --- a/dev/a11y_assessments/lib/use_cases/text_button.dart +++ b/dev/a11y_assessments/lib/use_cases/text_button.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class TextButtonUseCase extends UseCase { - @override String get name => 'TextButton'; @@ -46,7 +45,9 @@ class MainWidgetState extends State { const Text('This is a TextButton:'), TextButton( onPressed: () { - setState(() { _count++; }); + setState(() { + _count++; + }); }, child: const Text('Action'), ), diff --git a/dev/a11y_assessments/lib/use_cases/text_field.dart b/dev/a11y_assessments/lib/use_cases/text_field.dart index 378be4444c..f4b99482cc 100644 --- a/dev/a11y_assessments/lib/use_cases/text_field.dart +++ b/dev/a11y_assessments/lib/use_cases/text_field.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class TextFieldUseCase extends UseCase { - @override String get name => 'TextField'; diff --git a/dev/a11y_assessments/lib/use_cases/text_field_password.dart b/dev/a11y_assessments/lib/use_cases/text_field_password.dart index 513604cc5e..f4b6ab97e6 100644 --- a/dev/a11y_assessments/lib/use_cases/text_field_password.dart +++ b/dev/a11y_assessments/lib/use_cases/text_field_password.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'use_cases.dart'; class TextFieldPasswordUseCase extends UseCase { - @override String get name => 'TextField password'; diff --git a/dev/a11y_assessments/lib/use_cases/use_cases.dart b/dev/a11y_assessments/lib/use_cases/use_cases.dart index f6d8e1bc58..2f63888182 100644 --- a/dev/a11y_assessments/lib/use_cases/use_cases.dart +++ b/dev/a11y_assessments/lib/use_cases/use_cases.dart @@ -11,9 +11,12 @@ import 'card.dart'; import 'check_box_list_tile.dart'; import 'date_picker.dart'; import 'dialog.dart'; +import 'drawer.dart'; import 'expansion_tile.dart'; import 'material_banner.dart'; import 'navigation_bar.dart'; +import 'navigation_drawer.dart'; +import 'navigation_rail.dart'; import 'radio_list_tile.dart'; import 'slider.dart'; import 'snack_bar.dart'; @@ -46,4 +49,7 @@ final List useCases = [ SwitchListTileUseCase(), ExpansionTileUseCase(), CardUseCase(), + DrawerUseCase(), + NavigationDrawerUseCase(), + NavigationRailUseCase(), ]; diff --git a/dev/a11y_assessments/test/accessibility_guideline_test.dart b/dev/a11y_assessments/test/accessibility_guideline_test.dart index 08f73effed..c36807c067 100644 --- a/dev/a11y_assessments/test/accessibility_guideline_test.dart +++ b/dev/a11y_assessments/test/accessibility_guideline_test.dart @@ -9,9 +9,11 @@ import 'package:flutter_test/flutter_test.dart'; void main() { for (final UseCase useCase in useCases) { - testWidgets('testing accessibility guideline for ${useCase.name}', (WidgetTester tester) async { + testWidgets('testing accessibility guideline for ${useCase.name}', + (WidgetTester tester) async { await tester.pumpWidget(const App()); - final ScrollController controller = tester.state(find.byType(HomePage)).scrollController; + final ScrollController controller = + tester.state(find.byType(HomePage)).scrollController; while (find.byKey(Key(useCase.name)).evaluate().isEmpty) { controller.jumpTo(controller.offset + 600); await tester.pumpAndSettle(); diff --git a/dev/a11y_assessments/test/check_box_list_tile_test.dart b/dev/a11y_assessments/test/check_box_list_tile_test.dart index 8e653d5d55..6dd236264d 100644 --- a/dev/a11y_assessments/test/check_box_list_tile_test.dart +++ b/dev/a11y_assessments/test/check_box_list_tile_test.dart @@ -8,7 +8,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'test_utils.dart'; void main() { - testWidgets('check box list tile use-case renders check boxes', (WidgetTester tester) async { + testWidgets('check box list tile use-case renders check boxes', + (WidgetTester tester) async { await pumpsUseCase(tester, CheckBoxListTile()); expect(find.text('a check box list title'), findsOneWidget); expect(find.text('a disabled check box list title'), findsOneWidget); diff --git a/dev/a11y_assessments/test/drawer_test.dart b/dev/a11y_assessments/test/drawer_test.dart new file mode 100644 index 0000000000..eae212b1f5 --- /dev/null +++ b/dev/a11y_assessments/test/drawer_test.dart @@ -0,0 +1,23 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/drawer.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('drawer can run', (WidgetTester tester) async { + await pumpsUseCase(tester, DrawerUseCase()); + + final ScaffoldState state = tester.firstState(find.byType(Scaffold)); + state.openEndDrawer(); + + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); + + expect(find.byType(Drawer), findsExactly(1)); + }); +} diff --git a/dev/a11y_assessments/test/home_page_test.dart b/dev/a11y_assessments/test/home_page_test.dart index 33b888be52..ef029624a2 100644 --- a/dev/a11y_assessments/test/home_page_test.dart +++ b/dev/a11y_assessments/test/home_page_test.dart @@ -7,75 +7,137 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:material_color_utilities/material_color_utilities.dart'; - void main() { testWidgets('Has light and dark theme', (WidgetTester tester) async { await tester.pumpWidget(const App()); - final MaterialApp app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp; + final MaterialApp app = + find.byType(MaterialApp).evaluate().first.widget as MaterialApp; expect(app.theme!.brightness, equals(Brightness.light)); expect(app.darkTheme!.brightness, equals(Brightness.dark)); }); - testWidgets('App can generate high-contrast color scheme', (WidgetTester tester) async { + testWidgets('App can generate high-contrast color scheme', + (WidgetTester tester) async { await tester.pumpWidget(const MediaQuery( - data: MediaQueryData( - highContrast: true, - ), - child: App() - )); + data: MediaQueryData( + highContrast: true, + ), + child: App())); - final MaterialApp app = find.byType(MaterialApp).evaluate().first.widget as MaterialApp; + final MaterialApp app = + find.byType(MaterialApp).evaluate().first.widget as MaterialApp; - final DynamicScheme highContrastScheme = SchemeTonalSpot(sourceColorHct: Hct.fromInt(const Color(0xff6750a4).value), isDark: false, contrastLevel: 1.0); + final DynamicScheme highContrastScheme = SchemeTonalSpot( + sourceColorHct: Hct.fromInt(const Color(0xff6750a4).value), + isDark: false, + contrastLevel: 1.0); final ColorScheme appScheme = app.theme!.colorScheme; - expect(appScheme.primary.value, MaterialDynamicColors.primary.getArgb(highContrastScheme)); - expect(appScheme.onPrimary.value, MaterialDynamicColors.onPrimary.getArgb(highContrastScheme)); - expect(appScheme.primaryContainer.value, MaterialDynamicColors.primaryContainer.getArgb(highContrastScheme)); - expect(appScheme.onPrimaryContainer.value, MaterialDynamicColors.onPrimaryContainer.getArgb(highContrastScheme)); - expect(appScheme.primaryFixed.value, MaterialDynamicColors.primaryFixed.getArgb(highContrastScheme)); - expect(appScheme.primaryFixedDim.value, MaterialDynamicColors.primaryFixedDim.getArgb(highContrastScheme)); - expect(appScheme.onPrimaryFixed.value, MaterialDynamicColors.onPrimaryFixed.getArgb(highContrastScheme)); - expect(appScheme.onPrimaryFixedVariant.value, MaterialDynamicColors.onPrimaryFixedVariant.getArgb(highContrastScheme)); - expect(appScheme.secondary.value, MaterialDynamicColors.secondary.getArgb(highContrastScheme)); - expect(appScheme.onSecondary.value, MaterialDynamicColors.onSecondary.getArgb(highContrastScheme)); - expect(appScheme.secondaryContainer.value, MaterialDynamicColors.secondaryContainer.getArgb(highContrastScheme)); - expect(appScheme.onSecondaryContainer.value, MaterialDynamicColors.onSecondaryContainer.getArgb(highContrastScheme)); - expect(appScheme.secondaryFixed.value, MaterialDynamicColors.secondaryFixed.getArgb(highContrastScheme)); - expect(appScheme.secondaryFixedDim.value, MaterialDynamicColors.secondaryFixedDim.getArgb(highContrastScheme)); - expect(appScheme.onSecondaryFixed.value, MaterialDynamicColors.onSecondaryFixed.getArgb(highContrastScheme)); - expect(appScheme.onSecondaryFixedVariant.value, MaterialDynamicColors.onSecondaryFixedVariant.getArgb(highContrastScheme)); - expect(appScheme.tertiary.value, MaterialDynamicColors.tertiary.getArgb(highContrastScheme)); - expect(appScheme.onTertiary.value, MaterialDynamicColors.onTertiary.getArgb(highContrastScheme)); - expect(appScheme.tertiaryContainer.value, MaterialDynamicColors.tertiaryContainer.getArgb(highContrastScheme)); - expect(appScheme.onTertiaryContainer.value, MaterialDynamicColors.onTertiaryContainer.getArgb(highContrastScheme)); - expect(appScheme.tertiaryFixed.value, MaterialDynamicColors.tertiaryFixed.getArgb(highContrastScheme)); - expect(appScheme.tertiaryFixedDim.value, MaterialDynamicColors.tertiaryFixedDim.getArgb(highContrastScheme)); - expect(appScheme.onTertiaryFixed.value, MaterialDynamicColors.onTertiaryFixed.getArgb(highContrastScheme)); - expect(appScheme.onTertiaryFixedVariant.value, MaterialDynamicColors.onTertiaryFixedVariant.getArgb(highContrastScheme)); - expect(appScheme.error.value, MaterialDynamicColors.error.getArgb(highContrastScheme)); - expect(appScheme.onError.value, MaterialDynamicColors.onError.getArgb(highContrastScheme)); - expect(appScheme.errorContainer.value, MaterialDynamicColors.errorContainer.getArgb(highContrastScheme)); - expect(appScheme.onErrorContainer.value, MaterialDynamicColors.onErrorContainer.getArgb(highContrastScheme)); - expect(appScheme.background.value, MaterialDynamicColors.background.getArgb(highContrastScheme)); - expect(appScheme.onBackground.value, MaterialDynamicColors.onBackground.getArgb(highContrastScheme)); - expect(appScheme.surface.value, MaterialDynamicColors.surface.getArgb(highContrastScheme)); - expect(appScheme.surfaceDim.value, MaterialDynamicColors.surfaceDim.getArgb(highContrastScheme)); - expect(appScheme.surfaceBright.value, MaterialDynamicColors.surfaceBright.getArgb(highContrastScheme)); - expect(appScheme.surfaceContainerLowest.value, MaterialDynamicColors.surfaceContainerLowest.getArgb(highContrastScheme)); - expect(appScheme.surfaceContainerLow.value, MaterialDynamicColors.surfaceContainerLow.getArgb(highContrastScheme)); - expect(appScheme.surfaceContainer.value, MaterialDynamicColors.surfaceContainer.getArgb(highContrastScheme)); - expect(appScheme.surfaceContainerHigh.value, MaterialDynamicColors.surfaceContainerHigh.getArgb(highContrastScheme)); - expect(appScheme.surfaceContainerHighest.value, MaterialDynamicColors.surfaceContainerHighest.getArgb(highContrastScheme)); - expect(appScheme.onSurface.value, MaterialDynamicColors.onSurface.getArgb(highContrastScheme)); - expect(appScheme.surfaceVariant.value, MaterialDynamicColors.surfaceVariant.getArgb(highContrastScheme)); - expect(appScheme.onSurfaceVariant.value, MaterialDynamicColors.onSurfaceVariant.getArgb(highContrastScheme)); - expect(appScheme.outline.value, MaterialDynamicColors.outline.getArgb(highContrastScheme)); - expect(appScheme.outlineVariant.value, MaterialDynamicColors.outlineVariant.getArgb(highContrastScheme)); - expect(appScheme.shadow.value, MaterialDynamicColors.shadow.getArgb(highContrastScheme)); - expect(appScheme.scrim.value, MaterialDynamicColors.scrim.getArgb(highContrastScheme)); - expect(appScheme.inverseSurface.value, MaterialDynamicColors.inverseSurface.getArgb(highContrastScheme)); - expect(appScheme.onInverseSurface.value, MaterialDynamicColors.inverseOnSurface.getArgb(highContrastScheme)); - expect(appScheme.inversePrimary.value, MaterialDynamicColors.inversePrimary.getArgb(highContrastScheme)); + expect(appScheme.primary.value, + MaterialDynamicColors.primary.getArgb(highContrastScheme)); + expect(appScheme.onPrimary.value, + MaterialDynamicColors.onPrimary.getArgb(highContrastScheme)); + expect(appScheme.primaryContainer.value, + MaterialDynamicColors.primaryContainer.getArgb(highContrastScheme)); + expect(appScheme.onPrimaryContainer.value, + MaterialDynamicColors.onPrimaryContainer.getArgb(highContrastScheme)); + expect(appScheme.primaryFixed.value, + MaterialDynamicColors.primaryFixed.getArgb(highContrastScheme)); + expect(appScheme.primaryFixedDim.value, + MaterialDynamicColors.primaryFixedDim.getArgb(highContrastScheme)); + expect(appScheme.onPrimaryFixed.value, + MaterialDynamicColors.onPrimaryFixed.getArgb(highContrastScheme)); + expect( + appScheme.onPrimaryFixedVariant.value, + MaterialDynamicColors.onPrimaryFixedVariant + .getArgb(highContrastScheme)); + expect(appScheme.secondary.value, + MaterialDynamicColors.secondary.getArgb(highContrastScheme)); + expect(appScheme.onSecondary.value, + MaterialDynamicColors.onSecondary.getArgb(highContrastScheme)); + expect(appScheme.secondaryContainer.value, + MaterialDynamicColors.secondaryContainer.getArgb(highContrastScheme)); + expect(appScheme.onSecondaryContainer.value, + MaterialDynamicColors.onSecondaryContainer.getArgb(highContrastScheme)); + expect(appScheme.secondaryFixed.value, + MaterialDynamicColors.secondaryFixed.getArgb(highContrastScheme)); + expect(appScheme.secondaryFixedDim.value, + MaterialDynamicColors.secondaryFixedDim.getArgb(highContrastScheme)); + expect(appScheme.onSecondaryFixed.value, + MaterialDynamicColors.onSecondaryFixed.getArgb(highContrastScheme)); + expect( + appScheme.onSecondaryFixedVariant.value, + MaterialDynamicColors.onSecondaryFixedVariant + .getArgb(highContrastScheme)); + expect(appScheme.tertiary.value, + MaterialDynamicColors.tertiary.getArgb(highContrastScheme)); + expect(appScheme.onTertiary.value, + MaterialDynamicColors.onTertiary.getArgb(highContrastScheme)); + expect(appScheme.tertiaryContainer.value, + MaterialDynamicColors.tertiaryContainer.getArgb(highContrastScheme)); + expect(appScheme.onTertiaryContainer.value, + MaterialDynamicColors.onTertiaryContainer.getArgb(highContrastScheme)); + expect(appScheme.tertiaryFixed.value, + MaterialDynamicColors.tertiaryFixed.getArgb(highContrastScheme)); + expect(appScheme.tertiaryFixedDim.value, + MaterialDynamicColors.tertiaryFixedDim.getArgb(highContrastScheme)); + expect(appScheme.onTertiaryFixed.value, + MaterialDynamicColors.onTertiaryFixed.getArgb(highContrastScheme)); + expect( + appScheme.onTertiaryFixedVariant.value, + MaterialDynamicColors.onTertiaryFixedVariant + .getArgb(highContrastScheme)); + expect(appScheme.error.value, + MaterialDynamicColors.error.getArgb(highContrastScheme)); + expect(appScheme.onError.value, + MaterialDynamicColors.onError.getArgb(highContrastScheme)); + expect(appScheme.errorContainer.value, + MaterialDynamicColors.errorContainer.getArgb(highContrastScheme)); + expect(appScheme.onErrorContainer.value, + MaterialDynamicColors.onErrorContainer.getArgb(highContrastScheme)); + expect(appScheme.background.value, + MaterialDynamicColors.background.getArgb(highContrastScheme)); + expect(appScheme.onBackground.value, + MaterialDynamicColors.onBackground.getArgb(highContrastScheme)); + expect(appScheme.surface.value, + MaterialDynamicColors.surface.getArgb(highContrastScheme)); + expect(appScheme.surfaceDim.value, + MaterialDynamicColors.surfaceDim.getArgb(highContrastScheme)); + expect(appScheme.surfaceBright.value, + MaterialDynamicColors.surfaceBright.getArgb(highContrastScheme)); + expect( + appScheme.surfaceContainerLowest.value, + MaterialDynamicColors.surfaceContainerLowest + .getArgb(highContrastScheme)); + expect(appScheme.surfaceContainerLow.value, + MaterialDynamicColors.surfaceContainerLow.getArgb(highContrastScheme)); + expect(appScheme.surfaceContainer.value, + MaterialDynamicColors.surfaceContainer.getArgb(highContrastScheme)); + expect(appScheme.surfaceContainerHigh.value, + MaterialDynamicColors.surfaceContainerHigh.getArgb(highContrastScheme)); + expect( + appScheme.surfaceContainerHighest.value, + MaterialDynamicColors.surfaceContainerHighest + .getArgb(highContrastScheme)); + expect(appScheme.onSurface.value, + MaterialDynamicColors.onSurface.getArgb(highContrastScheme)); + expect(appScheme.surfaceVariant.value, + MaterialDynamicColors.surfaceVariant.getArgb(highContrastScheme)); + expect(appScheme.onSurfaceVariant.value, + MaterialDynamicColors.onSurfaceVariant.getArgb(highContrastScheme)); + expect(appScheme.outline.value, + MaterialDynamicColors.outline.getArgb(highContrastScheme)); + expect(appScheme.outlineVariant.value, + MaterialDynamicColors.outlineVariant.getArgb(highContrastScheme)); + expect(appScheme.shadow.value, + MaterialDynamicColors.shadow.getArgb(highContrastScheme)); + expect(appScheme.scrim.value, + MaterialDynamicColors.scrim.getArgb(highContrastScheme)); + expect(appScheme.inverseSurface.value, + MaterialDynamicColors.inverseSurface.getArgb(highContrastScheme)); + expect(appScheme.onInverseSurface.value, + MaterialDynamicColors.inverseOnSurface.getArgb(highContrastScheme)); + expect(appScheme.inversePrimary.value, + MaterialDynamicColors.inversePrimary.getArgb(highContrastScheme)); }); } diff --git a/dev/a11y_assessments/test/navigation_drawer_test.dart b/dev/a11y_assessments/test/navigation_drawer_test.dart new file mode 100644 index 0000000000..267118e83a --- /dev/null +++ b/dev/a11y_assessments/test/navigation_drawer_test.dart @@ -0,0 +1,23 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/navigation_drawer.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('navigation drawer can run', (WidgetTester tester) async { + await pumpsUseCase(tester, NavigationDrawerUseCase()); + + final ScaffoldState state = tester.firstState(find.byType(Scaffold)); + state.openEndDrawer(); + + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); + + expect(find.byType(NavigationDrawer), findsExactly(1)); + }); +} diff --git a/dev/a11y_assessments/test/navigation_rail_test.dart b/dev/a11y_assessments/test/navigation_rail_test.dart new file mode 100644 index 0000000000..4dc98ea4cf --- /dev/null +++ b/dev/a11y_assessments/test/navigation_rail_test.dart @@ -0,0 +1,17 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/navigation_rail.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('navigation rail can run', (WidgetTester tester) async { + await pumpsUseCase(tester, NavigationRailUseCase()); + + expect(find.byType(NavigationRail), findsExactly(1)); + }); +} diff --git a/dev/a11y_assessments/test/radio_list_tile_test.dart b/dev/a11y_assessments/test/radio_list_tile_test.dart index 499bf3bd88..f8d0553235 100644 --- a/dev/a11y_assessments/test/radio_list_tile_test.dart +++ b/dev/a11y_assessments/test/radio_list_tile_test.dart @@ -8,7 +8,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'test_utils.dart'; void main() { - testWidgets('radio list tile use-case renders radio buttons', (WidgetTester tester) async { + testWidgets('radio list tile use-case renders radio buttons', + (WidgetTester tester) async { await pumpsUseCase(tester, RadioListTileUseCase()); expect(find.text('Lafayette'), findsOneWidget); expect(find.text('Jefferson'), findsOneWidget); diff --git a/dev/a11y_assessments/test/slider_test.dart b/dev/a11y_assessments/test/slider_test.dart index 8e08835436..7b7665dac6 100644 --- a/dev/a11y_assessments/test/slider_test.dart +++ b/dev/a11y_assessments/test/slider_test.dart @@ -16,12 +16,14 @@ void main() { await tester.tapAt(tester.getCenter(find.byType(Slider))); await tester.pumpAndSettle(); - final MainWidgetState state = tester.state(find.byType(MainWidget)); + final MainWidgetState state = + tester.state(find.byType(MainWidget)); expect(state.currentSliderValue, 60); }); testWidgets('slider semantics wrapper exists', (WidgetTester tester) async { await pumpsUseCase(tester, SliderUseCase()); - final Finder semanticsWidget = find.bySemanticsLabel('Accessibility Test Slider'); + final Finder semanticsWidget = + find.bySemanticsLabel('Accessibility Test Slider'); expect(semanticsWidget, findsOneWidget); }); } diff --git a/dev/a11y_assessments/test/snack_bar_test.dart b/dev/a11y_assessments/test/snack_bar_test.dart index 21a8a9cc59..1cce3e8260 100644 --- a/dev/a11y_assessments/test/snack_bar_test.dart +++ b/dev/a11y_assessments/test/snack_bar_test.dart @@ -9,7 +9,7 @@ import 'test_utils.dart'; void main() { testWidgets('snack bar can run', (WidgetTester tester) async { - await pumpsUseCase(tester, SnackBarUseCase()); + await pumpsUseCase(tester, SnackBarUseCase()); const String snackBarText = 'Awesome Snackbar!'; expect(find.text(snackBarText), findsNothing); await tester.tap(find.text('Show Snackbar')); diff --git a/dev/a11y_assessments/test/text_button_test.dart b/dev/a11y_assessments/test/text_button_test.dart index 46f0444595..07ec8d8323 100644 --- a/dev/a11y_assessments/test/text_button_test.dart +++ b/dev/a11y_assessments/test/text_button_test.dart @@ -14,7 +14,8 @@ void main() { expect(find.text('Action Disabled'), findsOneWidget); }); - testWidgets('text button increments correctly when clicked', (WidgetTester tester) async { + testWidgets('text button increments correctly when clicked', + (WidgetTester tester) async { await pumpsUseCase(tester, TextButtonUseCase()); expect(find.text('Action'), findsOneWidget); diff --git a/dev/a11y_assessments/test/text_field_password_test.dart b/dev/a11y_assessments/test/text_field_password_test.dart index 5ecd650d62..8fdcdbb045 100644 --- a/dev/a11y_assessments/test/text_field_password_test.dart +++ b/dev/a11y_assessments/test/text_field_password_test.dart @@ -31,7 +31,8 @@ void main() { } }); - testWidgets('text field passwords do not have hint text', (WidgetTester tester) async { + testWidgets('text field passwords do not have hint text', + (WidgetTester tester) async { await pumpsUseCase(tester, TextFieldPasswordUseCase()); expect(find.byType(TextField), findsExactly(2)); @@ -40,7 +41,6 @@ void main() { final Finder finder = find.byKey(const Key('enabled password')); final TextField textField = tester.widget(finder); expect(textField.decoration?.hintText, isNull); - } // Test the disabled password diff --git a/dev/a11y_assessments/test/text_field_test.dart b/dev/a11y_assessments/test/text_field_test.dart index 58439bb3aa..e1a1011ae4 100644 --- a/dev/a11y_assessments/test/text_field_test.dart +++ b/dev/a11y_assessments/test/text_field_test.dart @@ -31,7 +31,8 @@ void main() { } }); - testWidgets('font size increase does not ellipsize hint text', (WidgetTester tester) async { + testWidgets('font size increase does not ellipsize hint text', + (WidgetTester tester) async { await pumpsUseCase(tester, TextFieldUseCase()); await tester.pumpWidget(MaterialApp( home: MediaQuery.withClampedTextScaling( @@ -59,7 +60,8 @@ void main() { await pumpsUseCase(tester, TextFieldUseCase()); const String textFieldLabel = 'Input field with suffix @gmail.com'; - final Finder semanticsWidgets = find.bySemanticsLabel(RegExp(textFieldLabel)); + final Finder semanticsWidgets = + find.bySemanticsLabel(RegExp(textFieldLabel)); expect(semanticsWidgets, findsExactly(2)); }); }