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: flutter integration tests #92

Merged
merged 66 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
978593d
Create login_page.dart
minikin Oct 27, 2023
9b35f05
feat: add constants , update login screen
minikin Oct 27, 2023
7e18228
feat: update app
minikin Oct 27, 2023
e6d4d8c
Merge branch 'main' into feature/poc-flutter-integration-tests
minikin Oct 27, 2023
63f0610
Update login_page.dart
minikin Oct 27, 2023
1e57c71
feat: add integration tests
minikin Oct 30, 2023
0e8882a
wip
minikin Oct 30, 2023
18bfa8f
Merge branch 'main' into feature/poc-flutter-integration-tests
minikin Oct 30, 2023
cc4c32e
Update FLUTTER_INTEGRATION_TEST.md
minikin Oct 31, 2023
74a2029
feat: add integration tests support for iOS
minikin Oct 31, 2023
a7daeea
feat: add CI job to run integration tests
minikin Nov 1, 2023
2104b86
Update app-integration-test.yml
minikin Nov 1, 2023
fc38c55
wip
minikin Nov 1, 2023
14677a4
Update melos.yaml
minikin Nov 1, 2023
c7f482a
Merge branch 'main' into feature/poc-flutter-integration-tests
minikin Nov 1, 2023
189e2ac
Update melos.yaml
minikin Nov 2, 2023
bf0d3a3
Update app-integration-test.yml
minikin Nov 2, 2023
b502501
Update app-integration-test.yml
minikin Nov 2, 2023
df809b3
Update app-integration-test.yml
minikin Nov 2, 2023
d2f5fda
feat: update project structure
minikin Nov 2, 2023
87b870d
Update app-integration-test.yml
minikin Nov 2, 2023
c2c2ea4
Update pubspec.yaml
minikin Nov 2, 2023
3508549
update flutter_web_integration_test
minikin Nov 2, 2023
5c2d035
Update flutter_web_integration_test.sh
minikin Nov 2, 2023
fa29364
Update flutter_web_integration_test.sh
minikin Nov 2, 2023
da31cc5
Update flutter_web_integration_test.sh
minikin Nov 2, 2023
4bf16b3
wip
minikin Nov 2, 2023
1fdb403
wip
minikin Nov 2, 2023
37f0d98
Update app-integration-test.yml
minikin Nov 2, 2023
45e88f7
Update app-integration-test.yml
minikin Nov 2, 2023
e328e55
wip
minikin Nov 2, 2023
a9d12da
Update flutter_web_integration_test.sh
minikin Nov 2, 2023
fddcfd1
Update flutter_web_integration_test.sh
minikin Nov 2, 2023
441a9dc
Update flutter_web_integration_test.sh
minikin Nov 2, 2023
ff4e876
clean up
minikin Nov 2, 2023
c1c7d03
Update project.dic
minikin Nov 2, 2023
16673a2
Update project.dic
minikin Nov 2, 2023
0b4ad59
Update project.dic
minikin Nov 2, 2023
35a038f
Update project.dic
minikin Nov 2, 2023
74d9aee
more clean up
minikin Nov 2, 2023
b9ae4da
Update dummy.dart
minikin Nov 2, 2023
b28c13a
Update FLUTTER_INTEGRATION_TEST.md
minikin Nov 2, 2023
ca2125f
update docs
minikin Nov 2, 2023
6017081
Update FLUTTER_INTEGRATION_TEST.md
minikin Nov 3, 2023
5426f89
feat: update android project
minikin Nov 3, 2023
a394024
feat: integration scripts for iOS and Android, docs update
minikin Nov 3, 2023
2ce9f7a
feat: add flutter integration test for Android
minikin Nov 6, 2023
475aeac
Merge branch 'main' into feature/poc-flutter-integration-tests
minikin Nov 6, 2023
5f74452
Update project.dic
minikin Nov 6, 2023
ee699b3
Update FLUTTER_INTEGRATION_TEST.md
minikin Nov 6, 2023
7ee721c
Update project.dic
minikin Nov 6, 2023
02cbffc
minor update
minikin Nov 7, 2023
f1f11a9
Update flitter-mobile-integration-test.yml
minikin Nov 7, 2023
7b2c811
Update flitter-mobile-integration-test.yml
minikin Nov 7, 2023
a288ede
Update flutter_android_integration_test.sh
minikin Nov 7, 2023
d94b439
wip: iOS build
minikin Nov 7, 2023
e0796f3
Update flutter_ios_integration_test.sh
minikin Nov 8, 2023
5b5ba03
Merge branch 'main' into feature/poc-flutter-integration-tests
minikin Nov 8, 2023
fd4cd7c
Update flutter_ios_integration_test.sh
minikin Nov 8, 2023
3d0d4cc
Merge branch 'main' into feature/poc-flutter-integration-tests
minikin Nov 8, 2023
5ca30eb
wip ios
minikin Nov 8, 2023
fbced85
update iOS project and tests
minikin Nov 8, 2023
d202643
update ios
minikin Nov 9, 2023
0fda99a
Update flutter_ios_integration_test.sh
minikin Nov 9, 2023
c0d11f7
Update flitter-mobile-integration-test.yml
minikin Nov 9, 2023
655d5d4
Merge branch 'main' into feature/poc-flutter-integration-tests
stevenj Nov 9, 2023
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
23 changes: 23 additions & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
aarch
addrr
adminer
androidx
appspot
asyncio
auditability
bluefireteam
BROTLI
cardano
CEST
cfbundle
chromedriver
chrono
ciphertext
COCOAPODS
codepoints
coti
cryptoxide
Expand All @@ -20,10 +26,14 @@ dotglob
drep
dreps
encryptor
gcloud
genhtml
gmtime
gradlew
ideascale
integ
Intellij
iphoneos
jetbrains
jorm
jormungandr
Expand All @@ -40,11 +50,16 @@ netkey
oneshot
openapi
opentelemetry
Pdart
permissionless
pg_isready
plpgsql
podfile
podhelper
preprod
projectcatalyst
psql
Ptarget
pubkey
pubspec
rapidoc
Expand All @@ -54,11 +69,19 @@ saibatizoku
seckey
slotno
stevenj
subosito
tacho
thiserror
timelike
Traceback
TXNZD
vitss
voteplan
voteplans
xcconfig
xcfilelist
xcodebuild
xctest
xctestrun
xcworkspace
yoroi
55 changes: 55 additions & 0 deletions .github/workflows/flitter-mobile-integration-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: 🧪 Flutter iOS and Android Integration Tests

