diff --git a/integration_test/robots/labels/choose_label_modal_robot.dart b/integration_test/robots/labels/choose_label_modal_robot.dart new file mode 100644 index 000000000..e97da4665 --- /dev/null +++ b/integration_test/robots/labels/choose_label_modal_robot.dart @@ -0,0 +1,35 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:tmail_ui_user/features/labels/presentation/widgets/choose_label_modal.dart'; +import 'package:tmail_ui_user/features/labels/presentation/widgets/no_label_yet_widget.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/labels/label_list_item.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +import '../../base/core_robot.dart'; + +class ChooseLabelModalRobot extends CoreRobot { + ChooseLabelModalRobot(super.$); + + Future tapCreateALabelButton() async { + await $(ChooseLabelModal) + .$(find.text(AppLocalizations().createALabel)) + .tap(); + } + + Future tapLabelByName(String name) async { + final item = $(ChooseLabelModal).$(LabelListItem).$(name); + await $.scrollUntilVisible(finder: item); + await item.tap(); + } + + Future tapAddLabelButton() async { + await $(ChooseLabelModal) + .$(find.text(AppLocalizations().addLabel)) + .tap(); + } + + bool get isNoLabelYetWidgetVisible => + $(ChooseLabelModal).$(NoLabelYetWidget).visible; + + bool get isLabelListVisible => + $(ChooseLabelModal).$(LabelListItem).visible; +} diff --git a/integration_test/robots/thread_robot.dart b/integration_test/robots/thread_robot.dart index 75d26dfb1..69045d79a 100644 --- a/integration_test/robots/thread_robot.dart +++ b/integration_test/robots/thread_robot.dart @@ -117,6 +117,12 @@ class ThreadRobot extends CoreRobot { await $.pumpAndSettle(duration: const Duration(seconds: 2)); } + Future tapLabelAsButton() async { + await $(#moreAction_selected_email_button).tap(); + await $.pumpAndTrySettle(); + await $(#labelAs_action).tap(); + } + Future tapEmptySpamAfterLongPress() async { await $(AppLocalizations().deleteAllSpamEmails).tap(); } diff --git a/integration_test/scenarios/labels/create_label_from_choose_label_modal_with_existing_labels_scenario.dart b/integration_test/scenarios/labels/create_label_from_choose_label_modal_with_existing_labels_scenario.dart new file mode 100644 index 000000000..e43dbb1fc --- /dev/null +++ b/integration_test/scenarios/labels/create_label_from_choose_label_modal_with_existing_labels_scenario.dart @@ -0,0 +1,75 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:labels/labels.dart'; +import 'package:tmail_ui_user/features/labels/presentation/models/label_action_type.dart'; +import 'package:tmail_ui_user/features/labels/presentation/widgets/no_label_yet_widget.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/widgets/labels/label_list_view.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +import '../../base/base_test_scenario.dart'; +import '../../mixin/provisioning_label_scenario_mixin.dart'; +import '../../robots/labels/choose_label_modal_robot.dart'; +import '../../robots/labels/create_label_modal_robot.dart'; +import '../../robots/thread_robot.dart'; + +class CreateLabelFromChooseLabelModalWithExistingLabelsScenario + extends BaseTestScenario with ProvisioningLabelScenarioMixin { + const CreateLabelFromChooseLabelModalWithExistingLabelsScenario(super.$); + + @override + Future runTestLogic() async { + const emailUser = String.fromEnvironment('BASIC_AUTH_EMAIL'); + expect(emailUser, isNotEmpty, reason: 'BASIC_AUTH_EMAIL must be set'); + + final threadRobot = ThreadRobot($); + final chooseLabelModalRobot = ChooseLabelModalRobot($); + final createLabelModalRobot = CreateLabelModalRobot($); + + final labels = await provisionLabelsByDisplayNames(['Existing Label 1']); + await $.pumpAndSettle(); + expect(labels, isNotEmpty, reason: 'Provisioning label failed'); + + final existingLabel = labels.first; + + await provisionEmail( + buildEmailsForLabel( + label: existingLabel, + toEmail: emailUser, + count: 1, + ), + requestReadReceipt: false, + ); + await $.pumpAndSettle(duration: const Duration(seconds: 2)); + + await threadRobot.openMailbox(); + await expectViewVisible($(LabelListView)); + await $.native.pressBack(); + + await threadRobot.longPressEmailWithSubject( + 'Email 1 subject ${existingLabel.safeDisplayName}', + ); + await $.pumpAndTrySettle(); + + await threadRobot.tapLabelAsButton(); + await $.pumpAndTrySettle(); + + expect(chooseLabelModalRobot.isLabelListVisible, isTrue); + expect($(NoLabelYetWidget).visible, isFalse); + await expectViewVisible($(find.text(AppLocalizations().createALabel))); + + await chooseLabelModalRobot.tapCreateALabelButton(); + await $.pumpAndTrySettle(); + + await expectViewVisible($(#create_new_label_modal)); + + final uniqueSuffix = DateTime.now().microsecondsSinceEpoch; + final newLabelName = 'New label from modal $uniqueSuffix'; + await createLabelModalRobot.enterNewLabelName(newLabelName); + await createLabelModalRobot.tapPositiveActionButton(LabelActionType.create); + await $.pumpAndTrySettle(); + + await expectViewVisible( + $(find.text(AppLocalizations().createLabelSuccessfullyMessage(newLabelName))), + ); + await expectViewVisible($(newLabelName)); + } +} diff --git a/integration_test/scenarios/labels/create_label_from_no_label_yet_widget_scenario.dart b/integration_test/scenarios/labels/create_label_from_no_label_yet_widget_scenario.dart new file mode 100644 index 000000000..c9f8f2219 --- /dev/null +++ b/integration_test/scenarios/labels/create_label_from_no_label_yet_widget_scenario.dart @@ -0,0 +1,64 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:tmail_ui_user/features/labels/presentation/models/label_action_type.dart'; +import 'package:tmail_ui_user/features/labels/presentation/widgets/no_label_yet_widget.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +import '../../base/base_test_scenario.dart'; +import '../../models/provisioning_email.dart'; +import '../../robots/labels/choose_label_modal_robot.dart'; +import '../../robots/labels/create_label_modal_robot.dart'; +import '../../robots/thread_robot.dart'; + +class CreateLabelFromNoLabelYetWidgetScenario extends BaseTestScenario { + const CreateLabelFromNoLabelYetWidgetScenario(super.$); + + @override + Future runTestLogic() async { + const emailUser = String.fromEnvironment('BASIC_AUTH_EMAIL'); + expect(emailUser, isNotEmpty, reason: 'BASIC_AUTH_EMAIL must be set'); + + final threadRobot = ThreadRobot($); + final chooseLabelModalRobot = ChooseLabelModalRobot($); + final createLabelModalRobot = CreateLabelModalRobot($); + + await provisionEmail( + [ + ProvisioningEmail( + toEmail: emailUser, + subject: 'Test email for create label from no-label widget', + content: 'Content', + ), + ], + requestReadReceipt: false, + ); + await $.pumpAndSettle(duration: const Duration(seconds: 2)); + + await threadRobot.longPressEmailWithSubject( + 'Test email for create label from no-label widget', + ); + await $.pumpAndTrySettle(); + + await threadRobot.tapLabelAsButton(); + await $.pumpAndTrySettle(); + + await expectViewVisible($(NoLabelYetWidget)); + + await chooseLabelModalRobot.tapCreateALabelButton(); + await $.pumpAndTrySettle(); + + await expectViewVisible($(#create_new_label_modal)); + + final uniqueSuffix = DateTime.now().microsecondsSinceEpoch; + final newLabelName = 'Label from no-label widget $uniqueSuffix'; + await createLabelModalRobot.enterNewLabelName(newLabelName); + await createLabelModalRobot.tapPositiveActionButton(LabelActionType.create); + await $.pumpAndTrySettle(); + + await expectViewVisible( + $(find.text(AppLocalizations().createLabelSuccessfullyMessage(newLabelName))), + ); + expect(chooseLabelModalRobot.isLabelListVisible, isTrue); + await expectViewVisible($(newLabelName)); + expect($(NoLabelYetWidget).visible, isFalse); + } +} diff --git a/integration_test/scenarios/labels/display_no_label_yet_widget_when_open_choose_label_modal_scenario.dart b/integration_test/scenarios/labels/display_no_label_yet_widget_when_open_choose_label_modal_scenario.dart new file mode 100644 index 000000000..5d186383b --- /dev/null +++ b/integration_test/scenarios/labels/display_no_label_yet_widget_when_open_choose_label_modal_scenario.dart @@ -0,0 +1,51 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:tmail_ui_user/features/labels/presentation/widgets/no_label_yet_widget.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +import '../../base/base_test_scenario.dart'; +import '../../models/provisioning_email.dart'; +import '../../robots/labels/choose_label_modal_robot.dart'; +import '../../robots/thread_robot.dart'; + +class DisplayNoLabelYetWidgetWhenOpenChooseLabelModalScenario + extends BaseTestScenario { + const DisplayNoLabelYetWidgetWhenOpenChooseLabelModalScenario(super.$); + + @override + Future runTestLogic() async { + const emailUser = String.fromEnvironment('BASIC_AUTH_EMAIL'); + expect(emailUser, isNotEmpty, reason: 'BASIC_AUTH_EMAIL must be set'); + + final threadRobot = ThreadRobot($); + final chooseLabelModalRobot = ChooseLabelModalRobot($); + + await provisionEmail( + [ + ProvisioningEmail( + toEmail: emailUser, + subject: 'Test email for no-label modal', + content: 'Content', + ), + ], + requestReadReceipt: false, + ); + await $.pumpAndSettle(duration: const Duration(seconds: 2)); + + await threadRobot.longPressEmailWithSubject('Test email for no-label modal'); + await $.pumpAndTrySettle(); + + await threadRobot.tapLabelAsButton(); + await $.pumpAndTrySettle(); + + await _expectNoLabelYetWidgetVisible(chooseLabelModalRobot); + } + + Future _expectNoLabelYetWidgetVisible( + ChooseLabelModalRobot chooseLabelModalRobot, + ) async { + await expectViewVisible($(NoLabelYetWidget)); + await expectViewVisible($(find.text(AppLocalizations().noLabelsYet))); + await expectViewVisible($(find.text(AppLocalizations().createALabel))); + expect(chooseLabelModalRobot.isLabelListVisible, isFalse); + } +} diff --git a/integration_test/tests/labels/create_label_from_choose_label_modal_with_existing_labels_test.dart b/integration_test/tests/labels/create_label_from_choose_label_modal_with_existing_labels_test.dart new file mode 100644 index 000000000..6135e1bf5 --- /dev/null +++ b/integration_test/tests/labels/create_label_from_choose_label_modal_with_existing_labels_test.dart @@ -0,0 +1,11 @@ +import '../../base/test_base.dart'; +import '../../scenarios/labels/create_label_from_choose_label_modal_with_existing_labels_scenario.dart'; + +void main() { + TestBase().runPatrolTest( + description: + 'Should show "Create a label" button in Choose Label modal when labels exist, and create a new label successfully', + scenarioBuilder: ($) => + CreateLabelFromChooseLabelModalWithExistingLabelsScenario($), + ); +} diff --git a/integration_test/tests/labels/create_label_from_no_label_yet_widget_test.dart b/integration_test/tests/labels/create_label_from_no_label_yet_widget_test.dart new file mode 100644 index 000000000..0f3a1b449 --- /dev/null +++ b/integration_test/tests/labels/create_label_from_no_label_yet_widget_test.dart @@ -0,0 +1,10 @@ +import '../../base/test_base.dart'; +import '../../scenarios/labels/create_label_from_no_label_yet_widget_scenario.dart'; + +void main() { + TestBase().runPatrolTest( + description: + 'Should create a label from NoLabelYetWidget and show it in the Choose Label modal list', + scenarioBuilder: ($) => CreateLabelFromNoLabelYetWidgetScenario($), + ); +} diff --git a/integration_test/tests/labels/display_no_label_yet_widget_when_open_choose_label_modal_test.dart b/integration_test/tests/labels/display_no_label_yet_widget_when_open_choose_label_modal_test.dart new file mode 100644 index 000000000..eb9e1776c --- /dev/null +++ b/integration_test/tests/labels/display_no_label_yet_widget_when_open_choose_label_modal_test.dart @@ -0,0 +1,11 @@ +import '../../base/test_base.dart'; +import '../../scenarios/labels/display_no_label_yet_widget_when_open_choose_label_modal_scenario.dart'; + +void main() { + TestBase().runPatrolTest( + description: + 'Should display NoLabelYetWidget when opening Choose Label modal with no labels', + scenarioBuilder: ($) => + DisplayNoLabelYetWidgetWhenOpenChooseLabelModalScenario($), + ); +}