From e3dfadce34513a308f2a19422e39e8e41ea5f06d Mon Sep 17 00:00:00 2001 From: Dat Dang Date: Fri, 17 Apr 2026 20:50:22 +0700 Subject: [PATCH] Upgrade Patrol to 4.5.0 (#4446) --- .../html_viewer/html_content_viewer_widget.dart | 1 - integration_test/base/core_robot.dart | 2 ++ integration_test/base/test_base.dart | 4 ++-- integration_test/mixin/scenario_utils_mixin.dart | 12 ++++++++++++ integration_test/robots/composer_robot.dart | 4 ++-- integration_test/robots/login_robot.dart | 7 +++---- integration_test/robots/mailbox_menu_robot.dart | 6 +++--- integration_test/scenarios/app_grid_scenario.dart | 11 ++++++----- .../scenarios/download_all_attachments_scenario.dart | 2 +- .../email_detailed/export_attachment_scenario.dart | 2 +- .../scenarios/login_with_basic_auth_scenario.dart | 2 +- ...end_email_with_read_receipt_enabled_scenario.dart | 2 +- pubspec.lock | 12 ++++++------ pubspec.yaml | 7 ++++--- scripts/patrol-integration-test-with-docker.sh | 2 +- 15 files changed, 45 insertions(+), 31 deletions(-) diff --git a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart index 9e682ccb5..bc185e4f7 100644 --- a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart +++ b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart @@ -85,7 +85,6 @@ class HtmlContentViewState extends State with AutomaticKeepAl String? _htmlData; - @visibleForTesting InAppWebViewController get webViewController => _webViewController; @override diff --git a/integration_test/base/core_robot.dart b/integration_test/base/core_robot.dart index 7d586037b..3933361a6 100644 --- a/integration_test/base/core_robot.dart +++ b/integration_test/base/core_robot.dart @@ -6,4 +6,6 @@ abstract class CoreRobot { CoreRobot(this.$); dynamic ignoreException() => $.tester.takeException(); + + MobileAutomator get native => $.platformAutomator.mobile; } \ No newline at end of file diff --git a/integration_test/base/test_base.dart b/integration_test/base/test_base.dart index 924ef0b6a..b41341718 100644 --- a/integration_test/base/test_base.dart +++ b/integration_test/base/test_base.dart @@ -28,8 +28,8 @@ class TestBase { visibleTimeout: Duration(seconds: 30), printLogs: true, ), - nativeAutomatorConfig: const NativeAutomatorConfig( - findTimeout: Duration(seconds: 10), + platformAutomatorConfig: PlatformAutomatorConfig.fromOptions( + findTimeout: const Duration(seconds: 10), ), framePolicy: LiveTestWidgetsFlutterBindingFramePolicy.benchmarkLive, ($) async { diff --git a/integration_test/mixin/scenario_utils_mixin.dart b/integration_test/mixin/scenario_utils_mixin.dart index 6766ba2db..40fc27cee 100644 --- a/integration_test/mixin/scenario_utils_mixin.dart +++ b/integration_test/mixin/scenario_utils_mixin.dart @@ -4,6 +4,7 @@ import 'dart:io' hide HttpClient; import 'package:collection/collection.dart'; import 'package:core/utils/app_logger.dart'; +import 'package:core/utils/platform_info.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:jmap_dart_client/http/http_client.dart'; @@ -17,6 +18,7 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:labels/extensions/list_label_extension.dart'; import 'package:model/model.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:patrol/patrol.dart'; import 'package:tmail_ui_user/features/composer/domain/state/upload_attachment_state.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_send_email_interactor.dart'; import 'package:tmail_ui_user/features/composer/domain/usecases/upload_attachment_interactor.dart'; @@ -287,4 +289,14 @@ mixin ScenarioUtilsMixin { void hideKeyboard() { FocusManager.instance.primaryFocus?.unfocus(); } + + Future mobileBack(PatrolIntegrationTester $) async { + if (PlatformInfo.isIOS) { + await $.platformAutomator.ios.swipeBack(); + } else if (PlatformInfo.isAndroid) { + await $.platformAutomator.android.pressBack(); + } else { + throw UnsupportedError('mobileBack() is only supported on Android/iOS'); + } + } } diff --git a/integration_test/robots/composer_robot.dart b/integration_test/robots/composer_robot.dart index c1b372eca..5759bce85 100644 --- a/integration_test/robots/composer_robot.dart +++ b/integration_test/robots/composer_robot.dart @@ -86,9 +86,9 @@ class ComposerRobot extends CoreRobot { } Future grantContactPermission() async { - if (await $.native + if (await native .isPermissionDialogVisible(timeout: const Duration(seconds: 5))) { - await $.native.grantPermissionWhenInUse(); + await native.grantPermissionWhenInUse(); } } diff --git a/integration_test/robots/login_robot.dart b/integration_test/robots/login_robot.dart index cb69949fb..fe6aea4c0 100644 --- a/integration_test/robots/login_robot.dart +++ b/integration_test/robots/login_robot.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:patrol/patrol.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import '../base/core_robot.dart'; @@ -10,9 +9,9 @@ class LoginRobot extends CoreRobot { LoginRobot(super.$); - Future grantNotificationPermission(NativeAutomator nativeAutomator) async { - if (await nativeAutomator.isPermissionDialogVisible(timeout: const Duration(seconds: 1))) { - await nativeAutomator.grantPermissionWhenInUse(); + Future grantNotificationPermission() async { + if (await native.isPermissionDialogVisible(timeout: const Duration(seconds: 1))) { + await native.grantPermissionWhenInUse(); } } diff --git a/integration_test/robots/mailbox_menu_robot.dart b/integration_test/robots/mailbox_menu_robot.dart index f43bf7d65..61e28200c 100644 --- a/integration_test/robots/mailbox_menu_robot.dart +++ b/integration_test/robots/mailbox_menu_robot.dart @@ -84,7 +84,7 @@ class MailboxMenuRobot extends CoreRobot { } Future closeMenu() async { - await $.native.swipe(from: const Offset(0.9, 0.5), to: const Offset(0, 0.5)); + await native.swipe(from: const Offset(0.9, 0.5), to: const Offset(0, 0.5)); } int getCurrentInboxCount() { @@ -130,8 +130,8 @@ class MailboxMenuRobot extends CoreRobot { } Future tapConfirmRecoverDeletedMessages() async { - if (await $.native.isPermissionDialogVisible(timeout: const Duration(seconds: 2))) { - await $.native.grantPermissionWhenInUse(); + if (await native.isPermissionDialogVisible(timeout: const Duration(seconds: 2))) { + await native.grantPermissionWhenInUse(); } await $(AppLocalizations().restore).tap(); await $.pumpAndSettle(); diff --git a/integration_test/scenarios/app_grid_scenario.dart b/integration_test/scenarios/app_grid_scenario.dart index cfa72886f..bf5a72905 100644 --- a/integration_test/scenarios/app_grid_scenario.dart +++ b/integration_test/scenarios/app_grid_scenario.dart @@ -35,19 +35,20 @@ class AppGridScenario extends BaseTestScenario { await Future.delayed(const Duration(seconds: 2)); if (PlatformInfo.isAndroid) { - await $.native.pressHome(); - await $.native.openApp(); + final native = $.platformAutomator.android; + await native.pressHome(); + await native.openApp(); await appGridRobot.openAppInAppGridByAppName('Twake Sync'); await Future.delayed(const Duration(seconds: 2)); - await $.native.pressBack(); + await native.pressBack(); await appGridRobot.openAppInAppGridByAppName('Twake Chat'); await Future.delayed(const Duration(seconds: 2)); - await $.native.pressBack(); - await $.native.pressBack(); + await native.pressBack(); + await native.pressBack(); await _expectMailboxViewVisible(); } else if (PlatformInfo.isIOS) { diff --git a/integration_test/scenarios/download_all_attachments_scenario.dart b/integration_test/scenarios/download_all_attachments_scenario.dart index 4bb6a1d70..4f41e8abf 100644 --- a/integration_test/scenarios/download_all_attachments_scenario.dart +++ b/integration_test/scenarios/download_all_attachments_scenario.dart @@ -45,6 +45,6 @@ class DownloadAllAttachmentsScenario extends BaseTestScenario { } Future _expectNativeSaveButtonVisible() async { - await expectLater($.native.tap(Selector(text: 'SAVE')), completes); + await expectLater($.platformAutomator.tap(Selector(text: 'SAVE')), completes); } } \ No newline at end of file diff --git a/integration_test/scenarios/email_detailed/export_attachment_scenario.dart b/integration_test/scenarios/email_detailed/export_attachment_scenario.dart index 67f252e53..419658c5d 100644 --- a/integration_test/scenarios/email_detailed/export_attachment_scenario.dart +++ b/integration_test/scenarios/email_detailed/export_attachment_scenario.dart @@ -42,7 +42,7 @@ class ExportAttachmentScenario extends BaseTestScenario { await emailRobot.onTapAttachmentItem(); await $.pumpAndSettle(); - await $.native.pressBack(); + await mobileBack($); _expectEmailViewVisible(); _expectExportDialogLoadingInvisible(appLocalizations); } diff --git a/integration_test/scenarios/login_with_basic_auth_scenario.dart b/integration_test/scenarios/login_with_basic_auth_scenario.dart index 1421fefcc..171198dbd 100644 --- a/integration_test/scenarios/login_with_basic_auth_scenario.dart +++ b/integration_test/scenarios/login_with_basic_auth_scenario.dart @@ -51,7 +51,7 @@ class LoginWithBasicAuthScenario extends BaseScenario { await loginRobot.loginBasicAuth(); - await loginRobot.grantNotificationPermission($.native); + await loginRobot.grantNotificationPermission(); await _expectThreadViewVisible(); } diff --git a/integration_test/scenarios/send_email_with_read_receipt_enabled_scenario.dart b/integration_test/scenarios/send_email_with_read_receipt_enabled_scenario.dart index 419be6a34..6ed295bfe 100644 --- a/integration_test/scenarios/send_email_with_read_receipt_enabled_scenario.dart +++ b/integration_test/scenarios/send_email_with_read_receipt_enabled_scenario.dart @@ -53,7 +53,7 @@ class SendEmailWithReadReceiptEnabledScenario extends BaseTestScenario { await threadRobot.openEmailWithSubject(emailSubject); await _expectReadReceiptRequestDialog(appLocalizations); - await $.native.pressBack(); + await mobileBack($); await emailRobot.onTapBackButton(); await $.pumpAndSettle(duration: seconds(5)); diff --git a/pubspec.lock b/pubspec.lock index 9d476f2da..cc5f3d5f4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1730,26 +1730,26 @@ packages: dependency: "direct dev" description: name: patrol - sha256: "782988d05af24427296e48417c36c520598656e00ba73c401a19ecd65262ee0b" + sha256: "7825a6e96a8f0755f68eec600a91a08b19bd0975488a70885b3696f6b65ffc0f" url: "https://pub.dev" source: hosted - version: "3.19.0" + version: "4.5.0" patrol_finders: dependency: "direct dev" description: name: patrol_finders - sha256: "4a658d7d560de523f92deb3fa3326c78747ca0bf7e7f4b8788c012463138b628" + sha256: "9970eac0669a90b20ec7e1bcaabd0475655655998068ca656f4df9f6ec84f336" url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "3.2.0" patrol_log: dependency: "direct dev" description: name: patrol_log - sha256: "9fed4143980df1e3bbcfa00d0b443c7d68f04f9132317b7698bbc37f8a5a58c5" + sha256: a2360db165c34692665c0de146e5157887d6b584fdccca8f141f947a5acf1b2e url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" pattern_formatter: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d06d737fb..f13c4ac4e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -295,11 +295,11 @@ dev_dependencies: http_mock_adapter: 0.4.2 - patrol: 3.19.0 + patrol: 4.5.0 - patrol_log: 0.5.0 + patrol_log: 0.8.0 - patrol_finders: 2.9.0 + patrol_finders: 3.2.0 plugin_platform_interface: 2.1.8 @@ -444,6 +444,7 @@ cider: tag: https://github.com/linagora/tmail-flutter/releases/tag/v%tag% # initial release link template patrol: + test_directory: integration_test app_name: Twake Mail android: package_name: com.linagora.android.teammail diff --git a/scripts/patrol-integration-test-with-docker.sh b/scripts/patrol-integration-test-with-docker.sh index 589e2e085..b8c91ae88 100755 --- a/scripts/patrol-integration-test-with-docker.sh +++ b/scripts/patrol-integration-test-with-docker.sh @@ -8,7 +8,7 @@ curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/tru # Install patrol CLI echo "Installing patrol CLI..." -dart pub global activate patrol_cli 3.6.0 +dart pub global activate patrol_cli 4.3.1 flutter build apk --config-only # Forward traffic to tmail-backend