permissions:
contents: read
id-token: write

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true

on:
schedule:
# Schedule to run at midnight UTC
- cron: "0 0 * * *"

jobs:
integration-tests:
name: Mobile - Integration Tests
runs-on: macos-latest
timeout-minutes: 30
steps:
- name: ⬇️ Checkout repository
uses: actions/checkout@v3

- name: ⤵️ Authenticate with Google Cloud Platform
uses: "google-github-actions/auth@v1"
with:
credentials_json: "${{ secrets.GOOGLE_CREDENTIALS_INTEGRATION_TESTS }}"

- name: ⚙️ Setup Google Cloud SDK
uses: google-github-actions/setup-gcloud@v1

- name: ⚙️ Setup Java
uses: actions/setup-java@v1
with:
java-version: "12.x"

- name: ⚙️ Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
cache: true

- name: ⚙️ Setup Melos
uses: bluefireteam/melos-action@v2

- name: ⚙️ Install dependencies for all packages
run: melos build:pub_get:all

- name: 🤖 Run Android Integration Tests
run: ./scripts/flutter_android_integration_test.sh

# TODO: https://github.com/input-output-hk/catalyst-voices/issues/135
# - name: 📱 Run iOS Integration Tests
# run: ./scripts/flutter_ios_integration_test.sh
46 changes: 46 additions & 0 deletions .github/workflows/flitter-web-integration-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: 🧪 Flutter Web Integration Tests

permissions:
contents: read
id-token: write

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true

on:
pull_request:
types:
- opened
- reopened
- synchronize
branches:
- "main"
paths-ignore:
- "**.md"
- "doc/**"
- ".vscode/"

jobs:
integration-tests:
name: Web - Integration Tests
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: ⬇️ Checkout repository
uses: actions/checkout@v3

- name: ⚙️ Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
cache: true

- name: ⚙️ Setup Melos
uses: bluefireteam/melos-action@v2

- name: ⚙️ Install dependencies for all packages
run: melos build:pub_get:all

