diff --git a/android/gradle.properties b/android/gradle.properties index d1327d41..d697d418 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx4608m android.useAndroidX=true android.enableJetifier=true -android.enableR8=true +# android.enableR8=true enableProguardInReleaseBuilds = true diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index da88df3f..f1caa621 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -1,6 +1,10 @@ import 'dart:collection'; import 'dart:math'; +import 'package:app_tracking_transparency/app_tracking_transparency.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -8,22 +12,34 @@ import 'package:go_router/go_router.dart'; import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; +import 'package:hub/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart'; import 'package:hub/features/backend/api_requests/index.dart'; import 'package:hub/features/local/index.dart'; import 'package:hub/features/menu/index.dart'; import 'package:hub/features/module/data/index.dart'; import 'package:hub/features/module/domain/index.dart'; +import 'package:hub/features/notification/index.dart'; import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/index.dart' as ff; +import 'package:hub/flutter_flow/index.dart'; import 'package:hub/initialization.dart'; import 'package:hub/main.dart'; +import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart'; import 'package:integration_test/integration_test.dart'; import 'package:material_symbols_icons/symbols.dart'; +import 'package:patrol/patrol.dart'; +import 'package:flutter_web_plugins/url_strategy.dart'; import 'package:patrol_finders/patrol_finders.dart'; +// import 'package:patrol_finders/patrol_finders.dart'; +import 'app_test.dart'; import 'fuzzer/fuzzer.dart'; +export 'package:flutter_test/flutter_test.dart'; +export 'package:patrol/patrol.dart'; + part 'auth_test.dart'; +part 'common.dart'; part 'home_test.dart'; part 'locals_test.dart'; part 'menu_test.dart'; @@ -40,25 +56,26 @@ late PatrolTester $; void main() { //init integration test - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + // IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - setUp(() async {}); - tearDown(() async {}); + // setUp(() async {}); + // tearDown(() async {}); - WelcomeTest.signInToSignUp(); - WelcomeTest.signUpToSignIn(); + // WelcomeTest.signInToSignUp(); + // WelcomeTest.signUpToSignIn(); - AuthenticationTest.signIn(); - AuthenticationTest.signUp(); - AuthenticationTest.signOut(); + // AuthenticationTest.signIn(); + // AuthenticationTest.signUp(); + // AuthenticationTest.signOut(); + AuthenticationTest.recovery(); - ModularizationTest.switchLicense(); - ModularizationTest.containLicense(); + // ModularizationTest.switchLicense(); + // ModularizationTest.containLicense(); - MenuTest.navToEntries(); - MenuTest.containEntries(); - MenuTest.labels2AppbarConsistency(); + // MenuTest.navToEntries(); + // MenuTest.containEntries(); + // MenuTest.labels2AppbarConsistency(); - LocalsTest.setLocal(); - LocalsTest.unlinkLocal(); + // LocalsTest.setLocal(); + // LocalsTest.unlinkLocal(); } diff --git a/integration_test/auth_test.dart b/integration_test/auth_test.dart index 3528acc1..4045cfc3 100644 --- a/integration_test/auth_test.dart +++ b/integration_test/auth_test.dart @@ -182,9 +182,7 @@ class AuthenticationTest { await $.waitUntilVisible($(MenuStaggeredView)); - await $(Icons.menu_rounded) // - .waitUntilVisible() - .tap(); + await $(Icons.menu_rounded).waitUntilVisible().tap(); await $.waitUntilVisible($(MenuListView)); @@ -197,7 +195,28 @@ class AuthenticationTest { ); } - static Future recovery() async {} + static void recovery() async { + patrol('Open url in the app', ($) async { + await _loggedWithMultiLocalsAccount(); + await $.pumpWidget(const App()); + + await $.waitUntilVisible($(MenuStaggeredView)); + + // await $.native.pressHome(); + // final String browserId = 'com.android.chrome'; + // await $.native.openApp(appId: browserId); + await $.native.openUrl(// + 'https://freaccess.com.br/freaccess/alterarSenha.php?email=freaccesshub@gmail.com&token=67939240e12c31.10412525'); + + await $.pumpAndSettle(); + Future.delayed(Duration(seconds: 3)); + await $.pump(Duration(seconds: 3)); + await $.pumpAndSettle(); + final PatrolFinder forgotPassword = + await $(#ForgotPasswordScreen).waitUntilVisible(); + expect(forgotPassword, findsOneWidget); + }); + } } Future _auth( diff --git a/integration_test/common.dart b/integration_test/common.dart new file mode 100644 index 00000000..958a328e --- /dev/null +++ b/integration_test/common.dart @@ -0,0 +1,31 @@ +part of 'app_test.dart'; + +final _patrolTesterConfig = PatrolTesterConfig(printLogs: true); +final _nativeAutomatorConfig = NativeAutomatorConfig( + findTimeout: Duration(seconds: 20), // 10 seconds is too short for some CIs +); + +// Future createApp(PatrolTester $) async { +// await app_main.main(); +// await $.pumpAndSettle(); +// } + +void patrol( + String description, + Future Function(PatrolIntegrationTester) callback, { + bool? skip, + List tags = const [], + NativeAutomatorConfig? nativeAutomatorConfig, + LiveTestWidgetsFlutterBindingFramePolicy framePolicy = + LiveTestWidgetsFlutterBindingFramePolicy.fadePointers, +}) { + patrolTest( + description, + config: _patrolTesterConfig, + nativeAutomatorConfig: nativeAutomatorConfig ?? _nativeAutomatorConfig, + framePolicy: framePolicy, + skip: skip, + callback, + tags: tags, + ); +} diff --git a/integration_test/test_bundle.dart b/integration_test/test_bundle.dart index 9045d298..55d38e30 100644 --- a/integration_test/test_bundle.dart +++ b/integration_test/test_bundle.dart @@ -9,7 +9,7 @@ import 'package:patrol/src/native/contracts/contracts.dart'; import 'package:test_api/src/backend/invoker.dart'; // START: GENERATED TEST IMPORTS -import 'app_test.dart' as app_test; +import 'app_test.dart' as __app_test; // END: GENERATED TEST IMPORTS Future main() async { @@ -31,7 +31,7 @@ Future main() async { // When running on iOS, the native side of Patrol (specifically: the // PATROL_INTEGRATION_TEST_IOS_RUNNER macro) makes an initial run to gather // the tests that it will later run (same as the Android). During that initial - // run, it makes an RPC call to PatrolAppSevice and asks it for Dart tests. + // run, it makes an RPC call to PatrolAppService and asks it for Dart tests. // // Once the native runner has the list of Dart tests, it dynamically creates // native test cases from them. On Android, this is done using the @@ -70,7 +70,7 @@ Future main() async { }); // START: GENERATED TEST GROUPS - group('app_test', app_test.main); + group('.app_test', __app_test.main); // END: GENERATED TEST GROUPS final dartTestGroup = await testExplorationCompleter.future; diff --git a/integration_test/utils_test.dart b/integration_test/utils_test.dart index 144aa4ad..17c49545 100644 --- a/integration_test/utils_test.dart +++ b/integration_test/utils_test.dart @@ -2,7 +2,7 @@ part of 'app_test.dart'; Future _loggedWithMultiLocalsAccount( [bool forceLinkedLocal = true]) async { - await initializeApp(); + await _init(); await StorageHelper() // .set(SecureStorageKey.isLogged.value, 'true'); await StorageHelper() // @@ -31,7 +31,7 @@ Future _loggedWithMultiLocalsAccount( Future _loggedWithSomeoneLocalAccount( [bool forceLinkedLocal = true]) async { - await initializeApp(); + await _init(); await StorageHelper() // .set(SecureStorageKey.isLogged.value, 'true'); await StorageHelper() // @@ -59,7 +59,7 @@ Future _loggedWithSomeoneLocalAccount( } Future _unlogged() async { - await initializeApp(); + await _init(); await StorageHelper() // .set(SecureStorageKey.isLogged.value, 'false'); await StorageHelper() // @@ -78,6 +78,18 @@ Future _unlogged() async { .set(LocalsStorageKey.isNewVersion.key, true); } +Future _init() async { + WidgetsFlutterBinding.ensureInitialized(); + await _initializeTracking(); + await _initializeStorage(); + await _initializeFirebase(); + await _initializeNotificationService(); + _initializeUrlStrategy(); + _initializeSystemSettings(); + await _initializeFlutterFlow(); + await _initializeNav(); +} + Future _navigateToSignIn(PatrolTester $) async { final signInButton = $(#toggleSignInPage).waitUntilVisible(); await signInButton.tap(); @@ -91,3 +103,61 @@ Future _navigateToSignUp(PatrolTester $) async { Future _navigateBackUsingSystemGesture() async => IntegrationTestWidgetsFlutterBinding.instance.keyboard .isLogicalKeyPressed(LogicalKeyboardKey.escape); + +Future _initializeTracking() async { + print('Requesting tracking authorization...'); + await AppTrackingTransparency.requestTrackingAuthorization(); + print('Tracking authorization requested'); +} + +Future _initializeFirebase() async { + print('Initializing Firebase...'); + await Firebase.initializeApp(); + print('Firebase initialized'); +} + +Future _initializeNotificationService() async { + print('Initializing Notification Service...'); + await NotificationService.initialize(false); + + print('Notification Service initialized'); +} + +void _initializeUrlStrategy() { + print('Initializing URL Strategy...'); + setUrlStrategy(PathUrlStrategy()); + print('URL Strategy initialized'); +} + +void _initializeSystemSettings() { + print('Initializing System Settings...'); + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + if (kDebugMode) { + print('Debug mode'); + } else { + final crashlyticsInstance = FirebaseCrashlytics.instance; + print('Release mode'); + if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { + FlutterError.onError = crashlyticsInstance.recordFlutterError; + print('Crashlytics enabled'); + } + } +} + +Future _initializeFlutterFlow() async { + print('Initializing FlutterFlow...'); + await FlutterFlowTheme.initialize(); + await FFLocalizations.initialize(); + print('FlutterFlow initialized'); +} + +Future _initializeNav() async { + print('Initializing Nav...'); + GoRouter.optionURLReflectsImperativeAPIs = true; + usePathUrlStrategy(); + print('Nav initialized'); +} + +Future _initializeStorage() async { + await StorageHelper().init(); +} diff --git a/integration_test/welcome_test.dart b/integration_test/welcome_test.dart index c384d771..e3dc0316 100644 --- a/integration_test/welcome_test.dart +++ b/integration_test/welcome_test.dart @@ -9,6 +9,7 @@ class WelcomeTest { $.tester.printToConsole('Welcome Test - Sign-In to Sign-Up'); await _unlogged(); await $.pumpWidgetAndSettle(const App()); + await _navigateToSignIn($); await _navigateToSignUp($); }, diff --git a/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart b/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart index d9797e17..12bdc25e 100644 --- a/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart +++ b/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart @@ -58,6 +58,7 @@ class _ForgotPasswordTemplateComponentWidgetState LimitedFontSizeUtil.getHeaderFontSize(context); return Align( + key: ValueKey('ForgotPasswordTemplateComponentWidget'), alignment: const AlignmentDirectional(0.0, 1.0), child: SingleChildScrollView( child: Container( diff --git a/lib/features/notification/deep_link_service.dart b/lib/features/notification/deep_link_service.dart index f7aa1ac0..4f6ba58d 100644 --- a/lib/features/notification/deep_link_service.dart +++ b/lib/features/notification/deep_link_service.dart @@ -59,7 +59,11 @@ class DeepLinkService { context: navigatorKey.currentContext!, builder: (context) => Padding( padding: MediaQuery.viewInsetsOf(context), - child: ForgotPasswordScreen(email: email, token: token), + child: ForgotPasswordScreen( + key: ValueKey('ForgotPasswordScreen'), + email: email, + token: token, + ), ), isScrollControlled: true, backgroundColor: FlutterFlowTheme.of(navigatorKey.currentContext!) diff --git a/lib/features/notification/notification_service.dart b/lib/features/notification/notification_service.dart index 8e1662d6..8c7b423c 100644 --- a/lib/features/notification/notification_service.dart +++ b/lib/features/notification/notification_service.dart @@ -260,7 +260,7 @@ Future onMessageReceived( } class NotificationService { - static Future initialize() async { + static Future initialize([bool forceRequest = true]) async { await AwesomeNotifications().initialize( 'resource://drawable/notification_icon', [ @@ -296,7 +296,8 @@ class NotificationService { if (isAllowed == false) { await StorageHelper() .set(LocalsStorageKey.requestOSNotification.key, true); - await AwesomeNotifications().requestPermissionToSendNotifications(); + if (forceRequest == true) + await AwesomeNotifications().requestPermissionToSendNotifications(); } } return; diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index 22782a4d..600a43ad 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -152,7 +152,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { params.getParam('token', ParamType.String); return ForgotPasswordScreen( - key: UniqueKey(), + key: ValueKey('ForgotPasswordScreen'), email: email, token: token, ); diff --git a/lib/main.dart b/lib/main.dart index c9941df7..03c6b70d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -181,7 +181,8 @@ class _AppState extends State { ); _setupFirebaseMessaging(); - if (TestUtil.isInTest) DeepLinkService().ensureInitialization(); + // if (TestUtil.isInTest) // + DeepLinkService().ensureInitialization(); } @override diff --git a/lib/pages/forgot_password_page/forgot_password_screen.dart b/lib/pages/forgot_password_page/forgot_password_screen.dart index bf737647..99d0914d 100644 --- a/lib/pages/forgot_password_page/forgot_password_screen.dart +++ b/lib/pages/forgot_password_page/forgot_password_screen.dart @@ -116,6 +116,7 @@ class _ForgotPasswordScreenState extends State }, ), title: Text( + key: ValueKey('ForgotPasswordText'), FFLocalizations.of(context).getVariableText( ptText: 'Recuperar Senha', enText: 'Recover Password', diff --git a/pubspec.lock b/pubspec.lock index 056ad392..1494098d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -146,50 +146,50 @@ packages: dependency: transitive description: name: build - sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" build_config: dependency: transitive description: name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" build_daemon: dependency: transitive description: name: build_daemon - sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + sha256: "294a2edaf4814a378725bfe6358210196f5ea37af89ecd81bfa32960113d4948" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.3" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + sha256: "99d3980049739a985cf9b21f30881f46db3ebc62c5b8d5e60e27440876b1ba1e" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.3" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" + sha256: "74691599a5bc750dc96a6b4bfd48f7d9d66453eab04c7f4063134800d6a5c573" url: "https://pub.dev" source: hosted - version: "2.4.13" + version: "2.4.14" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 + sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021" url: "https://pub.dev" source: hosted - version: "7.3.2" + version: "8.0.0" built_collection: dependency: transitive description: @@ -824,18 +824,18 @@ packages: dependency: transitive description: name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" go_router: dependency: "direct main" description: name: go_router - sha256: "7c2d40b59890a929824f30d442e810116caf5088482629c894b9e4478c67472d" + sha256: daf3ff5570f55396b2d2c9bf8136d7db3a8acf208ac0cef92a3ae2beb9a81550 url: "https://pub.dev" source: hosted - version: "14.6.3" + version: "14.7.1" google_fonts: dependency: "direct main" description: @@ -896,10 +896,10 @@ packages: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" image: dependency: "direct dev" description: @@ -952,10 +952,10 @@ packages: dependency: transitive description: name: image_picker_macos - sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" + sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1" url: "https://pub.dev" source: hosted - version: "0.2.1+1" + version: "0.2.1+2" image_picker_platform_interface: dependency: "direct main" description: @@ -1061,10 +1061,10 @@ packages: dependency: "direct dev" description: name: lints - sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.1.1" local_auth: dependency: "direct main" description: @@ -1181,10 +1181,10 @@ packages: dependency: "direct dev" description: name: mockito - sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" + sha256: f99d8d072e249f719a5531735d146d8cf04c580d93920b04de75bef6dfb2daf6 url: "https://pub.dev" source: hosted - version: "5.4.4" + version: "5.4.5" nested: dependency: transitive description: @@ -1461,10 +1461,10 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0" + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.5.0" qr: dependency: transitive description: @@ -1533,10 +1533,10 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: a752ce92ea7540fc35a0d19722816e04d0e72828a4200e83a98cf1a1eb524c9a + sha256: c59819dacc6669a1165d54d2735a9543f136f9b3cec94ca65cea6ab8dffc422e url: "https://pub.dev" source: hosted - version: "2.3.5" + version: "2.4.0" shared_preferences_android: dependency: "direct main" description: @@ -1589,10 +1589,10 @@ packages: dependency: transitive description: name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.2" shelf_packages_handler: dependency: transitive description: @@ -1874,10 +1874,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" + sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.4.0" url_launcher_windows: dependency: transitive description: @@ -1962,10 +1962,10 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" webdriver: dependency: transitive description: @@ -2055,5 +2055,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.5.0 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.6.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/scripts/test.ps1 b/scripts/test.ps1 new file mode 100644 index 00000000..bb742505 --- /dev/null +++ b/scripts/test.ps1 @@ -0,0 +1,3 @@ +flutter clean +flutter pub get +patrol test --target integration_test/app_test.dart --verbose \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100644 index 00000000..3ab1e543 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,3 @@ +flutter clean +flutter pub get +patrol test --target integration_test/app_test.dart \ No newline at end of file