Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5fd710f
test(e2e): add e2e_app, port native e2e suites, one app process per C…
testableapple Oct 23, 2026
0b8aa6d
chore(repo): ignore e2e mock server, Allure results and allurectl in …
testableapple Oct 23, 2026
b4979e4
test(repo): link every e2e test to its Allure TestOps case
testableapple Oct 23, 2026
b71afe2
Merge remote-tracking branch 'origin/master' into test/e2e-native-parity
testableapple Oct 23, 2026
b03e78e
test(repo): unmount the e2e app before resetting the client, verify c…
testableapple Oct 23, 2026
3bb8bd3
ci(repo): run PR e2e on API 36, use a preinstalled NDK, retry failed …
testableapple Oct 23, 2026
e7510b3
test(repo): retype into a field that ignored the text
testableapple Oct 23, 2026
1e75428
test(repo): keep the copied message id in the e2e app, bound the vid…
testableapple Oct 23, 2026
4b7a5fa
Merge branch 'master' into test/e2e-native-parity
testableapple Oct 23, 2026
8d9cef2
test(repo): scroll until a message is on screen, stop when the emulat…
testableapple Oct 23, 2026
0e4da80
ci(repo): give the e2e app's Gradle the sample app's memory settings
testableapple Oct 23, 2026
4a66a48
Bump timeout
testableapple Oct 24, 2026
ab90f31
test(repo): restart a dead emulator during the e2e run
testableapple Oct 24, 2026
c883599
test(repo): time-limit e2e runs so a dead emulator can't hang the job
testableapple Oct 24, 2026
87586b9
fix(repo): look up timeout through sh so the lane runs on Linux
testableapple Oct 24, 2026
d42a93a
ci(repo): split the e2e coverage nightly into 4 batches
testableapple Oct 25, 2026
8e73290
ci(repo): give the e2e runners memory headroom
testableapple Oct 25, 2026
b6acb2a
test(repo): retry the tap that opens the image gallery
testableapple Oct 25, 2026
d0d5fad
test(repo): assert the token date and signature policy (#3123)
xsahil03x Oct 27, 2026
bdf15fd
fix(ui): keep the footer of a sent message before a failed one (#3122)
xsahil03x Oct 27, 2026
9f02ab0
test(repo): address review comments on the e2e suite
testableapple Oct 27, 2026
f67eaf9
test(repo): use a unique text instead of clearing the clipboard
testableapple Oct 27, 2026
db1ef2a
ci(repo): run analyze for e2e_app-only changes
testableapple Oct 27, 2026
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
12 changes: 6 additions & 6 deletions .claude/skills/flutter-version-bump/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,9 @@ Flutter 3.47, showing how far apart the two are:

| Tool | error floor | warn floor | **verified matrix** | Set in |
|---|---|---|---|---|
| Gradle | 8.14.0 | 9.1.0 | **9.3.1** | `sample_app/android/gradle/wrapper/gradle-wrapper.properties` |
| AGP | 8.11.1 | 9.0.1 | **9.1.0** | `sample_app/android/settings.gradle` |
| Kotlin (KGP) | 2.2.20 | 2.3.20 | **2.4.0** | `sample_app/android/settings.gradle` |
| Gradle | 8.14.0 | 9.1.0 | **9.3.1** | `{sample_app,e2e_app}/android/gradle/wrapper/gradle-wrapper.properties` |
| AGP | 8.11.1 | 9.0.1 | **9.1.0** | `sample_app/android/settings.gradle`, `e2e_app/android/settings.gradle.kts` |
| Kotlin (KGP) | 2.2.20 | 2.3.20 | **2.4.0** | `sample_app/android/settings.gradle`, `e2e_app/android/settings.gradle.kts` |
| Java | — | — | **17** minimum | `.github/actions/setup-java` + `app/build.gradle` |

The matrix is internally constrained — "AGP 9.1.0 is the newest compatible with KGP 2.4.0; Gradle 9.3.1 is the
Expand All @@ -420,7 +420,8 @@ hardcoded numbers, so future releases carry the project forward automatically.
5-minute CI round trips per attempt. Only fall back to "unverifiable locally" if the toolchain is genuinely
missing.

Also check `sample_app/android/{app/build.gradle,build.gradle,gradle.properties}` for SDK floors. Precedent: 3.44
Also check `sample_app/android/{app/build.gradle,build.gradle,gradle.properties}` and their `e2e_app/android/*.kts`
counterparts for SDK floors. Precedent: 3.44
needed `compileSdk` floored at 36 via `Math.max(flutter.compileSdkVersion, 36)` in both the `:app` module and the
root `subprojects` block.

Expand Down Expand Up @@ -475,12 +476,11 @@ Version-carrying files, all of which must move together:
and carries **no** `flutter` constraint — do not add one)
- `packages/*/example/pubspec.yaml` × 5
- `sample_app/pubspec.yaml`
- `e2e_app/pubspec.yaml`
- `docs/docs_screenshots/pubspec.yaml`
- `.github/workflows/legacy_version_analyze.yml` — `env.flutter_version`. Set it to the **new floor** (never the
new stable): this job exists to prove the floor still analyses and tests clean.
Comment thread
testableapple marked this conversation as resolved.
Resolved

`sample_app/e2e_stubs/*/pubspec.yaml` pin `sdk: ^3.0.0` deliberately — they are throwaway stubs. Leave them.

### The floor raise activates dormant lints — budget for it

This is the step that surprises people. Raising the Dart constraint raises each package's **language version**,
Expand Down
6 changes: 4 additions & 2 deletions .github/actions/allure-launch/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: 'Allure Launch'
description: 'Create an Allure TestOps launch and expose its id'
inputs:
working-directory:
description: 'Platform fastlane directory to run the lane from'
description: 'Directory to run the fastlane lane from'
required: false
default: sample_app/android
default: e2e_app
outputs:
launch_id:
description: 'The created launch id; empty when the e2e check was not required'
Expand All @@ -13,6 +13,8 @@ runs:
using: "composite"
steps:
- uses: ./.github/actions/setup-ruby
with:
working-directory: ${{ inputs.working-directory }}

- name: Launch Allure TestOps
shell: bash
Expand Down
4 changes: 2 additions & 2 deletions .github/actions/setup-ios-runtime/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ runs:

- name: Install iOS runtime
shell: bash
working-directory: sample_app/ios
working-directory: e2e_app
run: bundle exec fastlane install_runtime ios:${{ inputs.version }}

- name: Cleanup iOS runtime install artifacts
shell: bash
run: |
sudo rm -rfv sample_app/*.dmg || true
sudo rm -rfv e2e_app/*.dmg || true
xcrun simctl list runtimes

- name: Create custom iOS simulator
Expand Down
7 changes: 6 additions & 1 deletion .github/actions/setup-ruby/action.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
name: 'Setup Ruby'
description: 'Install Ruby and Cache Gems'
inputs:
working-directory:
description: 'The directory holding the Gemfile to install'
required: false
default: sample_app
runs:
using: "composite"
steps:
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
bundler-cache: true
working-directory: sample_app
working-directory: ${{ inputs.working-directory }}
53 changes: 28 additions & 25 deletions .github/workflows/e2e_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,18 @@ jobs:
fetch-depth: 2 # the pull request merge commit and its base

- uses: ./.github/actions/setup-ruby
with:
working-directory: e2e_app

- name: Select e2e tests
id: select
working-directory: sample_app/android
working-directory: e2e_app
run: bundle exec fastlane select_e2e_tests

- uses: actions/upload-artifact@v7
with:
name: e2e-selection
path: sample_app/build/e2e_selection.json
path: e2e_app/build/e2e_selection.json

allure_launch_android:
needs: select
Expand All @@ -65,7 +67,7 @@ jobs:
- uses: ./.github/actions/allure-launch
id: launch
with:
working-directory: sample_app/android
working-directory: e2e_app

allure_launch_ios:
needs: select
Expand All @@ -80,7 +82,7 @@ jobs:
- uses: ./.github/actions/allure-launch
id: launch
with:
working-directory: sample_app/ios
working-directory: e2e_app

android:
# Always on pull_request; opt-out via the checkbox on workflow_dispatch.
Expand All @@ -93,7 +95,7 @@ jobs:
matrix:
batch: ${{ fromJson(needs.select.outputs.e2e_batches) }}
env:
ANDROID_API_LEVEL: "34"
ANDROID_API_LEVEL: "36"
LAUNCH_ID: ${{ needs.allure_launch_android.outputs.launch_id }}
steps:
- uses: actions/checkout@v7
Expand All @@ -103,14 +105,13 @@ jobs:
- uses: ./.github/actions/cache-gradle

- uses: ./.github/actions/setup-ruby
with:
working-directory: e2e_app

- uses: ./.github/actions/setup-flutter

- uses: ./.github/actions/enable-kvm

- name: Use Firebase stubs
run: cp sample_app/pubspec_overrides.e2e.yaml sample_app/pubspec_overrides.yaml

- name: Bootstrap
run: |
flutter pub global activate melos
Expand All @@ -119,40 +120,43 @@ jobs:
- uses: actions/download-artifact@v8
with:
name: e2e-selection
path: sample_app/build
path: e2e_app/build

- 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 selection:build/e2e_selection.json batch:${{ matrix.batch }} batch_count:${{ strategy.job-total }}
script: cd e2e_app && bundle exec fastlane run_e2e_test device:emulator-5554 selection:build/e2e_selection.json batch:${{ matrix.batch }} batch_count:${{ strategy.job-total }}

- name: Attach videos to failed tests
if: failure()
working-directory: sample_app/android
# Videos only help debugging: a slow apt mirror (19 min once) must not hold the job.
timeout-minutes: 5
continue-on-error: true
working-directory: e2e_app
run: |
sudo apt-get update && sudo apt-get install -y ffmpeg
sudo apt-get update && sudo apt-get install -y --no-install-recommends ffmpeg
bundle exec fastlane attach_videos

- name: Upload Allure results
if: env.LAUNCH_ID != '' && (success() || failure())
working-directory: sample_app/android
working-directory: e2e_app
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
working-directory: e2e_app
run: bundle exec fastlane allure_launch_removal launch_id:$LAUNCH_ID

- uses: actions/upload-artifact@v7
if: failure()
with:
name: e2e-android-logs-${{ matrix.batch }}
path: |
sample_app/stream-chat-test-mock-server/logs
sample_app/build/e2e-test.log
e2e_app/stream-chat-test-mock-server/logs
e2e_app/build/e2e-test.log

ios:
# Only on workflow_dispatch, when the checkbox is ticked.
Expand All @@ -179,9 +183,8 @@ jobs:
- uses: ./.github/actions/setup-flutter

- uses: ./.github/actions/setup-ruby

- name: Use Firebase stubs
run: cp sample_app/pubspec_overrides.e2e.yaml sample_app/pubspec_overrides.yaml
with:
working-directory: e2e_app

- name: Bootstrap
run: |
Expand All @@ -192,29 +195,29 @@ jobs:
- uses: actions/download-artifact@v8
with:
name: e2e-selection
path: sample_app/build
path: e2e_app/build

- name: Run e2e (iOS simulator)
working-directory: sample_app/ios
working-directory: e2e_app
run: bundle exec fastlane run_e2e_test platform:ios ios:"${{ env.IOS_SIMULATOR_VERSION }}" device:"${{ env.IOS_SIMULATOR_DEVICE }}" selection:build/e2e_selection.json batch:${{ matrix.batch }} batch_count:${{ strategy.job-total }}

- name: Upload Allure results
if: env.LAUNCH_ID != '' && (success() || failure())
working-directory: sample_app/ios
working-directory: e2e_app
run: bundle exec fastlane allure_upload launch_id:$LAUNCH_ID

- name: Allure TestOps Launch Removal
if: env.LAUNCH_ID != '' && cancelled()
working-directory: sample_app/ios
working-directory: e2e_app
run: bundle exec fastlane allure_launch_removal launch_id:$LAUNCH_ID

- uses: actions/upload-artifact@v7
if: failure()
with:
name: e2e-ios-logs-${{ matrix.batch }}
path: |
sample_app/stream-chat-test-mock-server/logs
sample_app/build/e2e-test.log
e2e_app/stream-chat-test-mock-server/logs
e2e_app/build/e2e-test.log

# The single required check for E2E: the batch count follows the selection, so
# the per-batch job names come and go.
Expand Down
Loading
Loading