- name: 🤖 Run Integration Tests
run: ./scripts/flutter_web_integration_test.sh
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ $RECYCLE.BIN/
!/.vscode/settings.recommended.json
!/.vscode/tasks.recommended.json

# Flutter/Dart/Pub
.dart_tool/
.packages
build/
pubspec.lock
.pub-cache/
.pub/
coverage/
.idea/

# Secrets
dev-catalyst-voice-9f78f27c6bc5.json

# Local only development artefacts can get installed here.
/local

Expand Down

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

1 change: 1 addition & 0 deletions catalyst_voices/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ include: package:catalyst_analysis/analysis_options.1.0.0.yaml
exclude:
- 'build/**'
- '**/*.g.dart'

linter:
rules:
public_member_api_docs: false
6 changes: 5 additions & 1 deletion catalyst_voices/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ android {
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

signingConfigs {
Expand All @@ -74,7 +75,7 @@ android {
}

flavorDimensions "default"
productFlavors {
productFlavors {
production {
dimension "default"
applicationIdSuffix ""
Expand Down Expand Up @@ -110,4 +111,7 @@ flutter {

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.projectcatalyst.catalyst_voices;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import org.junit.Rule;
import org.junit.runner.RunWith;

@RunWith(FlutterTestRunner.class)
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class, true, false);
}
5 changes: 5 additions & 0 deletions catalyst_voices/integration_test/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import './scenarios/login_scenario.dart' as login_scenario;

void main() {
login_scenario.main();
}
36 changes: 36 additions & 0 deletions catalyst_voices/integration_test/scenarios/login_scenario.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:catalyst_voices/main_development.dart' as app;
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import 'robots/login_robot.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
LoginRobot loginRobot;

group('Login', () {
testWidgets('shows error message when login information is missing',
(tester) async {
loginRobot = await _configure(tester);

await loginRobot.enterUsername('Not Valid');
await loginRobot.tapLoginButton();
await loginRobot.checkInvalidCredentialsMessageIsShown();
});

testWidgets('authenticates a user with an username and password',
(tester) async {
loginRobot = await _configure(tester);

await loginRobot.enterUsername('robot');
await loginRobot.enterPassword('1234');
await loginRobot.tapLoginButton();
});
});
}

Future<LoginRobot> _configure(WidgetTester tester) async {
app.main();
await tester.pumpAndSettle();
return LoginRobot(widgetTester: tester);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:catalyst_voices/dummy/constants.dart';
import 'package:flutter_test/flutter_test.dart';

final class LoginRobot {
final WidgetTester widgetTester;

const LoginRobot({
required this.widgetTester,
});

Future<void> checkInvalidCredentialsMessageIsShown() async {
final loginErrorSnackbar = find.byKey(WidgetKeys.loginErrorSnackbar);
expect(loginErrorSnackbar, findsOneWidget);
await widgetTester.pump();
}

Future<void> enterPassword(String password) async {
final passwordTextController =
find.byKey(WidgetKeys.passwordTextController);
expect(passwordTextController, findsOneWidget);
await widgetTester.enterText(passwordTextController, password);
await widgetTester.pump();
}

Future<void> enterUsername(String username) async {
final usernameTextController =
find.byKey(WidgetKeys.usernameTextController);
expect(usernameTextController, findsOneWidget);
await widgetTester.enterText(usernameTextController, username);
await widgetTester.pump();
}

Future<void> tapLoginButton() async {
final loginButton = find.byKey(WidgetKeys.loginButton);
expect(loginButton, findsOneWidget);
await widgetTester.tap(loginButton);
await widgetTester.pump();
}

void verifyLoginScreenIsShown() {
final loginScreen = find.byKey(WidgetKeys.loginScreen);
expect(loginScreen, findsOneWidget);
}
}
1 change: 1 addition & 0 deletions catalyst_voices/ios/Flutter/Debug.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
1 change: 1 addition & 0 deletions catalyst_voices/ios/Flutter/Release.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
46 changes: 46 additions & 0 deletions catalyst_voices/ios/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
platform :ios, '15.0'

ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end

File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
use_frameworks!
use_modular_headers!

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

target 'RunnerTests' do
inherit! :search_paths
end
end

post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
end
end
end
Loading
Loading