Skip to content

Commit

Permalink
TF-2528 Add integration test for search email with sort by sender nam…
Browse files Browse the repository at this point in the history
…e ascending
  • Loading branch information
dab246 committed Nov 11, 2024
1 parent ba3eab6 commit ad98dbf
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import 'package:pointer_interceptor/pointer_interceptor.dart';
class CupertinoActionSheetBuilder {

final BuildContext _context;
final Key? key;
final List<Widget> _actionTiles = [];

Widget? _titleWidget;
Widget? _messageWidget;
Widget? _cancelWidget;

CupertinoActionSheetBuilder(this._context);
CupertinoActionSheetBuilder(this._context, {this.key});

void title(Widget? titleWidget) {
_titleWidget = titleWidget;
Expand All @@ -35,6 +36,7 @@ class CupertinoActionSheetBuilder {
context: _context,
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
builder: (context) => PointerInterceptor(child: CupertinoActionSheet(
key: key,
title: _titleWidget,
message: _messageWidget,
actions: _actionTiles,
Expand Down
51 changes: 51 additions & 0 deletions integration_test/robots/search_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';

import '../base/core_robot.dart';

class SearchRobot extends CoreRobot {
SearchRobot(super.$);

Future<void> enterQueryString(String queryString) async {
await $(#search_email_text_field).enterText(queryString);
await ensureViewVisible($(#suggestion_search_list_view));
}

Future<void> scrollToEndListSearchFilter() async {
await $.scrollUntilVisible(
finder: $(#mobile_sortBy_search_filter_button),
view: $(#search_filter_list_view),
scrollDirection: AxisDirection.right,
delta: 300,
);
await ensureViewVisible($(#mobile_sortBy_search_filter_button));
}

Future<void> openSortOrderBottomDialog() async {
await $(#mobile_sortBy_search_filter_button).tap();
await ensureViewVisible($(#sort_filter_context_menu));
}

Future<void> selectSenderAscending() async {
await $(find.text(AppLocalizations().senderAscending)).tap();
await Future.delayed(const Duration(seconds: 2));
await ensureViewVisible($(#search_email_list_notification_listener));
}

Future<void> expectEmailListDisplayedInFullOrder({
required String queryString,
required List<EmailAddress> recipientListSorted,
}) async {
expect(
find.byType(ListTile),
findsNWidgets(recipientListSorted.length),
);

for (var i = 0; i < recipientListSorted.length; i++) {
final itemFinder = find.text('$queryString ${recipientListSorted[i].name}');
expect(itemFinder, findsOneWidget);
}
}
}
8 changes: 7 additions & 1 deletion integration_test/robots/thread_robot.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:core/presentation/views/search/search_bar_view.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/widget/compose_floating_button.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_view.dart';
import 'package:tmail_ui_user/features/search/email/presentation/search_email_view.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';

import '../base/core_robot.dart';
Expand All @@ -12,7 +14,11 @@ class ThreadRobot extends CoreRobot {

Future<void> openComposer() async {
await $(ComposeFloatingButton).$(InkWell).tap();
await ensureViewVisible($(ComposerView));
}

Future<void> expectComposerViewVisible() => ensureViewVisible($(ComposerView));
Future<void> openSearchView() async {
await $(SearchBarView).$(InkWell).tap();
await ensureViewVisible($(SearchEmailView));
}
}
56 changes: 56 additions & 0 deletions integration_test/scenarios/search_email_scenario.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart';

import '../base/base_scenario.dart';
import '../robots/composer_robot.dart';
import '../robots/search_robot.dart';
import '../robots/thread_robot.dart';
import 'login_with_basic_auth_scenario.dart';

class SearchEmailScenario extends BaseScenario {
const SearchEmailScenario(
super.$,
{
required this.loginWithBasicAuthScenario,
required this.queryString,
required this.recipientListSorted,
}
);

final LoginWithBasicAuthScenario loginWithBasicAuthScenario;
final String queryString;
final List<EmailAddress> recipientListSorted;

@override
Future<void> execute() async {
await loginWithBasicAuthScenario.execute();

final threadRobot = ThreadRobot($);
final composerRobot = ComposerRobot($);

for (var i = 0; i < recipientListSorted.length; i++) {
await threadRobot.openComposer();
await composerRobot.grantContactPermission();
await composerRobot.addRecipient(recipientListSorted[i].emailAddress);
await composerRobot.addSubject('Subject');
await composerRobot.addContent('$queryString ${recipientListSorted[i].name}');
await composerRobot.sendEmail();
await composerRobot.expectSendEmailSuccessToast();
// Send each email after 2s
await Future.delayed(const Duration(seconds: 2));
}

await threadRobot.openSearchView();

final searchRobot = SearchRobot($);
await searchRobot.enterQueryString(queryString);
await searchRobot.scrollToEndListSearchFilter();
await searchRobot.openSortOrderBottomDialog();
await searchRobot.selectSenderAscending();

await searchRobot.expectEmailListDisplayedInFullOrder(
queryString: queryString,
recipientListSorted: recipientListSorted,
);
}
}
1 change: 0 additions & 1 deletion integration_test/scenarios/send_email_scenario.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class SendEmailScenario extends BaseScenario {
await loginWithBasicAuthScenario.execute();

await threadRobot.openComposer();
await threadRobot.expectComposerViewVisible();

await composerRobot.grantContactPermission();

Expand Down
41 changes: 41 additions & 0 deletions integration_test/tests/search/search_email_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';

import '../../base/test_base.dart';
import '../../scenarios/login_with_basic_auth_scenario.dart';
import '../../scenarios/search_email_scenario.dart';

void main() {
TestBase().runPatrolTest(
description: 'Should see list email sort by SenderName ascending when search email successfully',
test: ($) async {
const username = String.fromEnvironment('USERNAME');
const password = String.fromEnvironment('PASSWORD');
const hostUrl = String.fromEnvironment('BASIC_AUTH_URL');
const email = String.fromEnvironment('BASIC_AUTH_EMAIL');

final loginWithBasicAuthScenario = LoginWithBasicAuthScenario(
$,
username: username,
password: password,
hostUrl: hostUrl,
email: email,
);

const queryString = 'Hello';
final recipientList = [
EmailAddress('alice1', '[email protected]'),
EmailAddress('alice2', '[email protected]'),
EmailAddress('alice3', '[email protected]'),
];

final searchEmailScenario = SearchEmailScenario(
$,
loginWithBasicAuthScenario: loginWithBasicAuthScenario,
queryString: queryString,
recipientListSorted: recipientList,
);

await searchEmailScenario.execute();
},
);
}
11 changes: 9 additions & 2 deletions lib/features/base/mixin/popup_context_menu_action_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart';

mixin PopupContextMenuActionMixin {

void openContextMenuAction(BuildContext context, List<Widget> actionTiles, {Widget? cancelButton}) async {
await (CupertinoActionSheetBuilder(context)
void openContextMenuAction(
BuildContext context,
List<Widget> actionTiles,
{
Widget? cancelButton,
Key? key,
}
) async {
await (CupertinoActionSheetBuilder(context, key: key)
..addTiles(actionTiles)
..addCancelButton(cancelButton ?? buildCancelButton(context)))
.show();
Expand Down
15 changes: 9 additions & 6 deletions lib/features/composer/presentation/composer_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -955,12 +955,15 @@ class ComposerController extends BaseController
}

Future<String> _getContentInEditor() async {
final htmlTextEditor = PlatformInfo.isWeb
? _textEditorWeb
: await htmlEditorApi?.getText();
if (htmlTextEditor?.isNotEmpty == true) {
return htmlTextEditor!.removeEditorStartTag();
} else {
try {
final htmlTextEditor = PlatformInfo.isWeb
? _textEditorWeb
: await htmlEditorApi?.getText();
return htmlTextEditor?.isNotEmpty == true
? htmlTextEditor!.removeEditorStartTag()
: '';
} catch (e) {
logError('ComposerController::_getContentInEditor:Exception = $e');
return '';
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
onTap: () => controller.closeSearchView(context: context)
),
Expanded(child: TextFieldBuilder(
key: const Key('search_email_text_field'),
onTextChange: controller.onTextSearchChange,
textInputAction: TextInputAction.search,
controller: controller.textInputSearchController,
Expand Down Expand Up @@ -190,6 +191,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
),
scrollController: controller.listSearchFilterScrollController,
child: ListView(
key: const Key('search_filter_list_view'),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
controller: controller.listSearchFilterScrollController,
Expand Down Expand Up @@ -375,7 +377,8 @@ class SearchEmailView extends GetWidget<SearchEmailController>
context,
controller.emailSortOrderType.value,
controller.selectSortOrderQuickSearchFilter
)
),
key: const Key('sort_filter_context_menu')
);
}

Expand Down Expand Up @@ -562,6 +565,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>
List<PresentationEmail> listSuggestionSearch
) {
return ListView.builder(
key: const Key('suggestion_search_list_view'),
shrinkWrap: true,
primary: false,
itemCount: listSuggestionSearch.length,
Expand Down Expand Up @@ -618,6 +622,7 @@ class SearchEmailView extends GetWidget<SearchEmailController>

Widget _buildListEmailBody(BuildContext context, List<PresentationEmail> listPresentationEmail) {
return NotificationListener<ScrollNotification>(
key: const Key('search_email_list_notification_listener'),
onNotification: (ScrollNotification scrollInfo) {
if (scrollInfo is ScrollEndNotification
&& controller.searchMoreState != SearchMoreState.waiting
Expand Down

0 comments on commit ad98dbf

Please sign in to comment.