diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic index 35ad3b30be5..a8925d9cff5 100644 --- a/.config/dictionaries/project.dic +++ b/.config/dictionaries/project.dic @@ -1,13 +1,19 @@ aarch addrr adminer +androidx +appspot asyncio auditability +bluefireteam BROTLI cardano CEST +cfbundle +chromedriver chrono ciphertext +COCOAPODS codepoints coti cryptoxide @@ -20,10 +26,14 @@ dotglob drep dreps encryptor +gcloud genhtml gmtime +gradlew ideascale +integ Intellij +iphoneos jetbrains jorm jormungandr @@ -40,11 +50,16 @@ netkey oneshot openapi opentelemetry +Pdart permissionless pg_isready plpgsql +podfile +podhelper preprod +projectcatalyst psql +Ptarget pubkey pubspec rapidoc @@ -54,11 +69,19 @@ saibatizoku seckey slotno stevenj +subosito tacho thiserror timelike Traceback +TXNZD vitss voteplan voteplans +xcconfig +xcfilelist +xcodebuild +xctest +xctestrun +xcworkspace yoroi \ No newline at end of file diff --git a/.github/workflows/flitter-mobile-integration-test.yml b/.github/workflows/flitter-mobile-integration-test.yml new file mode 100644 index 00000000000..f71053b0f51 --- /dev/null +++ b/.github/workflows/flitter-mobile-integration-test.yml @@ -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 diff --git a/.github/workflows/flitter-web-integration-test.yml b/.github/workflows/flitter-web-integration-test.yml new file mode 100644 index 00000000000..84fe46fe449 --- /dev/null +++ b/.github/workflows/flitter-web-integration-test.yml @@ -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 diff --git a/.gitignore b/.gitignore index cad209d511d..20c0589e266 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/catalyst_voices/.idea/runConfigurations/melos_run_build.xml b/catalyst_voices/.idea/runConfigurations/melos_run_build_pub_get_all.xml similarity index 70% rename from catalyst_voices/.idea/runConfigurations/melos_run_build.xml rename to catalyst_voices/.idea/runConfigurations/melos_run_build_pub_get_all.xml index 624cc70a1ba..0657f330f0a 100644 --- a/catalyst_voices/.idea/runConfigurations/melos_run_build.xml +++ b/catalyst_voices/.idea/runConfigurations/melos_run_build_pub_get_all.xml @@ -1,9 +1,9 @@ - + - \ No newline at end of file + diff --git a/catalyst_voices/pubspec.yaml b/catalyst_voices/pubspec.yaml index dc7e4faeded..859443fa2fd 100644 --- a/catalyst_voices/pubspec.yaml +++ b/catalyst_voices/pubspec.yaml @@ -22,7 +22,8 @@ dev_dependencies: path: ../catalyst_voices_packages/packages/catalyst_analysis flutter_test: sdk: flutter - melos: ^3.1.1 + integration_test: + sdk: flutter mocktail: ^1.0.1 flutter: diff --git a/catalyst_voices/test_driver/integration_test.dart b/catalyst_voices/test_driver/integration_test.dart new file mode 100644 index 00000000000..b38629cca97 --- /dev/null +++ b/catalyst_voices/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/catalyst_voices_packages/melos.yaml b/catalyst_voices_packages/melos.yaml deleted file mode 100644 index 232884c3796..00000000000 --- a/catalyst_voices_packages/melos.yaml +++ /dev/null @@ -1,46 +0,0 @@ -name: CatalystFlutter -repository: https://github.com/input-output-hk/catalyst-flutter - -packages: - - packages/* - - packages/*/* - - packages/*/*/* - -command: - version: - # Generate commit links in package changelogs. - linkToCommits: true - # Only allow versioning to happen on main branch. - # branch: main - # Additionally build a changelog at the root of the workspace. - workspaceChangelog: true - - bootstrap: - # It seems so that running "pub get" in parallel has some issues (like - # https://github.com/dart-lang/pub/issues/3404). Disabling this feature - # makes the CI much more stable. - runPubGetInParallel: false - -scripts: - lint:all: - run: melos run analyze && melos run format - description: Run all static analysis checks. - - analyze: - # We are setting the concurrency to 1 because a higher concurrency can crash - # the analysis server on low performance machines (like GitHub Actions). - run: | - melos exec -c 1 -- \ - dart analyze . --fatal-infos - description: | - Run `dart analyze` in all packages. - - Note: you can also rely on your IDEs Dart Analysis / Issues window. - qualitycheck: - run: | - melos run clean:deep && \ - melos clean && \ - melos bootstrap && \ - melos run lint:all && \ - melos run build:all && \ - melos run test:all - description: Run all targets generally expected in CI for a full local quality check. \ No newline at end of file diff --git a/docs/FLUTTER_INTEGRATION_TEST.md b/docs/FLUTTER_INTEGRATION_TEST.md new file mode 100644 index 00000000000..d8437aef977 --- /dev/null +++ b/docs/FLUTTER_INTEGRATION_TEST.md @@ -0,0 +1,137 @@ +# Flutter Integration Tests + +* [Flutter Integration Tests](#flutter-integration-tests) + * [Requirements](#requirements) + * [Run Integration Tests](#run-integration-tests) + * [CI](#ci) + * [View Integration Test Results](#view-integration-test-results) + * [Local](#local) + * [Web](#web) + * [iOS](#ios) + * [Run integration test in Xcode](#run-integration-test-in-xcode) + * [Run integration test from command line](#run-integration-test-from-command-line) + * [Android](#android) + * [Run integration test in Android Studio](#run-integration-test-in-android-studio) + * [Run integration test from command line](#run-integration-test-from-command-line-1) + * [Run integration test in Firebase Test Lab](#run-integration-test-in-firebase-test-lab) + * [Gcloud CLI](#gcloud-cli) + * [Links](#links) + +## Requirements + +* macOS 14.0 + (if you want to run iOS tests locally) +* Xcode: 14.2+ (required for iOS tests) +* Android Studio: Android Studio Electric Eel | 2022.1.1 + +* [gcloud CLI](https://cloud.google.com/sdk/gcloud) + +## Run Integration Tests + +### CI + +* We run integration test for Web on every PR using chromedriver. +* We use [FireBase Test Lab](https://firebase.google.com/docs/test-lab) to run integration tests on iOS and Android, +nightly.(It's expensive to run integration tests on iOS and Android on every PR) + +#### View Integration Test Results + +To view integration tests results for Web, iOS and Android, +navigate to [Firebase Test Lab](https://console.firebase.google.com/u/0/project/dev-catalyst-voice/testlab/histories) +and select the appropriate history. + +### Local + +#### Web + +Navigate to `catalyst_voices` and run: + +```sh +flutter drive --driver=test_driver/integration_test.dart \ +--target=integration_test/main.dart \ +--flavor development \ +-d chrome +``` + +#### iOS + +##### Run integration test in Xcode + +Navigate to `catalyst_voices` + +Build the integration test for iOS + +```sh +flutter build ios --config-only integration_test/main.dart --flavor development +``` + +Open iOS app in Xcode, select appropriate schema and run the integration test target `Product > Test` or `Cmd + U`. + +##### Run integration test from command line + +Navigate to `catalyst_voices` + +Start iOS Simulator or connect iOS device and run: + +```sh +flutter test integration_test/main.dart --flavor development +``` + +#### Android + +##### Run integration test in Android Studio + +Navigate to `catalyst_voices/android` start Android Emulator or connect Android device and run: + +```sh +./gradlew app:connectedAndroidTest -Ptarget=`pwd`/../integration_test/main.dart +``` + +>Note: To use --dart-define with gradlew you must base64 encode all parameters, +>and pass them to gradle in a comma separated list: + +```sh +./gradlew project:task -Pdart-defines="{base64(key=value)},[...]" +``` + +##### Run integration test from command line + +Navigate to `catalyst_voices` start Android Emulator or connect Android device and run: + +```sh +flutter test integration_test/main.dart --flavor development +``` + +### Run integration test in Firebase Test Lab + +Android: + +```sh +./scripts/flutter_android_integration_test.sh +``` + +iOS: + +```sh +./scripts/flutter_ios_integration_test.sh +``` + +## Gcloud CLI + +List available android devices: + +```sh +gcloud firebase test android models list +``` + +List available iOS devices: + +```sh +gcloud firebase test ios models list +``` + +## Links + +* [Flutter Integration Tests](https://flutter.dev/docs/testing/integration-tests) +* [Flutter Integration Tests GitHub](https://github.com/flutter/flutter/tree/main/packages/integration_test) +* [Running Flutter Driver tests with Web](https://github.com/flutter/flutter/wiki/Running-Flutter-Driver-tests-with-Web) +* [Web install scripts for CI for Flutter Web](https://github.com/flutter/web_installers/tree/master) +* [Integration Test Example](https://github.com/flutter/flutter/tree/main/packages/integration_test/example) diff --git a/catalyst_voices/melos.yaml b/melos.yaml similarity index 71% rename from catalyst_voices/melos.yaml rename to melos.yaml index 8bef8715688..fb25d866d40 100644 --- a/catalyst_voices/melos.yaml +++ b/melos.yaml @@ -1,26 +1,17 @@ name: catalyst_voices -repository: https://github.com/minikin/didactic-parakeet/ +repository: https://github.com/input-output-hk/catalyst-voices packages: - - lib/** - - packages/** - - 'tests/*' + - catalyst_voices/* + - catalyst_voices_packages/packages/* + - catalyst_voices_packages/packages/*/* + - catalyst_voices_packages/packages/*/*/* command: version: - # Generate commit links in package changelogs. linkToCommits: true - # Only allow versioning to happen on main branch. - # branch: main - # Additionally build a changelog at the root of the workspace. workspaceChangelog: true - bootstrap: - # It seems so that running "pub get" in parallel has some issues (like - # https://github.com/dart-lang/pub/issues/3404). Disabling this feature - # makes the CI much more stable. - runPubGetInParallel: false - scripts: lint: run: melos run analyze @@ -66,6 +57,8 @@ scripts: melos exec -- genhtml coverage/lcov.info --output-directory=coverage/ description: Generate coverage for the selected package. - build: - run: melos exec fvm flutter build - description: Build app. \ No newline at end of file + build:pub_get:all: + run: flutter pub get + exec: + concurrency: 6 + description: Install all dependencies \ No newline at end of file diff --git a/catalyst_voices_packages/melos_catalystflutter.iml b/melos_catalyst_voices.iml similarity index 100% rename from catalyst_voices_packages/melos_catalystflutter.iml rename to melos_catalyst_voices.iml diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 00000000000..3b3107207cc --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,7 @@ +name: catalyst_voices_workspace + +environment: + sdk: '>=3.1.5 <4.0.0' + +dev_dependencies: + melos: ^3.2.0 diff --git a/scripts/flutter_android_integration_test.sh b/scripts/flutter_android_integration_test.sh new file mode 100755 index 00000000000..072d5586539 --- /dev/null +++ b/scripts/flutter_android_integration_test.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e + +pushd catalyst_voices +flutter build apk integration_test/main.dart --profile --flavor development + +pushd android +./gradlew app:assembleAndroidTest +./gradlew app:assembleDebug -Ptarget=integration_test/main.dart +popd + +gcloud firebase test android run --type instrumentation \ + --app ../catalyst_voices/build/app/outputs/apk/development/debug/app-development-debug.apk \ + --test ../catalyst_voices/build/app/outputs/apk/androidTest/development/debug/app-development-debug-androidTest.apk \ + --device-ids=redfin \ + --os-version-ids=30 \ + --locales=en_GB \ + --orientations=portrait \ + --use-orchestrator \ + --timeout 15m \ + --results-bucket=gs://dev-catalyst-voice.appspot.com \ + --results-dir=integration_test_results/android/ diff --git a/scripts/flutter_ios_integration_test.sh b/scripts/flutter_ios_integration_test.sh new file mode 100755 index 00000000000..f3898c5f862 --- /dev/null +++ b/scripts/flutter_ios_integration_test.sh @@ -0,0 +1,40 @@ +#!/bin/bash +set -e + +output="../build/ios_integ" +product="build/ios_integ/Build/Products" + +pushd catalyst_voices +flutter build ios integration_test/main.dart --release --flavor development + +pushd ios +xcodebuild -workspace Runner.xcworkspace \ + -allowProvisioningUpdates \ + -scheme development \ + -xcconfig Flutter/Release.xcconfig \ + -configuration Release-development \ + -sdk iphoneos build-for-testing \ + -derivedDataPath $output +popd + +## Verify test build locally before pushing to google cloud. +# xcodebuild test-without-building \ +# -xctestrun "../catalyst_voices/build/ios_integ/Build/Products/development_iphoneos17.0-arm64.xctestrun" \ +# -destination id=00008120-001934493663C01E + +pushd $product +ls +zip -r "ios_tests.zip" "Release-development-iphoneos" "development_iphoneos17.0-arm64.xctestrun" +popd + +gcloud firebase test ios run \ + --test "../catalyst_voices/build/ios_integ/Build/Products/ios_tests.zip" \ + --device model=iphone14pro \ + --device version=16.6 \ + --device locale=en_GB \ + --device orientation=portrait \ + --timeout 15m \ + --results-bucket=gs://dev-catalyst-voice.appspot.com \ + --results-dir=integration_test_results/ios/ + + diff --git a/scripts/flutter_web_integration_test.sh b/scripts/flutter_web_integration_test.sh new file mode 100755 index 00000000000..c11abf0b70b --- /dev/null +++ b/scripts/flutter_web_integration_test.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e + +# Path to ChromeDriver in Ubuntu image in GitHub Workspace +/usr/local/share/chromedriver-linux64/chromedriver --port=4444 & +# Wait for 5 seconds to allow ChromeDriver to start +sleep 5 + +cd ./catalyst_voices + +flutter drive --driver=test_driver/integration_test.dart \ +--target=integration_test/main.dart \ +--flavor development \ +-d web-server \ +--profile --browser-name=chrome \ No newline at end of file