Skip to content

Commit

Permalink
TF-2528 Add integration test for search with sort by sender name
Browse files Browse the repository at this point in the history
  • Loading branch information
dab246 committed Nov 11, 2024
1 parent ba3eab6 commit 2af41f6
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 5 deletions.
2 changes: 1 addition & 1 deletion backend-docker/jmap.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
url.prefix=https://a872-222-252-23-73.ngrok-free.app
url.prefix=https://b465-222-252-23-73.ngrok-free.app
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
50 changes: 50 additions & 0 deletions integration_test/robots/search_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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));
}

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: 8 additions & 0 deletions 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 @@ -15,4 +17,10 @@ class ThreadRobot extends CoreRobot {
}

Future<void> expectComposerViewVisible() => ensureViewVisible($(ComposerView));

Future<void> openSearchView() async {
await $(SearchBarView).$(InkWell).tap();
}

Future<void> expectSearchViewVisible() => ensureViewVisible($(SearchEmailView));
}
60 changes: 60 additions & 0 deletions integration_test/scenarios/search_email_scenario.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
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 threadRobot.expectComposerViewVisible();
await Future.delayed(const Duration(seconds: 1));
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 3s
await Future.delayed(const Duration(seconds: 2));
}

await threadRobot.openSearchView();
await threadRobot.expectSearchViewVisible();

final searchRobot = SearchRobot($);

await searchRobot.enterQueryString(queryString);
await searchRobot.scrollToEndListSearchFilter();
await searchRobot.openSortOrderBottomDialog();
await searchRobot.selectSenderAscending();

await searchRobot.expectEmailListDisplayedInFullOrder(
queryString: queryString,
recipientListSorted: recipientListSorted,
);
}
}
32 changes: 32 additions & 0 deletions integration_test/tests/search/search_email_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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 {
final loginWithBasicAuthScenario = LoginWithBasicAuthScenario($,
username: const String.fromEnvironment('USERNAME'),
hostUrl: const String.fromEnvironment('BASIC_AUTH_URL'),
email: const String.fromEnvironment('BASIC_AUTH_EMAIL'),
password: const String.fromEnvironment('PASSWORD'),
);

final searchEmailScenario = SearchEmailScenario(
$,
loginWithBasicAuthScenario: loginWithBasicAuthScenario,
queryString: 'Hello',
recipientListSorted: [
EmailAddress('alice1', '[email protected]'),
EmailAddress('alice2', '[email protected]'),
EmailAddress('alice3', '[email protected]'),
]
);

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
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

0 comments on commit 2af41f6

Please sign in to comment.