Skip to content

Commit

Permalink
Merge pull request #45 from wednesday-solutions/patrol
Browse files Browse the repository at this point in the history
Patrol - E2E testing
  • Loading branch information
shounak-mulay authored Aug 25, 2023
2 parents 7d6617e + eb28a82 commit 8e273c4
Show file tree
Hide file tree
Showing 21 changed files with 1,341 additions and 151 deletions.
5 changes: 5 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Description

## Ticket Link -

## Screenshot / GIF
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ jobs:
- name: Golden tests
run: derry test goldens -- --merge-coverage --coverage

- uses: actions/upload-artifact@v3
if: failure()
with:
name: my-artifact
path: test/presentation/goldens/**/failures/*.png

- uses: actions/upload-artifact@v3
with:
name: coverage-${{ github.event.number }}
Expand Down
8 changes: 8 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ android {
targetSdkVersion project.properties['flutter.targetSdkVersion'].toInteger()
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner"
}

testOptions {
execution "ANDROIDX_TEST_ORCHESTRATOR"
}

flavorDimensions "flavors"
Expand Down Expand Up @@ -108,4 +114,6 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

implementation 'androidx.core:core-splashscreen:1.0.0-beta01'

androidTestUtil "androidx.test:orchestrator:1.4.2"
}
32 changes: 32 additions & 0 deletions android/app/src/androidTest/java/MainActivityTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import androidx.test.platform.app.InstrumentationRegistry;

import com.example.flutter_template.MainActivity;

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(Parameterized.class)
public class MainActivityTest {
@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);
}
}
28 changes: 28 additions & 0 deletions integration_test/app_setup.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_template/app.dart';
import 'package:flutter_template/flavors/flavor_config.dart';
import 'package:flutter_template/presentation/intl/translations/translation_loader.dart';
import 'package:flutter_template/presentation/template_app.dart';
import 'package:patrol/patrol.dart';

Future setupApp(PatrolIntegrationTester patrol) async {
await dotenv.load(
fileName: ".env.qa",
);

FlavorConfig.initialize(flavorString: "qa");

await initialiseApp();

await patrol.pumpWidgetAndSettle(
EasyLocalization(
supportedLocales: const [Locale("en", "US"), Locale("hi", "IN")],
path: "assets/translations",
fallbackLocale: const Locale("en", "US"),
assetLoader: const CodegenLoader(),
child: TemplateApp(),
),
);
}
47 changes: 47 additions & 0 deletions integration_test/favorites_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

import 'app_setup.dart';
import 'test_actions.dart';

void main() {
patrolTest(
'user can search cities and add or remove them from favorites',
// ignore: deprecated_member_use
nativeAutomation: true,
(patrol) async {
await setupApp(patrol);

await _navigateSearchForBengaluruAndMarkFavorite(patrol);
await patrol.tap(find.byIcon(Icons.arrow_back));
expect(find.text("Bengaluru, IN"), findsOneWidget);
await _navigateSearchForBengaluruAndMarkFavorite(
patrol,
alreadySelected: true,
);
await patrol.tap(find.byIcon(Icons.arrow_back));
expect(find.text("Bengaluru, IN"), findsNothing);
},
);
}

Future _navigateSearchForBengaluruAndMarkFavorite(
PatrolIntegrationTester patrol, {
bool alreadySelected = false,
}) async {
await navigateToSearch(patrol);
await patrol.enterText(find.byType(TextField), "Bengaluru",
settlePolicy: SettlePolicy.settle);
if (alreadySelected) {
await patrol.tap(
find.byIcon(Icons.favorite),
settlePolicy: SettlePolicy.settle,
);
} else {
await patrol.tap(
find.byIcon(Icons.favorite_outline),
settlePolicy: SettlePolicy.settle,
);
}
}
41 changes: 41 additions & 0 deletions integration_test/language_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_template/presentation/intl/translations/translation_keys.dart';
import 'package:flutter_template/presentation/intl/translations/translation_loader.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

import 'app_setup.dart';
import 'test_actions.dart';

void main() {
patrolTest(
"users are able to change the language of the app",
// ignore: deprecated_member_use
nativeAutomation: true,
(patrol) async {
await setupApp(patrol);

expect(find.text(CodegenLoader.en_US[LocaleKeys.homePageTitle]),
findsOneWidget);

await navigateToSearch(patrol);
expect(find.text(CodegenLoader.en_US[LocaleKeys.searchPageTitle]),
findsOneWidget);
expect(find.text(CodegenLoader.en_US[LocaleKeys.searchResultsAppearHere]),
findsOneWidget);

await patrol.tap(find.byIcon(Icons.arrow_back));

await patrol.tap(find.byIcon(Icons.language));

expect(find.text(CodegenLoader.hi_IN[LocaleKeys.homePageTitle]),
findsOneWidget);

await navigateToSearch(patrol);
expect(find.text(CodegenLoader.hi_IN[LocaleKeys.searchPageTitle]),
findsOneWidget);
expect(find.text(CodegenLoader.hi_IN[LocaleKeys.searchResultsAppearHere]),
findsOneWidget);
},
);
}
7 changes: 7 additions & 0 deletions integration_test/test_actions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';

Future navigateToSearch(PatrolIntegrationTester patrol) async {
await patrol.tap(find.byIcon(Icons.search));
}
81 changes: 81 additions & 0 deletions integration_test/test_bundle.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ target 'Runner' do
use_modular_headers!

flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))

target 'RunnerUITests' do
inherit! :complete
end
end

post_install do |installer|
Expand Down
Loading

0 comments on commit 8e273c4

Please sign in to comment.