diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 705508f..505ceea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,10 @@ on: jobs: set-up: runs-on: ubuntu-latest + permissions: + actions: write steps: - - name: Cancel + - name: Cancel Previous Runs uses: styfle/cancel-workflow-action@0.12.1 with: access_token: ${{ github.token }} @@ -22,9 +24,9 @@ jobs: timeout-minutes: 60 strategy: matrix: - ios-version: [16,17] + ios-version: [17] fail-fast: false - runs-on: macos-13 + runs-on: macos-14 steps: - name: Check out uses: actions/checkout@v4 @@ -38,15 +40,104 @@ jobs: - name: Boot ios simulator uses: futureware-tech/simulator-action@v3 with: - model: iPhone 14 Pro Max + os: iOS + model: 'iPhone 15' os_version: ^${{ matrix.ios-version }} - - name: Build example + - name: Run Integration Tests timeout-minutes: 20 run: | cd example - flutter build ios --no-codesign + flutter test integration_test/integration_test.dart + + + android: + needs: set-up + timeout-minutes: 60 + runs-on: macos-13 + strategy: + matrix: + # Api 33 is [currently not available on the macos-13 runner](https://github.com/ReactiveCircus/android-emulator-runner/issues/340) + api-level: [34,32,31,30,29,28,27,26,25,24,23] + fail-fast: false + steps: + - name: Check out + uses: actions/checkout@v4 + + - name: Setup Flutter SDK + uses: subosito/flutter-action@v2 + with: + channel: beta + + - name: Install Flutter dependencies + run: flutter pub get ./example + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + + - name: Cache Gradle + uses: actions/cache@v4 + with: + path: ~/.gradle/caches + key: gradle + + - name: Cache AVD + uses: actions/cache@v4 + id: cache-avd + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ matrix.api-level }} + + - name: Run Integration Tests + id: Run-Integration-Tests + continue-on-error: true + timeout-minutes: 20 + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + working-directory: ./example + arch: x86_64 + emulator-boot-timeout: 200 + disable-spellchecker: true + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none + script: flutter test integration_test/integration_test.dart - #TODO: Integration tests + - name: Retry Integration Tests + id: Retry-Integration-Tests + if: steps.Run-Integration-Tests.outcome == 'failure' + continue-on-error: true + timeout-minutes: 20 + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + working-directory: ./example + arch: x86_64 + emulator-boot-timeout: 200 + disable-spellchecker: true + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none + script: | + flutter clean && flutter pub get + flutter test integration_test/integration_test.dart - #TODO: Android \ No newline at end of file + - name: Re:Retry Integration Tests + if: steps.Retry-integration-tests.outcome == 'failure' + timeout-minutes: 20 + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + working-directory: ./example + arch: x86_64 + emulator-boot-timeout: 200 + disable-spellchecker: true + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none + script: | + flutter clean && flutter pub get + flutter test integration_test/integration_test.dart \ No newline at end of file diff --git a/example/integration_test/integration_test.dart b/example/integration_test/integration_test.dart new file mode 100644 index 0000000..b950b26 --- /dev/null +++ b/example/integration_test/integration_test.dart @@ -0,0 +1,23 @@ +import 'dart:io' show Platform; + +import 'package:compassx_example/main.dart'; +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Test', (tester) async { + await tester.pumpWidget(const App()); + + /// Wait while data is being acquired and the + /// [CircularProgressIndicator] is displayed. + await tester.pumpAndSettle(); + + /// Ensure that the Android SDK 23 and lower emulators and the iOS + /// simulator do not have a heading sensor, so that an Exception is Throw. + final hasSensor = Platform.isAndroid && + (await DeviceInfoPlugin().androidInfo).version.sdkInt > 23; + hasSensor + ? expect(find.textContaining('Heading'), findsOneWidget) + : expect(find.textContaining('CompassXException'), findsOneWidget); + }); +} diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 9e6a8c4..3e9f6be 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2,12 +2,15 @@ PODS: - compassx (0.0.1): - Flutter - Flutter (1.0.0) - - permission_handler_apple (9.1.1): + - integration_test (0.0.1): + - Flutter + - permission_handler_apple (9.3.0): - Flutter DEPENDENCIES: - compassx (from `.symlinks/plugins/compassx/ios`) - Flutter (from `Flutter`) + - integration_test (from `.symlinks/plugins/integration_test/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) EXTERNAL SOURCES: @@ -15,14 +18,17 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/compassx/ios" Flutter: :path: Flutter + integration_test: + :path: ".symlinks/plugins/integration_test/ios" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" SPEC CHECKSUMS: compassx: 6abaa865a6241ed744ad53aec8d9241c6719ec60 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 + integration_test: 13825b8a9334a850581300559b8839134b124670 + permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048 -COCOAPODS: 1.14.2 +COCOAPODS: 1.15.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 0fae688..7d6d2d6 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -139,6 +139,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, B65040550A890F3C5201C442 /* [CP] Embed Pods Frameworks */, + FF05EE77FFD71AC4D683A00D /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -268,6 +269,23 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + FF05EE77FFD71AC4D683A00D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/example/pubspec.yaml b/example/pubspec.yaml index e3b8d81..2c866ea 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -16,5 +16,10 @@ dependencies: dev_dependencies: flutter_lints: ^3.0.1 + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + device_info_plus: ^10.0.1 flutter: uses-material-design: true