Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions integration_test/base/base_test_scenario.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@

import '../mixin/requires_login_mixin.dart';
import '../factories/robot_factory.dart';
import '../mixin/scenario_utils_mixin.dart';
import 'base_scenario.dart';

abstract class BaseTestScenario extends BaseScenario
with RequiresLoginMixin, ScenarioUtilsMixin {
abstract class BaseTestScenario extends BaseScenario with ScenarioUtilsMixin {
final RobotFactory robots;

const BaseTestScenario(super.$);
const BaseTestScenario(super.$, this.robots);

@override
Future<void> execute() async {
await executeLoginScenario();
await robots.loginRobot().loginWithBasicAuth(
username: const String.fromEnvironment('USERNAME'),
hostUrl: const String.fromEnvironment('BASIC_AUTH_URL'),
email: const String.fromEnvironment('BASIC_AUTH_EMAIL'),
password: const String.fromEnvironment('PASSWORD'),
);
await runTestLogic();
}

Expand Down
9 changes: 4 additions & 5 deletions integration_test/base/test_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';
import 'package:tmail_ui_user/main/main_entry.dart';

import '../models/test_tags.dart';
import 'base_scenario.dart';
import '../factories/robot_factory.dart';
import '../factories/robot_factory_provider.dart';

class TestBase {
static final TestBase _instance = TestBase._internal();
Expand All @@ -16,8 +17,7 @@ class TestBase {

void runPatrolTest({
required String description,
required BaseScenario Function(PatrolIntegrationTester $) scenarioBuilder,
List<TestTags> tags = const [],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should keep, but for other use not for mobile/web seperately

required BaseScenario Function(PatrolIntegrationTester $, RobotFactory robots) scenarioBuilder,
}) {
patrolSetUp(_setup);

Expand All @@ -34,10 +34,9 @@ class TestBase {
findTimeout: const Duration(seconds: 10),
),
framePolicy: LiveTestWidgetsFlutterBindingFramePolicy.benchmarkLive,
tags: tags.map((tag) => tag.name).toList(),
($) async {
await setupTest();
await scenarioBuilder($).execute();
await scenarioBuilder($, createRobotFactory($)).execute();
},
);
}
Expand Down
24 changes: 24 additions & 0 deletions integration_test/factories/mobile_robot_factory.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:patrol/patrol.dart';

import 'robot_factory.dart';
import '../robots/abstract/abstract_login_robot.dart';
import '../robots/abstract/abstract_thread_robot.dart';
import '../robots/abstract/abstract_composer_robot.dart';
import '../robots/mobile/mobile_login_robot.dart';
import '../robots/mobile/mobile_thread_robot.dart';
import '../robots/mobile/mobile_composer_robot.dart';

class MobileRobotFactory implements RobotFactory {
final PatrolIntegrationTester $;

MobileRobotFactory(this.$);

@override
AbstractLoginRobot loginRobot() => MobileLoginRobot($);

@override
AbstractThreadRobot threadRobot() => MobileThreadRobot($);

@override
AbstractComposerRobot composerRobot() => MobileComposerRobot($);
}
6 changes: 6 additions & 0 deletions integration_test/factories/mobile_robot_factory_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:patrol/patrol.dart';

import 'robot_factory.dart';
import 'mobile_robot_factory.dart';

RobotFactory createRobotFactory(PatrolIntegrationTester $) => MobileRobotFactory($);
9 changes: 9 additions & 0 deletions integration_test/factories/robot_factory.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import '../robots/abstract/abstract_login_robot.dart';
import '../robots/abstract/abstract_thread_robot.dart';
import '../robots/abstract/abstract_composer_robot.dart';

abstract class RobotFactory {
AbstractLoginRobot loginRobot();
AbstractThreadRobot threadRobot();
AbstractComposerRobot composerRobot();
}
4 changes: 4 additions & 0 deletions integration_test/factories/robot_factory_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Single branching point for platform selection — this file never changes.
// dart.library.html is true on web (dart2js/dartdevc), false on mobile (dart2native).
export 'mobile_robot_factory_provider.dart'
if (dart.library.html) 'web_robot_factory_provider.dart';
25 changes: 25 additions & 0 deletions integration_test/factories/web_robot_factory.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:patrol/patrol.dart';

import 'robot_factory.dart';
import '../robots/abstract/abstract_login_robot.dart';
import '../robots/abstract/abstract_thread_robot.dart';
import '../robots/abstract/abstract_composer_robot.dart';
import '../robots/mobile/mobile_login_robot.dart';
import '../robots/mobile/mobile_thread_robot.dart';
import '../robots/web/web_composer_robot.dart';

class WebRobotFactory implements RobotFactory {
final PatrolIntegrationTester $;

WebRobotFactory(this.$);

@override
AbstractLoginRobot loginRobot() => MobileLoginRobot($);

@override
// Thread interaction is identical on web — reuse mobile robot
AbstractThreadRobot threadRobot() => MobileThreadRobot($);

@override
AbstractComposerRobot composerRobot() => WebComposerRobot($);
}
6 changes: 6 additions & 0 deletions integration_test/factories/web_robot_factory_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:patrol/patrol.dart';

import 'robot_factory.dart';
import 'web_robot_factory.dart';

RobotFactory createRobotFactory(PatrolIntegrationTester $) => WebRobotFactory($);
3 changes: 0 additions & 3 deletions integration_test/models/test_tags.dart

This file was deleted.

9 changes: 9 additions & 0 deletions integration_test/robots/abstract/abstract_composer_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:model/email/prefix_email_address.dart';

abstract class AbstractComposerRobot {
Future<void> grantContactPermission();
Future<void> addRecipient(PrefixEmailAddress prefix, String email);
Future<void> addSubject(String subject);
Future<void> addContent(String content);
Future<void> send();
}
8 changes: 8 additions & 0 deletions integration_test/robots/abstract/abstract_login_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
abstract class AbstractLoginRobot {
Future<void> loginWithBasicAuth({
required String username,
required String hostUrl,
required String email,
required String password,
});
}
3 changes: 3 additions & 0 deletions integration_test/robots/abstract/abstract_thread_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
abstract class AbstractThreadRobot {
Future<void> openComposer();
}
17 changes: 17 additions & 0 deletions integration_test/robots/mobile/mobile_composer_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:model/email/prefix_email_address.dart';
import 'package:patrol/patrol.dart';

import '../abstract/abstract_composer_robot.dart';
import '../composer_robot.dart';

class MobileComposerRobot extends ComposerRobot implements AbstractComposerRobot {
MobileComposerRobot(PatrolIntegrationTester $) : super($);

@override
Future<void> addRecipient(PrefixEmailAddress prefix, String email) =>
addRecipientIntoField(prefixEmailAddress: prefix, email: email);

@override
Future<void> send() => sendEmail(ImagePaths());
}
26 changes: 26 additions & 0 deletions integration_test/robots/mobile/mobile_login_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:patrol/patrol.dart';

import '../abstract/abstract_login_robot.dart';
import '../../scenarios/login_with_basic_auth_scenario.dart';

class MobileLoginRobot implements AbstractLoginRobot {
final PatrolIntegrationTester $;

MobileLoginRobot(this.$);

@override
Future<void> loginWithBasicAuth({
required String username,
required String hostUrl,
required String email,
required String password,
}) async {
await LoginWithBasicAuthScenario(
$,
username: username,
hostUrl: hostUrl,
email: email,
password: password,
).execute();
}
}
7 changes: 7 additions & 0 deletions integration_test/robots/mobile/mobile_thread_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import '../abstract/abstract_thread_robot.dart';
import '../thread_robot.dart';
import 'package:patrol/patrol.dart';

class MobileThreadRobot extends ThreadRobot implements AbstractThreadRobot {
MobileThreadRobot(PatrolIntegrationTester $) : super($);
}
20 changes: 20 additions & 0 deletions integration_test/robots/web/web_composer_robot.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:patrol/patrol.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/web/web_editor_widget.dart';

import '../mobile/mobile_composer_robot.dart';

/// Web-specific composer robot. Overrides [addContent] because InAppWebView
/// is unavailable on web — content is injected via Patrol's web automator.
class WebComposerRobot extends MobileComposerRobot {
WebComposerRobot(PatrolIntegrationTester $) : super($);

@override
Future<void> addContent(String content) async {
await $(WebEditorWidget).tap();
await $.platformAutomator.web.enterText(
WebSelector(cssOrXpath: 'div.note-editable'),
iframeSelector: WebSelector(cssOrXpath: 'iframe'),
text: content,
);
}
}
2 changes: 1 addition & 1 deletion integration_test/scenarios/app_grid_scenario.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import '../robots/thread_robot.dart';

class AppGridScenario extends BaseTestScenario {

const AppGridScenario(super.$);
const AppGridScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import '../../robots/thread_robot.dart';

class CalendarEventCounterScenario extends BaseTestScenario
with OpenCalendarEventScenarioMixin {
const CalendarEventCounterScenario(super.$);
const CalendarEventCounterScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import '../../robots/thread_robot.dart';

class MailToAttendeesEventEmailScenario extends BaseTestScenario
with OpenCalendarEventScenarioMixin {
const MailToAttendeesEventEmailScenario(super.$);
const MailToAttendeesEventEmailScenario(super.$, super.robots);

static const _expectedEventTitle = 'Come for a chat';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../../robots/identities_list_menu_robot.dart';
import '../../robots/thread_robot.dart';

class AttachmentReminderScenario extends BaseTestScenario {
const AttachmentReminderScenario(super.$);
const AttachmentReminderScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../../robots/mailbox_menu_robot.dart';
import '../../robots/thread_robot.dart';

class ChangeIdentityInDraftEmailScenario extends BaseTestScenario {
const ChangeIdentityInDraftEmailScenario(super.$);
const ChangeIdentityInDraftEmailScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '../../robots/composer_robot.dart';
import '../../robots/thread_robot.dart';

class SendEmailWithReadReceiptEnabledScenario extends BaseTestScenario {
const SendEmailWithReadReceiptEnabledScenario(super.$);
const SendEmailWithReadReceiptEnabledScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import '../../robots/composer_robot.dart';
import '../../robots/thread_robot.dart';

class ShowFullRecipientFieldsWhenExpandAllScenario extends BaseTestScenario {
const ShowFullRecipientFieldsWhenExpandAllScenario(super.$);
const ShowFullRecipientFieldsWhenExpandAllScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import '../../robots/thread_robot.dart';

class UpdateDraftEmailWithMessageSuccessToastScenario extends BaseTestScenario {

const UpdateDraftEmailWithMessageSuccessToastScenario(super.$);
const UpdateDraftEmailWithMessageSuccessToastScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import '../../robots/composer_robot.dart';
import '../../robots/thread_robot.dart';

class ComposerUploadAttachmentAndInlineImageScenario extends BaseTestScenario {
const ComposerUploadAttachmentAndInlineImageScenario(super.$);
const ComposerUploadAttachmentAndInlineImageScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
52 changes: 0 additions & 52 deletions integration_test/scenarios/composer/web_send_email_scenario.dart

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import '../robots/thread_robot.dart';

class DownloadAllAttachmentsScenario extends BaseTestScenario {

const DownloadAllAttachmentsScenario(super.$);
const DownloadAllAttachmentsScenario(super.$, super.robots);

@override
Future<void> runTestLogic() async {
Expand Down
Loading
Loading