From b97abfbf698e9343fbeee7f54321fa7a31902183 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 25 Mar 2026 11:09:31 +0700 Subject: [PATCH] TF-4404 Add e2e test for `Mail to attendees` action on mobile --- .../open_calendar_event_scenario_mixin.dart | 79 +++++++++++++++++++ integration_test/robots/email_robot.dart | 4 + .../calendar_event_counter_scenario.dart | 75 +++--------------- ...ail_to_attendees_event_email_scenario.dart | 62 +++++++++++++++ .../mail_to_attendees_event_email_test.dart | 11 +++ .../email/domain/model/event_action.dart | 2 + .../calendar_event_action_button_widget.dart | 1 + 7 files changed, 168 insertions(+), 66 deletions(-) create mode 100644 integration_test/mixin/open_calendar_event_scenario_mixin.dart create mode 100644 integration_test/scenarios/calendar/mail_to_attendees_event_email_scenario.dart create mode 100644 integration_test/tests/calendar/mail_to_attendees_event_email_test.dart diff --git a/integration_test/mixin/open_calendar_event_scenario_mixin.dart b/integration_test/mixin/open_calendar_event_scenario_mixin.dart new file mode 100644 index 000000000..52fcc3b8f --- /dev/null +++ b/integration_test/mixin/open_calendar_event_scenario_mixin.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:tmail_ui_user/features/email/presentation/email_view.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_action_button_widget.dart'; +import 'package:tmail_ui_user/features/search/email/presentation/search_email_view.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +import '../base/base_scenario.dart'; +import '../robots/search_robot.dart'; +import '../robots/thread_robot.dart'; + +mixin OpenCalendarEventScenarioMixin on BaseScenario { + static const eventEmailSubject = 'Proposed new time'; + + Future openCalendarEvent({ + required ThreadRobot threadRobot, + required SearchRobot searchRobot, + required AppLocalizations appLocalizations, + }) async { + await threadRobot.openSearchView(); + await _expectSearchViewVisible(); + + await searchRobot.enterQueryString(eventEmailSubject); + await searchRobot.tapOnShowAllResultsText(); + await _expectSearchResultEmailListVisible(); + + await searchRobot.openEmailWithSubject(eventEmailSubject); + await _expectEmailViewVisible(); + await _expectYesButtonVisible(appLocalizations); + await _expectMailToAttendeesButtonVisible(appLocalizations); + await _expectNoButtonInvisible(appLocalizations); + await _expectMaybeButtonInvisible(appLocalizations); + } + + Future _expectSearchViewVisible() async { + await expectViewVisible($(SearchEmailView)); + } + + Future _expectSearchResultEmailListVisible() async { + await expectViewVisible($(#search_email_list_notification_listener)); + } + + Future _expectEmailViewVisible() async { + await expectViewVisible($(EmailView), alignment: Alignment.topCenter); + } + + Future _expectYesButtonVisible( + AppLocalizations appLocalizations, + ) async { + final yesButton = + $(CalendarEventActionButtonWidget).$(appLocalizations.yes); + await yesButton.scrollTo(scrollDirection: AxisDirection.down); + await expectViewVisible(yesButton); + } + + Future _expectMailToAttendeesButtonVisible( + AppLocalizations appLocalizations, + ) async { + final mailToAttendeesButton = + $(CalendarEventActionButtonWidget).$(appLocalizations.mailToAttendees); + await mailToAttendeesButton.scrollTo(); + await expectViewVisible(mailToAttendeesButton); + } + + Future _expectNoButtonInvisible( + AppLocalizations appLocalizations, + ) async { + final noButton = $(CalendarEventActionButtonWidget).$(appLocalizations.no); + await expectViewInvisible(noButton); + } + + Future _expectMaybeButtonInvisible( + AppLocalizations appLocalizations, + ) async { + final maybeButton = + $(CalendarEventActionButtonWidget).$(appLocalizations.maybe); + await expectViewInvisible(maybeButton); + } +} diff --git a/integration_test/robots/email_robot.dart b/integration_test/robots/email_robot.dart index af9731591..14fd37007 100644 --- a/integration_test/robots/email_robot.dart +++ b/integration_test/robots/email_robot.dart @@ -99,4 +99,8 @@ class EmailRobot extends CoreRobot { Future tapDeleteThreadButton() async { await $(#delete_thread_button).tap(); } + + Future tapMailToAttendeesEventActionButton() async { + await $(#mailToAttendees_event_action_button).tap(); + } } \ No newline at end of file diff --git a/integration_test/scenarios/calendar/calendar_event_counter_scenario.dart b/integration_test/scenarios/calendar/calendar_event_counter_scenario.dart index 73c485c54..2b9d75d83 100644 --- a/integration_test/scenarios/calendar/calendar_event_counter_scenario.dart +++ b/integration_test/scenarios/calendar/calendar_event_counter_scenario.dart @@ -1,87 +1,30 @@ import 'package:flutter/widgets.dart'; -import 'package:tmail_ui_user/features/email/presentation/email_view.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart'; -import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_action_button_widget.dart'; -import 'package:tmail_ui_user/features/search/email/presentation/search_email_view.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import '../../base/base_test_scenario.dart'; +import '../../mixin/open_calendar_event_scenario_mixin.dart'; import '../../robots/search_robot.dart'; import '../../robots/thread_robot.dart'; -class CalendarEventCounterScenario extends BaseTestScenario { +class CalendarEventCounterScenario extends BaseTestScenario + with OpenCalendarEventScenarioMixin { const CalendarEventCounterScenario(super.$); - + @override Future runTestLogic() async { - const emailSubject = 'Proposed new time'; - final threadRobot = ThreadRobot($); final searchRobot = SearchRobot($); final appLocalizations = AppLocalizations(); - - await threadRobot.openSearchView(); - await _expectSearchViewVisible(); - await searchRobot.enterQueryString(emailSubject); - await searchRobot.tapOnShowAllResultsText(); - await _expectSearchResultEmailListVisible(); - - await searchRobot.openEmailWithSubject(emailSubject); - await _expectEmailViewVisible(); - await _expectYesButtonVisible(appLocalizations); - await _expectMailToAttendeesButtonVisible(appLocalizations); - await _expectNoButtonInvisible(appLocalizations); - await _expectMaybeButtonInvisible(appLocalizations); + await openCalendarEvent( + threadRobot: threadRobot, + searchRobot: searchRobot, + appLocalizations: appLocalizations, + ); await _expectProposedEventChangesTextVisible(appLocalizations); } - Future _expectSearchViewVisible() async { - await expectViewVisible($(SearchEmailView)); - } - - Future _expectSearchResultEmailListVisible() async { - await expectViewVisible($(#search_email_list_notification_listener)); - } - - Future _expectEmailViewVisible() async { - await expectViewVisible($(EmailView), alignment: Alignment.topCenter); - } - - Future _expectYesButtonVisible( - AppLocalizations appLocalizations, - ) async { - final yesButton = $(CalendarEventActionButtonWidget) - .$(appLocalizations.yes); - await yesButton.scrollTo(scrollDirection: AxisDirection.down); - await expectViewVisible(yesButton); - } - - Future _expectMailToAttendeesButtonVisible( - AppLocalizations appLocalizations, - ) async { - final mailToAttendeesButton = $(CalendarEventActionButtonWidget) - .$(appLocalizations.mailToAttendees); - await mailToAttendeesButton.scrollTo(); - await expectViewVisible(mailToAttendeesButton); - } - - Future _expectNoButtonInvisible( - AppLocalizations appLocalizations, - ) async { - final noButton = $(CalendarEventActionButtonWidget) - .$(appLocalizations.no); - await expectViewInvisible(noButton); - } - - Future _expectMaybeButtonInvisible( - AppLocalizations appLocalizations, - ) async { - final maybeButton = $(CalendarEventActionButtonWidget) - .$(appLocalizations.maybe); - await expectViewInvisible(maybeButton); - } - Future _expectProposedEventChangesTextVisible( AppLocalizations appLocalizations, ) async { diff --git a/integration_test/scenarios/calendar/mail_to_attendees_event_email_scenario.dart b/integration_test/scenarios/calendar/mail_to_attendees_event_email_scenario.dart new file mode 100644 index 000000000..9bffe7009 --- /dev/null +++ b/integration_test/scenarios/calendar/mail_to_attendees_event_email_scenario.dart @@ -0,0 +1,62 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart'; +import 'package:tmail_ui_user/features/composer/presentation/composer_view.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/subject_composer_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +import '../../base/base_test_scenario.dart'; +import '../../mixin/open_calendar_event_scenario_mixin.dart'; +import '../../robots/composer_robot.dart'; +import '../../robots/email_robot.dart'; +import '../../robots/search_robot.dart'; +import '../../robots/thread_robot.dart'; + +class MailToAttendeesEventEmailScenario extends BaseTestScenario + with OpenCalendarEventScenarioMixin { + const MailToAttendeesEventEmailScenario(super.$); + + @override + Future runTestLogic() async { + final threadRobot = ThreadRobot($); + final searchRobot = SearchRobot($); + final composerRobot = ComposerRobot($); + final emailRobot = EmailRobot($); + final appLocalizations = AppLocalizations(); + + await openCalendarEvent( + threadRobot: threadRobot, + searchRobot: searchRobot, + appLocalizations: appLocalizations, + ); + + await emailRobot.tapMailToAttendeesEventActionButton(); + await _expectComposerViewVisible(); + await composerRobot.grantContactPermission(); + + await _expectSubjectFilledCorrectly(appLocalizations); + } + + Future _expectComposerViewVisible() async { + await expectViewVisible($(ComposerView)); + } + + Future _expectSubjectFilledCorrectly( + AppLocalizations appLocalizations, + ) async { + await expectViewVisible($(SubjectComposerWidget)); + + final composerController = Get.find(); + final actualSubject = composerController.subjectEmail.value ?? ''; + + final expectedSubject = EmailUtils.applyPrefix( + subject: 'Come for a chat', + defaultPrefix: EmailUtils.defaultReplyPrefix, + localizedPrefix: appLocalizations.prefix_reply_email, + ); + + expect(actualSubject, contains(appLocalizations.prefix_reply_email)); + expect(actualSubject, equals(expectedSubject)); + } +} diff --git a/integration_test/tests/calendar/mail_to_attendees_event_email_test.dart b/integration_test/tests/calendar/mail_to_attendees_event_email_test.dart new file mode 100644 index 000000000..2daccbb96 --- /dev/null +++ b/integration_test/tests/calendar/mail_to_attendees_event_email_test.dart @@ -0,0 +1,11 @@ +import '../../base/test_base.dart'; +import '../../scenarios/calendar/mail_to_attendees_event_email_scenario.dart'; + +void main() { + TestBase().runPatrolTest( + description: 'Should fill subject with reply prefix ' + 'when user taps mail to attendees button ' + 'on calendar event email', + scenarioBuilder: ($) => MailToAttendeesEventEmailScenario($), + ); +} diff --git a/lib/features/email/domain/model/event_action.dart b/lib/features/email/domain/model/event_action.dart index 69c8302c9..0ad2dbcf5 100644 --- a/lib/features/email/domain/model/event_action.dart +++ b/lib/features/email/domain/model/event_action.dart @@ -24,6 +24,8 @@ enum EventActionType { } } + Key getKeyButton() => Key('${name}_event_action_button'); + String getToastMessageSuccess(BuildContext context) { switch(this) { case EventActionType.yes: diff --git a/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_button_widget.dart b/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_button_widget.dart index a9d8316fd..a13c54032 100644 --- a/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_button_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_button_widget.dart @@ -40,6 +40,7 @@ class CalendarEventActionButtonWidget extends StatelessWidget { .map((action) => AbsorbPointer( absorbing: _getCallbackFunction(action) == null, child: TMailButtonWidget( + key: action.getKeyButton(), text: action.getLabelButton(context), backgroundColor: _getButtonBackgroundColor(action), borderRadius: CalendarEventActionButtonWidgetStyles.borderRadius,