From 51dba844338832751cdf2843923385c04d3fec5f Mon Sep 17 00:00:00 2001 From: Amanda Shafack Date: Mon, 27 Mar 2023 16:19:14 +0100 Subject: [PATCH 1/4] feat: write integration tests for the onboarding flow --- .../onboarding/view/onboarding_screens.dart | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 integration_test/onboarding/view/onboarding_screens.dart diff --git a/integration_test/onboarding/view/onboarding_screens.dart b/integration_test/onboarding/view/onboarding_screens.dart new file mode 100644 index 0000000..f6f0c19 --- /dev/null +++ b/integration_test/onboarding/view/onboarding_screens.dart @@ -0,0 +1,117 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:fpb/assets/fpb_svg.dart'; +import 'package:fpb/authentication_with_google/application/google_auth_bloc/google_sign_in_bloc.dart'; +import 'package:fpb/injection.dart'; +import 'package:fpb/l10n/l10n.dart'; +import 'package:fpb/onboarding/onboarding.dart'; + +import '../../../test/helpers/helpers.dart'; + +void onboardingFlowTest() { + final AppLocalizations l10n = getIt(); + + group('onboarding flow', () { + testWidgets('displays the onboarding flow', (tester) async { + await tester.pumpApp(OnboardingScreen(),); + await tester.pumpAndSettle(); + + /// TODO: write tests for the bubble animation when it's implemented + + /// Onboarding Screen One + expect(find.image(AssetImage(SvgNames.sendIllustration)), findsOneWidget); + expect(find.text(l10n.onboardingSendTitle), findsOneWidget); + expect(find.text(l10n.onboardingSendDescription), findsOneWidget); + + final Finder skipButtonLabel = find.byKey(ValueKey('skip_button')); + final Finder nextButtonLabel = find.byKey(ValueKey('next_button')); + + expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); + expect(find.text(l10n.onboardingNextLabel), findsOneWidget); + expect(find.byKey(ValueKey('next_icon')), findsOneWidget); + + await tester.tap(skipButtonLabel, warnIfMissed: true); + await tester.tap(nextButtonLabel, warnIfMissed: true); + + await waitForNextScreen(tester); + + /// Onboarding Screen Two + expect(find.image(AssetImage(SvgNames.saveIllustration,)), findsOneWidget); + expect(find.text(l10n.onboardingSaveTitle), findsOneWidget); + expect(find.text(l10n.onboardingSaveDescription), findsOneWidget); + expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); + expect(find.text(l10n.onboardingNextLabel), findsOneWidget); + await tester.tap(skipButtonLabel, warnIfMissed: true); + await tester.tap(nextButtonLabel, warnIfMissed: true); + + await waitForNextScreen(tester); + + /// Onboarding Screen Three + expect(find.image(AssetImage(SvgNames.transIllustration)), findsOneWidget); + expect(find.text(l10n.onboardingTransactionTitle), findsOneWidget); + expect(find.text(l10n.onboardingTransactionDescription), findsOneWidget); + final Finder getStartedButtonLabel = find.byKey(ValueKey('get_started_button')); + await tester.tap(getStartedButtonLabel, warnIfMissed: true); + + // Trigger a frame. + await tester.pumpAndSettle(); + + /// Display the Login screen at the end of the onboarding flow + expect(find.byType(SignIn), findsOneWidget); + + }); + testWidgets('showcase the ', (tester) async { + await tester.pumpApp(OnboardingScreen(),); + await tester.pumpAndSettle(); + + /// TODO: write tests for the bubble animation when it's implemented + + /// Onboarding Screen One + expect(find.image(AssetImage(SvgNames.sendIllustration)), findsOneWidget); + expect(find.text(l10n.onboardingSendTitle), findsOneWidget); + expect(find.text(l10n.onboardingSendDescription), findsOneWidget); + + final Finder skipButtonLabel = find.byKey(ValueKey('skip_button')); + final Finder nextButtonLabel = find.byKey(ValueKey('next_button')); + + expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); + expect(find.text(l10n.onboardingNextLabel), findsOneWidget); + expect(find.byKey(ValueKey('next_icon')), findsOneWidget); + + await tester.tap(skipButtonLabel, warnIfMissed: true); + await tester.tap(nextButtonLabel, warnIfMissed: true); + + await waitForNextScreen(tester); + + /// Onboarding Screen Two + expect(find.image(AssetImage(SvgNames.saveIllustration,)), findsOneWidget); + expect(find.text(l10n.onboardingSaveTitle), findsOneWidget); + expect(find.text(l10n.onboardingSaveDescription), findsOneWidget); + expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); + expect(find.text(l10n.onboardingNextLabel), findsOneWidget); + await tester.tap(skipButtonLabel, warnIfMissed: true); + await tester.tap(nextButtonLabel, warnIfMissed: true); + + await waitForNextScreen(tester); + + /// Onboarding Screen Three + expect(find.image(AssetImage(SvgNames.transIllustration)), findsOneWidget); + expect(find.text(l10n.onboardingTransactionTitle), findsOneWidget); + expect(find.text(l10n.onboardingTransactionDescription), findsOneWidget); + final Finder getStartedButtonLabel = find.byKey(ValueKey('get_started_button')); + await tester.tap(getStartedButtonLabel, warnIfMissed: true); + + // Trigger a frame. + await tester.pumpAndSettle(); + + /// Display the Login screen at the end of the onboarding flow + expect(find.byType(SignIn), findsOneWidget); + + }); + }); +} + +Future waitForNextScreen(WidgetTester tester) async { + await tester.pumpAndSettle(); + await tester.pump(Duration(seconds: 1)); +} From 6d106a79d8cb6b000b963e45ad60d02e0bf2a42b Mon Sep 17 00:00:00 2001 From: Amanda Shafack Date: Mon, 27 Mar 2023 16:20:38 +0100 Subject: [PATCH 2/4] chore: add key properties to widgets on the onboarding flow --- lib/onboarding/view/widgets/actions.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/onboarding/view/widgets/actions.dart b/lib/onboarding/view/widgets/actions.dart index 35079c5..ce97b1a 100644 --- a/lib/onboarding/view/widgets/actions.dart +++ b/lib/onboarding/view/widgets/actions.dart @@ -29,6 +29,7 @@ class Actions extends StatelessWidget { if (!isLastPage) const SizedBox(), if (!isLastPage) TextButton( + key: Key("skip_button"), onPressed: onSkipPressed, child: Text( l10n.onboardingSkipLabel, @@ -36,6 +37,7 @@ class Actions extends StatelessWidget { ), ), FpbButton( + key: !isLastPage ? Key("next_button") : Key('get_started_button'), label: !isLastPage ? l10n.onboardingNextLabel : l10n.onboardingGetStartedLabel, @@ -44,7 +46,8 @@ class Actions extends StatelessWidget { height: cts.maxHeight * 0.07, trailing: !isLastPage ? Icon( - FpbIcons.arrow_right, + key: Key("next_icon"), + FpbIcons.arrow_right, size: cts.maxHeight * 0.02, color: colors.background, ) From 52544f2e163162f8739f33e47515978d1ca8391b Mon Sep 17 00:00:00 2001 From: Amanda Shafack Date: Mon, 27 Mar 2023 16:21:11 +0100 Subject: [PATCH 3/4] chore: attach the onbaording flow integration test to the main function --- integration_test/app_test.dart | 2 ++ integration_test/onboarding/view/onboarding_screens.dart | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index f303140..fd28f99 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -2,11 +2,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'bottom_nav_bar_test.dart'; +import 'onboarding/view/onboarding_screens.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('Development App', () { bottomNavBarTest(); + onboardingFlowTest(); }); } diff --git a/integration_test/onboarding/view/onboarding_screens.dart b/integration_test/onboarding/view/onboarding_screens.dart index f6f0c19..505a990 100644 --- a/integration_test/onboarding/view/onboarding_screens.dart +++ b/integration_test/onboarding/view/onboarding_screens.dart @@ -6,6 +6,8 @@ import 'package:fpb/injection.dart'; import 'package:fpb/l10n/l10n.dart'; import 'package:fpb/onboarding/onboarding.dart'; +import '../../../integration_test/app_test.dart'; + import '../../../test/helpers/helpers.dart'; void onboardingFlowTest() { @@ -13,6 +15,9 @@ void onboardingFlowTest() { group('onboarding flow', () { testWidgets('displays the onboarding flow', (tester) async { + + main(); + await tester.pumpApp(OnboardingScreen(),); await tester.pumpAndSettle(); From d8687e981f9a29a74ce526b87226ca639fa832c4 Mon Sep 17 00:00:00 2001 From: Amanda Shafack Date: Tue, 28 Mar 2023 14:52:48 +0100 Subject: [PATCH 4/4] chore: fix access to applocalization - Enable access to an instance of AppLocalization from the test file - Rename the onboarding screen integration test file --- integration_test/app_test.dart | 3 +- .../onboarding/view/onboarding_flow_test.dart | 81 ++++++++++++ .../onboarding/view/onboarding_screens.dart | 122 ------------------ 3 files changed, 83 insertions(+), 123 deletions(-) create mode 100644 integration_test/onboarding/view/onboarding_flow_test.dart delete mode 100644 integration_test/onboarding/view/onboarding_screens.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index fd28f99..870d5bd 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -2,7 +2,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'bottom_nav_bar_test.dart'; -import 'onboarding/view/onboarding_screens.dart'; +import 'onboarding/view/onboarding_flow_test.dart'; + void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/integration_test/onboarding/view/onboarding_flow_test.dart b/integration_test/onboarding/view/onboarding_flow_test.dart new file mode 100644 index 0000000..b77be07 --- /dev/null +++ b/integration_test/onboarding/view/onboarding_flow_test.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:fpb/assets/fpb_svg.dart'; +import 'package:fpb/authentication_with_google/application/google_auth_bloc/google_sign_in_bloc.dart'; +import 'package:fpb/l10n/l10n.dart'; +import 'package:fpb/onboarding/onboarding.dart'; + +import '../../../test/helpers/helpers.dart'; + + +void onboardingFlowTest() { + + late AppLocalizations l10n; + + group('onboarding flow', () { + testWidgets('displays the onboarding flow', (tester) async { + await tester.pumpApp(Builder( + builder: (BuildContext context) { + l10n = context.l10n; + return OnboardingScreen(); + } + )); + + await tester.pumpAndSettle(); + + /// TODO: write tests for the bubble animation when it's implemented + + /// Onboarding Screen One + expect(find.image(AssetImage(SvgNames.sendIllustration)), findsOneWidget); + expect(find.text(l10n.onboardingSendTitle), findsOneWidget); + expect(find.text(l10n.onboardingSendDescription), findsOneWidget); + + final Finder skipButtonLabel = find.byKey(ValueKey('skip_button')); + final Finder nextButtonLabel = find.byKey(ValueKey('next_button')); + + expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); + expect(find.text(l10n.onboardingNextLabel), findsOneWidget); + expect(find.byKey(ValueKey('next_icon')), findsOneWidget); + + await tester.tap(skipButtonLabel, warnIfMissed: true); + await tester.tap(nextButtonLabel, warnIfMissed: true); + + await waitForNextScreen(tester); + + /// Onboarding Screen Two + expect( + find.image(AssetImage( + SvgNames.saveIllustration, + )), + findsOneWidget); + expect(find.text(l10n.onboardingSaveTitle), findsOneWidget); + expect(find.text(l10n.onboardingSaveDescription), findsOneWidget); + expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); + expect(find.text(l10n.onboardingNextLabel), findsOneWidget); + await tester.tap(skipButtonLabel, warnIfMissed: true); + await tester.tap(nextButtonLabel, warnIfMissed: true); + + await waitForNextScreen(tester); + + /// Onboarding Screen Three + expect( + find.image(AssetImage(SvgNames.transIllustration)), findsOneWidget); + expect(find.text(l10n.onboardingTransactionTitle), findsOneWidget); + expect(find.text(l10n.onboardingTransactionDescription), findsOneWidget); + final Finder getStartedButtonLabel = + find.byKey(ValueKey('get_started_button')); + await tester.tap(getStartedButtonLabel, warnIfMissed: true); + + // Trigger a frame. + await tester.pumpAndSettle(); + + /// Display the Login screen at the end of the onboarding flow + expect(find.byType(SignIn), findsOneWidget); + }); + }); +} + +Future waitForNextScreen(WidgetTester tester) async { + await tester.pumpAndSettle(); + await tester.pump(Duration(seconds: 1)); +} diff --git a/integration_test/onboarding/view/onboarding_screens.dart b/integration_test/onboarding/view/onboarding_screens.dart deleted file mode 100644 index 505a990..0000000 --- a/integration_test/onboarding/view/onboarding_screens.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:fpb/assets/fpb_svg.dart'; -import 'package:fpb/authentication_with_google/application/google_auth_bloc/google_sign_in_bloc.dart'; -import 'package:fpb/injection.dart'; -import 'package:fpb/l10n/l10n.dart'; -import 'package:fpb/onboarding/onboarding.dart'; - -import '../../../integration_test/app_test.dart'; - -import '../../../test/helpers/helpers.dart'; - -void onboardingFlowTest() { - final AppLocalizations l10n = getIt(); - - group('onboarding flow', () { - testWidgets('displays the onboarding flow', (tester) async { - - main(); - - await tester.pumpApp(OnboardingScreen(),); - await tester.pumpAndSettle(); - - /// TODO: write tests for the bubble animation when it's implemented - - /// Onboarding Screen One - expect(find.image(AssetImage(SvgNames.sendIllustration)), findsOneWidget); - expect(find.text(l10n.onboardingSendTitle), findsOneWidget); - expect(find.text(l10n.onboardingSendDescription), findsOneWidget); - - final Finder skipButtonLabel = find.byKey(ValueKey('skip_button')); - final Finder nextButtonLabel = find.byKey(ValueKey('next_button')); - - expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); - expect(find.text(l10n.onboardingNextLabel), findsOneWidget); - expect(find.byKey(ValueKey('next_icon')), findsOneWidget); - - await tester.tap(skipButtonLabel, warnIfMissed: true); - await tester.tap(nextButtonLabel, warnIfMissed: true); - - await waitForNextScreen(tester); - - /// Onboarding Screen Two - expect(find.image(AssetImage(SvgNames.saveIllustration,)), findsOneWidget); - expect(find.text(l10n.onboardingSaveTitle), findsOneWidget); - expect(find.text(l10n.onboardingSaveDescription), findsOneWidget); - expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); - expect(find.text(l10n.onboardingNextLabel), findsOneWidget); - await tester.tap(skipButtonLabel, warnIfMissed: true); - await tester.tap(nextButtonLabel, warnIfMissed: true); - - await waitForNextScreen(tester); - - /// Onboarding Screen Three - expect(find.image(AssetImage(SvgNames.transIllustration)), findsOneWidget); - expect(find.text(l10n.onboardingTransactionTitle), findsOneWidget); - expect(find.text(l10n.onboardingTransactionDescription), findsOneWidget); - final Finder getStartedButtonLabel = find.byKey(ValueKey('get_started_button')); - await tester.tap(getStartedButtonLabel, warnIfMissed: true); - - // Trigger a frame. - await tester.pumpAndSettle(); - - /// Display the Login screen at the end of the onboarding flow - expect(find.byType(SignIn), findsOneWidget); - - }); - testWidgets('showcase the ', (tester) async { - await tester.pumpApp(OnboardingScreen(),); - await tester.pumpAndSettle(); - - /// TODO: write tests for the bubble animation when it's implemented - - /// Onboarding Screen One - expect(find.image(AssetImage(SvgNames.sendIllustration)), findsOneWidget); - expect(find.text(l10n.onboardingSendTitle), findsOneWidget); - expect(find.text(l10n.onboardingSendDescription), findsOneWidget); - - final Finder skipButtonLabel = find.byKey(ValueKey('skip_button')); - final Finder nextButtonLabel = find.byKey(ValueKey('next_button')); - - expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); - expect(find.text(l10n.onboardingNextLabel), findsOneWidget); - expect(find.byKey(ValueKey('next_icon')), findsOneWidget); - - await tester.tap(skipButtonLabel, warnIfMissed: true); - await tester.tap(nextButtonLabel, warnIfMissed: true); - - await waitForNextScreen(tester); - - /// Onboarding Screen Two - expect(find.image(AssetImage(SvgNames.saveIllustration,)), findsOneWidget); - expect(find.text(l10n.onboardingSaveTitle), findsOneWidget); - expect(find.text(l10n.onboardingSaveDescription), findsOneWidget); - expect(find.text(l10n.onboardingSkipLabel), findsOneWidget); - expect(find.text(l10n.onboardingNextLabel), findsOneWidget); - await tester.tap(skipButtonLabel, warnIfMissed: true); - await tester.tap(nextButtonLabel, warnIfMissed: true); - - await waitForNextScreen(tester); - - /// Onboarding Screen Three - expect(find.image(AssetImage(SvgNames.transIllustration)), findsOneWidget); - expect(find.text(l10n.onboardingTransactionTitle), findsOneWidget); - expect(find.text(l10n.onboardingTransactionDescription), findsOneWidget); - final Finder getStartedButtonLabel = find.byKey(ValueKey('get_started_button')); - await tester.tap(getStartedButtonLabel, warnIfMissed: true); - - // Trigger a frame. - await tester.pumpAndSettle(); - - /// Display the Login screen at the end of the onboarding flow - expect(find.byType(SignIn), findsOneWidget); - - }); - }); -} - -Future waitForNextScreen(WidgetTester tester) async { - await tester.pumpAndSettle(); - await tester.pump(Duration(seconds: 1)); -}