From d9d80c9e2d2525600bbe91a8cb6be5f9a11a08d3 Mon Sep 17 00:00:00 2001 From: Alexey Alter-Pesotskiy Date: Thu, 16 Jul 2026 16:00:07 +0100 Subject: [PATCH 1/5] ci(repo): mock firebase for e2e tests --- .github/workflows/e2e_test.yml | 18 ++-- .github/workflows/e2e_test_cron.yml | 18 ++-- .../firebase_core/lib/firebase_core.dart | 55 +++++++++++ .../e2e_stubs/firebase_core/pubspec.yaml | 7 ++ .../lib/firebase_crashlytics.dart | 32 +++++++ .../firebase_crashlytics/pubspec.yaml | 11 +++ .../lib/firebase_messaging.dart | 91 +++++++++++++++++++ .../e2e_stubs/firebase_messaging/pubspec.yaml | 7 ++ sample_app/pubspec_overrides.e2e.yaml | 12 +++ 9 files changed, 237 insertions(+), 14 deletions(-) create mode 100644 sample_app/e2e_stubs/firebase_core/lib/firebase_core.dart create mode 100644 sample_app/e2e_stubs/firebase_core/pubspec.yaml create mode 100644 sample_app/e2e_stubs/firebase_crashlytics/lib/firebase_crashlytics.dart create mode 100644 sample_app/e2e_stubs/firebase_crashlytics/pubspec.yaml create mode 100644 sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart create mode 100644 sample_app/e2e_stubs/firebase_messaging/pubspec.yaml create mode 100644 sample_app/pubspec_overrides.e2e.yaml diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml index 41e119955..6bab3f801 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/e2e_test.yml @@ -85,6 +85,17 @@ jobs: - uses: ./.github/actions/setup-ruby + - name: Use Firebase stubs + run: cp sample_app/pubspec_overrides.e2e.yaml sample_app/pubspec_overrides.yaml + + - name: Bootstrap + run: | + flutter precache --ios + flutter config --no-enable-swift-package-manager + flutter pub global activate melos + melos bootstrap + + # After Bootstrap so the cache keys hash the resolved pubspec.lock - uses: ./.github/actions/cache-cocoapods with: key-suffix: ${{ runner.os }} @@ -94,13 +105,6 @@ jobs: key-suffix: ${{ runner.os }} xcode-version: ${{ env.IOS_SIMULATOR_VERSION }} - - name: Bootstrap - run: | - flutter precache --ios - flutter config --no-enable-swift-package-manager - flutter pub global activate melos - melos bootstrap - - name: Launch Allure TestOps working-directory: sample_app/ios run: bundle exec fastlane allure_launch diff --git a/.github/workflows/e2e_test_cron.yml b/.github/workflows/e2e_test_cron.yml index 4ddd07b66..fb3c2a08f 100644 --- a/.github/workflows/e2e_test_cron.yml +++ b/.github/workflows/e2e_test_cron.yml @@ -111,6 +111,17 @@ jobs: version: ${{ matrix.ios }} device: ${{ matrix.device }} + - name: Use Firebase stubs + run: cp sample_app/pubspec_overrides.e2e.yaml sample_app/pubspec_overrides.yaml + + - name: Bootstrap + run: | + flutter precache --ios + flutter config --no-enable-swift-package-manager + flutter pub global activate melos + melos bootstrap + + # After Bootstrap so the cache keys hash the resolved pubspec.lock - uses: ./.github/actions/cache-cocoapods with: key-suffix: ${{ matrix.ios }} @@ -120,13 +131,6 @@ jobs: key-suffix: ${{ matrix.ios }} xcode-version: ${{ env.XCODE_VERSION }} - - name: Bootstrap - run: | - flutter precache --ios - flutter config --no-enable-swift-package-manager - flutter pub global activate melos - melos bootstrap - - name: Launch Allure TestOps working-directory: sample_app/ios run: bundle exec fastlane allure_launch cron:true diff --git a/sample_app/e2e_stubs/firebase_core/lib/firebase_core.dart b/sample_app/e2e_stubs/firebase_core/lib/firebase_core.dart new file mode 100644 index 000000000..bde97276a --- /dev/null +++ b/sample_app/e2e_stubs/firebase_core/lib/firebase_core.dart @@ -0,0 +1,55 @@ +/// No-op stand-in for `firebase_core`, swapped in via `pubspec_overrides.e2e.yaml`. +/// +/// Being a pure-Dart package (no `flutter.plugin` section), it removes the Firebase +/// pods / Gradle dependencies from e2e builds entirely: nothing is downloaded, +/// compiled, or initialized. Only the API surface used by `sample_app` is stubbed. +library; + +/// No-op replacement for the Firebase entry point. +class Firebase { + /// Does nothing and returns a dummy [FirebaseApp]. + static Future initializeApp({String? name, FirebaseOptions? options}) async => const FirebaseApp(); +} + +/// Inert replacement for a configured Firebase app. +class FirebaseApp { + /// Creates the inert app handle. + const FirebaseApp(); +} + +/// Plain data holder matching the real `FirebaseOptions` constructor, so the +/// FlutterFire-generated `firebase_options.dart` compiles unchanged. +class FirebaseOptions { + /// Mirrors the real constructor's signature; values are never read. + const FirebaseOptions({ + required this.apiKey, + required this.appId, + required this.messagingSenderId, + required this.projectId, + this.authDomain, + this.databaseURL, + this.storageBucket, + this.measurementId, + this.trackingId, + this.deepLinkURLScheme, + this.androidClientId, + this.iosClientId, + this.iosBundleId, + this.appGroupId, + }); + + /// See the real `firebase_core` for field semantics; all unused here. + final String apiKey, appId, messagingSenderId, projectId; + + /// Optional platform-specific fields accepted for constructor compatibility. + final String? authDomain, + databaseURL, + storageBucket, + measurementId, + trackingId, + deepLinkURLScheme, + androidClientId, + iosClientId, + iosBundleId, + appGroupId; +} diff --git a/sample_app/e2e_stubs/firebase_core/pubspec.yaml b/sample_app/e2e_stubs/firebase_core/pubspec.yaml new file mode 100644 index 000000000..856088105 --- /dev/null +++ b/sample_app/e2e_stubs/firebase_core/pubspec.yaml @@ -0,0 +1,7 @@ +name: firebase_core +description: No-op pure-Dart stand-in for firebase_core, swapped in by e2e builds to keep the native Firebase SDK out of the app. +version: 0.0.1 +publish_to: none + +environment: + sdk: ^3.0.0 diff --git a/sample_app/e2e_stubs/firebase_crashlytics/lib/firebase_crashlytics.dart b/sample_app/e2e_stubs/firebase_crashlytics/lib/firebase_crashlytics.dart new file mode 100644 index 000000000..b96f25a1c --- /dev/null +++ b/sample_app/e2e_stubs/firebase_crashlytics/lib/firebase_crashlytics.dart @@ -0,0 +1,32 @@ +/// No-op stand-in for `firebase_crashlytics`, swapped in via `pubspec_overrides.e2e.yaml`. +/// +/// See the `firebase_core` stub for the rationale. Only the API surface used by +/// `sample_app` is stubbed; every call silently does nothing. +library; + +import 'package:flutter/foundation.dart'; + +/// No-op replacement for the Crashlytics reporter. +class FirebaseCrashlytics { + FirebaseCrashlytics._(); + + /// The shared no-op instance. + static final FirebaseCrashlytics instance = FirebaseCrashlytics._(); + + /// Does nothing. The positional bool must match the real API's signature. + // ignore: avoid_positional_boolean_parameters + Future setCrashlyticsCollectionEnabled(bool enabled) async {} + + /// Does nothing. + Future recordError( + dynamic exception, + StackTrace? stack, { + dynamic reason, + Iterable information = const [], + bool? printDetails, + bool fatal = false, + }) async {} + + /// Does nothing. + Future recordFlutterFatalError(FlutterErrorDetails flutterErrorDetails) async {} +} diff --git a/sample_app/e2e_stubs/firebase_crashlytics/pubspec.yaml b/sample_app/e2e_stubs/firebase_crashlytics/pubspec.yaml new file mode 100644 index 000000000..bafb8ff01 --- /dev/null +++ b/sample_app/e2e_stubs/firebase_crashlytics/pubspec.yaml @@ -0,0 +1,11 @@ +name: firebase_crashlytics +description: No-op pure-Dart stand-in for firebase_crashlytics, swapped in by e2e builds to keep the native Firebase SDK out of the app. +version: 0.0.1 +publish_to: none + +environment: + sdk: ^3.0.0 + +dependencies: + flutter: + sdk: flutter diff --git a/sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart b/sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart new file mode 100644 index 000000000..9210d93d8 --- /dev/null +++ b/sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart @@ -0,0 +1,91 @@ +/// No-op stand-in for `firebase_messaging`, swapped in via `pubspec_overrides.e2e.yaml`. +/// +/// See the `firebase_core` stub for the rationale. Only the API surface used by +/// `sample_app` is stubbed: permission requests report denied, token getters +/// return null, and the message streams never emit. +library; + +/// Signature of the top-level FCM background handler. +typedef BackgroundMessageHandler = Future Function(RemoteMessage message); + +/// No-op replacement for the FCM entry point. +class FirebaseMessaging { + FirebaseMessaging._(); + + /// The shared no-op instance. + static final FirebaseMessaging instance = FirebaseMessaging._(); + + /// Never emits. + static Stream get onMessage => const Stream.empty(); + + /// Never emits. + static Stream get onMessageOpenedApp => const Stream.empty(); + + /// Does nothing; [handler] is never invoked. + static void onBackgroundMessage(BackgroundMessageHandler handler) {} + + /// Never emits. + Stream get onTokenRefresh => const Stream.empty(); + + /// Always resolves to null. + Future getToken({String? vapidKey}) async => null; + + /// Always resolves to null. + Future getAPNSToken() async => null; + + /// Always resolves to null. + Future getInitialMessage() async => null; + + /// Always reports [AuthorizationStatus.denied]. + Future requestPermission({ + bool alert = true, + bool announcement = false, + bool badge = true, + bool carPlay = false, + bool criticalAlert = false, + bool provisional = false, + bool providesAppNotificationSettings = false, + bool sound = true, + }) async => + const NotificationSettings(authorizationStatus: AuthorizationStatus.denied); + + /// Does nothing. + Future setForegroundNotificationPresentationOptions({ + bool alert = false, + bool badge = false, + bool sound = false, + }) async {} +} + +/// Mirrors the real enum values. +enum AuthorizationStatus { + /// Permission granted. + authorized, + + /// Permission denied — the stub's fixed answer. + denied, + + /// Permission not requested yet. + notDetermined, + + /// Provisional (quiet) permission. + provisional, +} + +/// Minimal result type for [FirebaseMessaging.requestPermission]. +class NotificationSettings { + /// Creates settings with the given [authorizationStatus]. + const NotificationSettings({required this.authorizationStatus}); + + /// The reported permission state. + final AuthorizationStatus authorizationStatus; +} + +/// Minimal FCM message: only [data] is read by `sample_app`. +class RemoteMessage { + /// Creates a message carrying [data]. + const RemoteMessage({this.data = const {}}); + + /// The message payload. + final Map data; +} diff --git a/sample_app/e2e_stubs/firebase_messaging/pubspec.yaml b/sample_app/e2e_stubs/firebase_messaging/pubspec.yaml new file mode 100644 index 000000000..63d1fe314 --- /dev/null +++ b/sample_app/e2e_stubs/firebase_messaging/pubspec.yaml @@ -0,0 +1,7 @@ +name: firebase_messaging +description: No-op pure-Dart stand-in for firebase_messaging, swapped in by e2e builds to keep the native Firebase SDK out of the app. +version: 0.0.1 +publish_to: none + +environment: + sdk: ^3.0.0 diff --git a/sample_app/pubspec_overrides.e2e.yaml b/sample_app/pubspec_overrides.e2e.yaml new file mode 100644 index 000000000..9137cc18f --- /dev/null +++ b/sample_app/pubspec_overrides.e2e.yaml @@ -0,0 +1,12 @@ +# Copied over pubspec_overrides.yaml by the e2e CI jobs BEFORE `melos bootstrap` +# (melos merges its own managed overrides into the existing file, preserving these +# entries). Swaps the Firebase plugins for the pure-Dart no-op stubs in +# e2e_stubs/ so no native Firebase SDK is downloaded, compiled, or +# initialized during e2e runs. +dependency_overrides: + firebase_core: + path: e2e_stubs/firebase_core + firebase_crashlytics: + path: e2e_stubs/firebase_crashlytics + firebase_messaging: + path: e2e_stubs/firebase_messaging From 373de712ad9f5231f714545971a7e30000ec1824 Mon Sep 17 00:00:00 2001 From: Alexey Alter-Pesotskiy Date: Thu, 16 Jul 2026 17:44:09 +0100 Subject: [PATCH 2/5] ci(e2e): add compilation-cache diagnostics (remarks + verbose dispatch input) --- .github/actions/cache-xcode-cas/action.yml | 2 + .github/workflows/e2e_test.yml | 110 ++++++++++----------- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/.github/actions/cache-xcode-cas/action.yml b/.github/actions/cache-xcode-cas/action.yml index 630e57906..6e3767ce2 100644 --- a/.github/actions/cache-xcode-cas/action.yml +++ b/.github/actions/cache-xcode-cas/action.yml @@ -14,6 +14,8 @@ runs: - shell: bash run: | echo "FLUTTER_XCODE_COMPILATION_CACHE_ENABLE_CACHING=YES" >> "$GITHUB_ENV" + # Emits per-file cache hit/miss remarks; only visible in verbose runs. + echo "FLUTTER_XCODE_COMPILATION_CACHE_ENABLE_DIAGNOSTIC_REMARKS=YES" >> "$GITHUB_ENV" echo "FLUTTER_XCODE_SWIFT_ENABLE_COMPILE_CACHE=YES" >> "$GITHUB_ENV" echo "FLUTTER_XCODE_CLANG_ENABLE_COMPILE_CACHE=YES" >> "$GITHUB_ENV" echo "FLUTTER_XCODE_COMPILATION_CACHE_CAS_PATH=$HOME/xcode-cas" >> "$GITHUB_ENV" diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml index 6bab3f801..c758915cb 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/e2e_test.yml @@ -17,60 +17,60 @@ env: GITHUB_PR_NUM: ${{ github.event.pull_request.number }} jobs: - android: - runs-on: ubuntu-latest - timeout-minutes: 40 - env: - ANDROID_API_LEVEL: "34" - steps: - - uses: actions/checkout@v6 - - - uses: ./.github/actions/setup-java - - - uses: ./.github/actions/cache-gradle - - - uses: ./.github/actions/setup-ruby - - - uses: ./.github/actions/setup-flutter - - - uses: ./.github/actions/enable-kvm - - - name: Bootstrap - run: | - flutter pub global activate melos - melos bootstrap - - - name: Launch Allure TestOps - working-directory: sample_app/android - run: bundle exec fastlane allure_launch - env: - GITHUB_EVENT: ${{ toJson(github.event) }} - - - name: Run e2e (Android emulator) - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ env.ANDROID_API_LEVEL }} - arch: x86_64 - profile: pixel_6 - script: cd sample_app/android && bundle exec fastlane run_e2e_test device:emulator-5554 - - - name: Upload Allure results - if: env.LAUNCH_ID != '' && (success() || failure()) - working-directory: sample_app/android - run: bundle exec fastlane allure_upload launch_id:$LAUNCH_ID - - - name: Allure TestOps Launch Removal - if: env.LAUNCH_ID != '' && cancelled() - working-directory: sample_app/android - run: bundle exec fastlane allure_launch_removal launch_id:$LAUNCH_ID - - - uses: actions/upload-artifact@v7 - if: failure() - with: - name: e2e-android-logs - path: | - sample_app/stream-chat-test-mock-server/logs - sample_app/build/e2e-test.log + # android: + # runs-on: ubuntu-latest + # timeout-minutes: 40 + # env: + # ANDROID_API_LEVEL: "34" + # steps: + # - uses: actions/checkout@v6 + + # - uses: ./.github/actions/setup-java + + # - uses: ./.github/actions/cache-gradle + + # - uses: ./.github/actions/setup-ruby + + # - uses: ./.github/actions/setup-flutter + + # - uses: ./.github/actions/enable-kvm + + # - name: Bootstrap + # run: | + # flutter pub global activate melos + # melos bootstrap + + # - name: Launch Allure TestOps + # working-directory: sample_app/android + # run: bundle exec fastlane allure_launch + # env: + # GITHUB_EVENT: ${{ toJson(github.event) }} + + # - name: Run e2e (Android emulator) + # uses: reactivecircus/android-emulator-runner@v2 + # with: + # api-level: ${{ env.ANDROID_API_LEVEL }} + # arch: x86_64 + # profile: pixel_6 + # script: cd sample_app/android && bundle exec fastlane run_e2e_test device:emulator-5554 + + # - name: Upload Allure results + # if: env.LAUNCH_ID != '' && (success() || failure()) + # working-directory: sample_app/android + # run: bundle exec fastlane allure_upload launch_id:$LAUNCH_ID + + # - name: Allure TestOps Launch Removal + # if: env.LAUNCH_ID != '' && cancelled() + # working-directory: sample_app/android + # run: bundle exec fastlane allure_launch_removal launch_id:$LAUNCH_ID + + # - uses: actions/upload-artifact@v7 + # if: failure() + # with: + # name: e2e-android-logs + # path: | + # sample_app/stream-chat-test-mock-server/logs + # sample_app/build/e2e-test.log ios: runs-on: macos-15 @@ -113,7 +113,7 @@ jobs: - name: Run e2e (iOS simulator) working-directory: sample_app/ios - run: bundle exec fastlane run_e2e_test platform:ios ios:"${{ env.IOS_SIMULATOR_VERSION }}" device:"${{ env.IOS_SIMULATOR_DEVICE }}" + run: bundle exec fastlane run_e2e_test platform:ios ios:"${{ env.IOS_SIMULATOR_VERSION }}" device:"${{ env.IOS_SIMULATOR_DEVICE }}" verbose:true - name: Upload Allure results if: env.LAUNCH_ID != '' && (success() || failure()) From 36b29c7dd520347c40f00365c67288f1d3865ad1 Mon Sep 17 00:00:00 2001 From: Alexey Alter-Pesotskiy Date: Thu, 16 Jul 2026 18:16:45 +0100 Subject: [PATCH 3/5] ci(e2e): remove xcode compilation cache (works, but ~no benefit on CI runners) --- .github/actions/cache-xcode-cas/action.yml | 27 ----- .github/workflows/e2e_test.yml | 115 ++++++++++----------- .github/workflows/e2e_test_cron.yml | 5 - 3 files changed, 55 insertions(+), 92 deletions(-) delete mode 100644 .github/actions/cache-xcode-cas/action.yml diff --git a/.github/actions/cache-xcode-cas/action.yml b/.github/actions/cache-xcode-cas/action.yml deleted file mode 100644 index 6e3767ce2..000000000 --- a/.github/actions/cache-xcode-cas/action.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: 'Cache Xcode CAS' -description: 'Persist Xcode compilation cache (LLVM CAS) across CI runs' -inputs: - key-suffix: - description: 'Cache key suffix (e.g. runner.os or iOS version from matrix)' - required: true - xcode-version: - description: 'Xcode version for the cache key' - required: false - default: '26.2' -runs: - using: "composite" - steps: - - shell: bash - run: | - echo "FLUTTER_XCODE_COMPILATION_CACHE_ENABLE_CACHING=YES" >> "$GITHUB_ENV" - # Emits per-file cache hit/miss remarks; only visible in verbose runs. - echo "FLUTTER_XCODE_COMPILATION_CACHE_ENABLE_DIAGNOSTIC_REMARKS=YES" >> "$GITHUB_ENV" - echo "FLUTTER_XCODE_SWIFT_ENABLE_COMPILE_CACHE=YES" >> "$GITHUB_ENV" - echo "FLUTTER_XCODE_CLANG_ENABLE_COMPILE_CACHE=YES" >> "$GITHUB_ENV" - echo "FLUTTER_XCODE_COMPILATION_CACHE_CAS_PATH=$HOME/xcode-cas" >> "$GITHUB_ENV" - mkdir -p "$HOME/xcode-cas" - - uses: actions/cache@v6 - with: - path: ~/xcode-cas - key: xcode-cas-${{ inputs.xcode-version }}-${{ inputs.key-suffix }}-${{ hashFiles('sample_app/pubspec.lock', 'sample_app/ios/Podfile', 'sample_app/ios/Runner.xcodeproj/project.pbxproj') }} - restore-keys: xcode-cas-${{ inputs.xcode-version }}-${{ inputs.key-suffix }}- diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml index c758915cb..c2c07e62e 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/e2e_test.yml @@ -17,60 +17,60 @@ env: GITHUB_PR_NUM: ${{ github.event.pull_request.number }} jobs: - # android: - # runs-on: ubuntu-latest - # timeout-minutes: 40 - # env: - # ANDROID_API_LEVEL: "34" - # steps: - # - uses: actions/checkout@v6 - - # - uses: ./.github/actions/setup-java - - # - uses: ./.github/actions/cache-gradle - - # - uses: ./.github/actions/setup-ruby - - # - uses: ./.github/actions/setup-flutter - - # - uses: ./.github/actions/enable-kvm - - # - name: Bootstrap - # run: | - # flutter pub global activate melos - # melos bootstrap - - # - name: Launch Allure TestOps - # working-directory: sample_app/android - # run: bundle exec fastlane allure_launch - # env: - # GITHUB_EVENT: ${{ toJson(github.event) }} - - # - name: Run e2e (Android emulator) - # uses: reactivecircus/android-emulator-runner@v2 - # with: - # api-level: ${{ env.ANDROID_API_LEVEL }} - # arch: x86_64 - # profile: pixel_6 - # script: cd sample_app/android && bundle exec fastlane run_e2e_test device:emulator-5554 - - # - name: Upload Allure results - # if: env.LAUNCH_ID != '' && (success() || failure()) - # working-directory: sample_app/android - # run: bundle exec fastlane allure_upload launch_id:$LAUNCH_ID - - # - name: Allure TestOps Launch Removal - # if: env.LAUNCH_ID != '' && cancelled() - # working-directory: sample_app/android - # run: bundle exec fastlane allure_launch_removal launch_id:$LAUNCH_ID - - # - uses: actions/upload-artifact@v7 - # if: failure() - # with: - # name: e2e-android-logs - # path: | - # sample_app/stream-chat-test-mock-server/logs - # sample_app/build/e2e-test.log + android: + runs-on: ubuntu-latest + timeout-minutes: 40 + env: + ANDROID_API_LEVEL: "34" + steps: + - uses: actions/checkout@v6 + + - uses: ./.github/actions/setup-java + + - uses: ./.github/actions/cache-gradle + + - uses: ./.github/actions/setup-ruby + + - uses: ./.github/actions/setup-flutter + + - uses: ./.github/actions/enable-kvm + + - name: Bootstrap + run: | + flutter pub global activate melos + melos bootstrap + + - name: Launch Allure TestOps + working-directory: sample_app/android + run: bundle exec fastlane allure_launch + env: + GITHUB_EVENT: ${{ toJson(github.event) }} + + - name: Run e2e (Android emulator) + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ env.ANDROID_API_LEVEL }} + arch: x86_64 + profile: pixel_6 + script: cd sample_app/android && bundle exec fastlane run_e2e_test device:emulator-5554 + + - name: Upload Allure results + if: env.LAUNCH_ID != '' && (success() || failure()) + working-directory: sample_app/android + run: bundle exec fastlane allure_upload launch_id:$LAUNCH_ID + + - name: Allure TestOps Launch Removal + if: env.LAUNCH_ID != '' && cancelled() + working-directory: sample_app/android + run: bundle exec fastlane allure_launch_removal launch_id:$LAUNCH_ID + + - uses: actions/upload-artifact@v7 + if: failure() + with: + name: e2e-android-logs + path: | + sample_app/stream-chat-test-mock-server/logs + sample_app/build/e2e-test.log ios: runs-on: macos-15 @@ -100,11 +100,6 @@ jobs: with: key-suffix: ${{ runner.os }} - - uses: ./.github/actions/cache-xcode-cas - with: - key-suffix: ${{ runner.os }} - xcode-version: ${{ env.IOS_SIMULATOR_VERSION }} - - name: Launch Allure TestOps working-directory: sample_app/ios run: bundle exec fastlane allure_launch @@ -113,7 +108,7 @@ jobs: - name: Run e2e (iOS simulator) working-directory: sample_app/ios - run: bundle exec fastlane run_e2e_test platform:ios ios:"${{ env.IOS_SIMULATOR_VERSION }}" device:"${{ env.IOS_SIMULATOR_DEVICE }}" verbose:true + run: bundle exec fastlane run_e2e_test platform:ios ios:"${{ env.IOS_SIMULATOR_VERSION }}" device:"${{ env.IOS_SIMULATOR_DEVICE }}" - name: Upload Allure results if: env.LAUNCH_ID != '' && (success() || failure()) diff --git a/.github/workflows/e2e_test_cron.yml b/.github/workflows/e2e_test_cron.yml index fb3c2a08f..ad2b6e6cf 100644 --- a/.github/workflows/e2e_test_cron.yml +++ b/.github/workflows/e2e_test_cron.yml @@ -126,11 +126,6 @@ jobs: with: key-suffix: ${{ matrix.ios }} - - uses: ./.github/actions/cache-xcode-cas - with: - key-suffix: ${{ matrix.ios }} - xcode-version: ${{ env.XCODE_VERSION }} - - name: Launch Allure TestOps working-directory: sample_app/ios run: bundle exec fastlane allure_launch cron:true From 325b53299ff35b87221003b08a9b18a8eb99c014 Mon Sep 17 00:00:00 2001 From: Alexey Alter-Pesotskiy Date: Thu, 16 Jul 2026 20:19:23 +0100 Subject: [PATCH 4/5] Fix format --- .../e2e_stubs/firebase_messaging/lib/firebase_messaging.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart b/sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart index 9210d93d8..f38097fd6 100644 --- a/sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart +++ b/sample_app/e2e_stubs/firebase_messaging/lib/firebase_messaging.dart @@ -46,8 +46,7 @@ class FirebaseMessaging { bool provisional = false, bool providesAppNotificationSettings = false, bool sound = true, - }) async => - const NotificationSettings(authorizationStatus: AuthorizationStatus.denied); + }) async => const NotificationSettings(authorizationStatus: AuthorizationStatus.denied); /// Does nothing. Future setForegroundNotificationPresentationOptions({ From 924f27e7b4af27c72637e77eb37df2ad8fd62c99 Mon Sep 17 00:00:00 2001 From: Alexey Alter-Pesotskiy Date: Fri, 17 Jul 2026 15:55:44 +0100 Subject: [PATCH 5/5] Rename e2e workflow --- .github/workflows/e2e_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml index c2c07e62e..a81421f7b 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/e2e_test.yml @@ -1,4 +1,4 @@ -name: e2e +name: E2E Tests on: workflow_dispatch: