Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add patrol poc #524

Closed
wants to merge 12 commits into from
Closed
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
3 changes: 2 additions & 1 deletion .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ asmjs
asyncio
asyncpg
auditability
Automator
backendpython
bech
bkioshn
Expand Down Expand Up @@ -203,4 +204,4 @@ xctestrun
xcworkspace
yoroi
multiasset
unawaited
unawaited
5 changes: 4 additions & 1 deletion catalyst_voices/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,7 @@ coverage/
**/fastlane/test_output

# Fastlane.swift runner binary
**/fastlane/FastlaneRunner
**/fastlane/FastlaneRunner

# Patrol auto-generated file
test_bundle.dart
11 changes: 10 additions & 1 deletion catalyst_voices/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ android {
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: "true"
multiDexEnabled true
}

signingConfigs {
Expand Down Expand Up @@ -105,6 +107,10 @@ android {
signingConfig signingConfigs.debug
}
}
testOptions {
execution "ANDROIDX_TEST_ORCHESTRATOR"
}

}

flutter {
Expand All @@ -113,6 +119,9 @@ flutter {

dependencies {
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:multidex:2.0.1'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.3'
androidTestUtil "androidx.test:orchestrator:1.4.2"

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
package io.projectcatalyst.catalyst_voices;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import org.junit.Rule;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import pl.leancode.patrol.PatrolJUnitRunner;

@RunWith(FlutterTestRunner.class)
@RunWith(Parameterized.class)
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class, true, false);
}

@Parameters(name = "{0}")
public static Object[] testCases() {
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
instrumentation.setUp(MainActivity.class);
instrumentation.waitForPatrolAppService();
return instrumentation.listDartTests();
}

public MainActivityTest(String dartTestName) {
this.dartTestName = dartTestName;
}

private final String dartTestName;

@Test
public void runDartTest() {
PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation();
instrumentation.runDartTest(dartTestName);
}
}
34 changes: 34 additions & 0 deletions catalyst_voices/integration_test/common.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'package:catalyst_voices/app/app.dart';
import 'package:catalyst_voices/app/view/app_page.dart';
import 'package:catalyst_voices/configs/bootstrap.dart' as app;
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

export 'package:flutter_test/flutter_test.dart';
export 'package:patrol/patrol.dart';

const _nativeAutomatorConfig = NativeAutomatorConfig(
findTimeout: Duration(seconds: 30), // 10 seconds is too short for some CIs
);

Future<void> createApp(PatrolIntegrationTester $) async {
await app.bootstrapForTests();
await $.pumpWidgetAndSettle(const App());
}

void patrol(
String description,
Future<void> Function(PatrolIntegrationTester) callback, {
bool? skip,
NativeAutomatorConfig? nativeAutomatorConfig,
LiveTestWidgetsFlutterBindingFramePolicy framePolicy =
LiveTestWidgetsFlutterBindingFramePolicy.fadePointers,
}) {
patrolTest(
description,
nativeAutomatorConfig: nativeAutomatorConfig ?? _nativeAutomatorConfig,
framePolicy: framePolicy,
skip: skip,
callback,
);
}
19 changes: 19 additions & 0 deletions catalyst_voices/integration_test/landing_page_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:catalyst_voices_localization/generated/catalyst_voices_localizations.dart';
import 'package:flutter/material.dart';

import 'common.dart';

void main() {
patrol('Test Landing page', (PatrolIntegrationTester $) async {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a section in catalyst_voices/README.md how to run the patrol test?

await createApp($);
await Future<void>.delayed(const Duration(seconds: 15));
final BuildContext context = $.tester.element(find.byType(Container).first);
final localization = VoicesLocalizations.of(context);
final comingSoonText = localization?.comingSoonDescription;
final comingSoonTitle1 = localization?.comingSoonTitle1;
final comingSoonTitle2 = localization?.comingSoonTitle2;
expect($(comingSoonText), findsOneWidget);
expect($(comingSoonTitle1), findsOneWidget);
expect($(comingSoonTitle2), findsOneWidget);
});
}
17 changes: 17 additions & 0 deletions catalyst_voices/lib/configs/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:url_strategy/url_strategy.dart';

/// Initializes and runs the application provided by the [builder].
///
/// When updating see docs for [bootstrapForTests].
Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
WidgetsFlutterBinding.ensureInitialized();

Expand All @@ -24,3 +27,17 @@ Future<void> bootstrap(FutureOr<Widget> Function() builder) async {

runApp(await builder());
}

/// Initializer for integration tests, similar to [bootstrap] but:
/// - Must not call [WidgetsFlutterBinding.ensureInitialized].
/// - Must not call [runApp].
/// - Must not override [FlutterError.onError].
/// - Must be synced with [bootstrap], to run exactly the same
/// initialization logic except for the above exclusions.
///
/// Keep the function close to [bootstrap] so that they get updated together.
Future<void> bootstrapForTests() async {
GoRouter.optionURLReflectsImperativeAPIs = true;
setPathUrlStrategy();
Bloc.observer = AppBlocObserver();
}
7 changes: 7 additions & 0 deletions catalyst_voices/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ dev_dependencies:
sdk: flutter
mockito: ^5.4.4
mocktail: ^1.0.1
patrol: ^3.6.1

flutter:
uses-material-design: true
generate: true

patrol:
app_name: Catalyst Voices
flavor: qa
android:
package_name: io.projectcatalyst.catalyst_voices
Loading