Skip to content

chore: stabilize Maestro CI (Maestro 2.5.1, emulator headroom)#7311

Open
diegolmello wants to merge 27 commits into
developfrom
chore/maestro-ci-bundle
Open

chore: stabilize Maestro CI (Maestro 2.5.1, emulator headroom)#7311
diegolmello wants to merge 27 commits into
developfrom
chore/maestro-ci-bundle

Conversation

@diegolmello
Copy link
Copy Markdown
Member

@diegolmello diegolmello commented May 7, 2026

Proposed changes

CI infra follow-up #2 (commit 63db0eb)

  • Add a serial e2e-seed-android-avd job in build-pr.yml between e2e-hold and e2e-run-android. Every shard in the 14-job matrix was previously hitting actions/cache simultaneously and missing — nothing had been written yet — so every shard ran its own "Generate AVD snapshot for cache" step. The seed job restores or generates the AVD snapshot once, post-uploads, and then the matrix fans out — every shard's cache restore now hits. The repo is also at ~12.5 GB of caches (over the 10 GB cap), so the AVD entry was the LRU victim across runs; the seed job re-populates on each PR run regardless. The per-shard fallback step stays as defense in depth.

CI infra follow-up (commit 2066fbf)

  • Anchor the Open in App? dialog tap selector in .maestro/helpers/open-deeplink.yaml to text: '^Open$'. Unanchored Open matched both the iOS 26 alert title ("Open in 'Rocket.Chat Experimental'?") and the button; on cold-launch (shard 1) Maestro's index: 0 picked the title at (275, 485) pt instead of the button at ~(277, 573) pt, the dialog persisted, and all 4 flows chain-failed. Other shards launch the app via UI first so the dialog either doesn't appear or its hierarchy looks different — same regex happened to work. Anchoring kills the ambiguity.
  • Raise iOS Run Maestro Tests step timeout-minutes 30 → 45. Dropping nick-fields/retry removed the previous 2×30=60 min ceiling; shard 12 ran 35 min on run 26168373950 and was killed mid-flight. 45 min matches the slowest passing shard (~27 min) plus rerun headroom.
  • Raise Android AVD snapshot-generation step timeout-minutes 30 → 45. A cache miss after the 4 GB → 6 GB RAM bump pushed cold-boot + AVD recreate past the cap on shard 3. Once the cache repopulates, future runs hit cache and skip this step.

CI infra (Android & iOS)

  • Bump Maestro CLI 2.2.0 → 2.5.1. 2.5.0 switched from gRPC to dadb's direct ADB socket, eliminating the Broken pipe install failures that were the dominant Android shard flake source.
  • Drop the monkey warmup in run-maestro.sh (+ trailing sleep 6 / am force-stop) — it stressed system_server right before Maestro's driver install.
  • Add explicit AVD snapshot caching for shards 1–13: cache miss → cold boot to seed snapshot; cache hit → replay with -no-snapshot-save to prevent corruption. Keyboard AVD (shard 14) untouched.
  • Bump Android emulator RAM 4 GB → 6 GB on all android-emulator-runner steps.
  • Pre-launch disk cleanup via jlumbroso/free-disk-space@v1.3.1 (Android SDK preserved; ~6 GB freed).
  • Drop the nick-fields/retry wrapper on iOS Maestro shards and lower MAX_RERUN_ROUNDS in run-maestro.sh from 3 → 2. The compounded retry produced up to 8 reruns of each failing flow (outer max_attempts: 2 × inner 1 main + 3 rerun rounds), wasting ~20 min/job on deterministic failures and re-running every flow in the shard on outer retry. New ceiling per failing flow: 3 runs (1 main + 2 rerun rounds). Android already called the script directly and inherits the new default.
  • Expand artifact upload globs to include JUnit XMLs (maestro-report.xml, maestro-rerun-round-*.xml) and the full ~/.maestro/tests tree — previously only screenshots were captured.
  • Move iOS Maestro shards to macos-26 + Xcode 26.2.0 to match e2e-build-ios.yml. The artifact is built against the iOS 26 SDK; the prior macos-14 runner booted iOS 18.2, which surfaced a rocketchat://room?path= deeplink crash that does not reproduce on the build-matched runtime.

App: sidebar testID fix (unblocks shard 8 + ~12 other flows)
SidebarView wraps the ScrollView in a plain View carrying testID='sidebar-view'. On Android, ScrollView does not propagate testID to the native accessibility tree; a regular View does. Folded in from #7319.

App: profile rate-limit fix (shard 8, Android)
profile.yaml was making three consecutive users.updateOwnBasicInfo calls; the endpoint is rate-limited per user. Collapsed into one combined submit (name, username, nickname, bio, email) before tapping submit. The password-confirm sheet and ChangePasswordView path are preserved.

App: form keyboard scroll fix (shard 6, iOS)
FormContainer swaps KeyboardAvoidingView + ScrollView for KeyboardAwareScrollView from react-native-keyboard-controller (already a dep). KAS scrolls the focused TextInput above the keyboard on focus change, preventing Maestro 2.5.1's tapOn from landing on the QWERTY row instead of the target field.

App: iOS Save Password suppression at FormTextInput (shards 1 & 9, iOS)
iOS 26 surfaces a system Save Password? sheet asynchronously (0.5s–7s variable latency) after any secureTextEntry={true} field submit. It overlays the app and blocks XCUITest hit-testing, breaking shard 1 (change-password.yaml, 100% deterministic — 8/8 failures in run 26117774450 all show the sheet over rooms-list-view) and shard 9 (e2e-encryption.yaml). The earlier YAML-level dismiss (a one-shot runFlow when: visible: 'Securely store your password') missed the late-arriving variant of the sheet and required per-test discipline.

Researched alternatives (no clean sim/CLI/Maestro-config kill switch exists — confirmed by Detox #3761, Selenium #11426, Maestro #2089). iOS only engages Password AutoFill on secureTextEntry={true} fields; setting it to false declassifies the field at the OS level and suppresses the offering entirely. RegisterView already uses this same pattern at register-view-password.

Fix: in app/containers/TextInput/FormTextInput.tsx, when RUNNING_E2E_TESTS === 'true' on iOS, suppress the native secureTextEntry prop passed to the underlying TextInput. Visual masking and the show/hide eye icon stay driven by the original prop. One seam covers every password field that uses the shared input (LoginView, ChangePasswordView, E2EE views, RoomInfoEditView, etc.). Plaintext password rendering under E2E mirrors what RegisterView already does and is acceptable for test environments using throwaway credentials. The YAML dismiss block added in b04b5ab is reverted.

Deferred (tracked separately)

  • Shard 12 (room-last-message-thread-50-plus.yaml) — Maestro gesture injection exits RoomView mid-scroll; tracked as NATIVE-1128.
  • Shard 11 (jump-to-message.yaml) — pre-existing baseline failure; related regressions tracked as NATIVE-1125 (composer auto-focus) and [NATIVE-1126] (quoted message tap).

Issue(s)

NATIVE-1123

Related (deferred, not fixed here): NATIVE-1125 · [NATIVE-1126] · NATIVE-1128

How to test or reproduce

  1. Trigger the Build PR workflow on this branch and watch the 14 Android + 13 iOS Maestro shards.
  2. Confirm absence of Broken pipe, Monkey aborted, and Failed to install apk in shard logs.
  3. Shard 8 (Android): should progress past the sidebar-view step and complete profile edits + password change in a single submit.
  4. Shard 6 (iOS): helpers/create-account.yaml should complete with a clean email field (no leading t/tmobile character corruption).
  5. Shards 1 & 9 (iOS): change-password.yaml and e2e-encryption.yaml should complete on iOS 26 — no Save Password? sheet appears because every FormTextInput-backed password field is declassified under RUNNING_E2E_TESTS=true.
  6. Shard 11 (jump-to-message.yaml) is expected to remain red — pre-existing failure.

Screenshots

n/a

Types of changes

  • Bugfix (non-breaking change which fixes an issue) — sidebar testID, profile rate-limit, form keyboard scroll, iOS 26 Save Password suppression at FormTextInput
  • Improvement (non-breaking change which improves a current function) — CI stabilization

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable) — covered by the Maestro flows this PR unblocks
  • I have added necessary documentation (if applicable) — inline comments next to each pinned version
  • Any dependent changes have been merged and published in downstream modules

Further comments

The sidebar testID fix was originally opened as #7319 and folded here so CI stabilization and its dependency ship together (#7319 closed). Acceptance is measured over a 10-run window on develop after this lands; tracked separately.

Summary by CodeRabbit

  • Chores

    • Upgraded Maestro CLI to 2.5.1 for Android and iOS; improved emulator caching and increased emulator memory for Android.
    • Adjusted test workflow retry behavior and added pre-test app install to improve run reliability.
  • Tests

    • Consolidated profile edit flow into a single submit and added deterministic scrolling in message-thread tests to reduce flakiness.
  • Style

    • Minor Sidebar layout adjustment (no functional change).

Review Change Stack

Maestro 2.5.0 switched gRPC to dadb direct ADB socket — removes the
broken-pipe install class on the Android emulator. Drop the monkey
warmup that was stressing system_server right before driver install.
Broaden iOS retry to fire on any error, not just timeout.
Bump emulator RAM 4G→6G to keep system_server out of the meminfo-dump
timeout window, free ~6 GB pre-launch via jlumbroso/free-disk-space,
and split the default-profile path into a cache-miss snapshot warmup
plus a cache-hit replay (-no-snapshot-save) so we stop cold-booting
the AVD on every shard.
@diegolmello diegolmello temporarily deployed to approve_e2e_testing May 7, 2026 20:45 — with GitHub Actions Inactive
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR upgrades Maestro to 2.5.1 (Android/iOS), changes Android AVD caching and emulator RAM/options, replaces the Android monkey pre-test step with adb install -r, adjusts iOS retry behavior to error, batches profile test edits, and moves SidebarView's testID to an outer View.

Changes

Maestro Test Infrastructure Upgrade

Layer / File(s) Summary
Maestro Version & iOS retry changes
.github/workflows/maestro-android.yml, .github/workflows/maestro-ios.yml
MAESTRO_VERSION pinned to 2.5.1 (Android & iOS); iOS “Run Maestro Tests” retry changed from timeout to error.
Android Emulator & AVD Caching Strategy
.github/workflows/maestro-android.yml
Gates AVD cache to non-shard-14, boots pixel_7_pro on cache miss to generate a snapshot, increases emulator RAM to 6144M, and adds -no-snapshot-save for non-keyboard runs; shard-14 step also uses 6144M.
Test Execution Script & Maestro Tests
.github/scripts/run-maestro.sh, .maestro/tests/assorted/profile.yaml, .maestro/tests/room/room-last-message-thread-50-plus.yaml
Replaces Android monkey-launch/force-stop with adb install -r app-experimental-release.apk before Maestro; Maestro invocation unchanged; profile test batches multiple field edits into a single submit; room test replaces scrollUntilVisible with a deterministic repeat-scroll sequence.

Sidebar View Layout Change

Layer / File(s) Summary
Imports
app/views/SidebarView/index.tsx
Adds View to react-native imports.
Render
app/views/SidebarView/index.tsx
Wraps ScrollView in an outer View with testID='sidebar-view'; removes testID from ScrollView.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

type: chore

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main objective: upgrading Maestro to version 2.5.1 and increasing emulator memory for CI stability.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (4)
  • NATIVE-1125: Request failed with status code 401
  • NATIVE-1126: Request failed with status code 401
  • NATIVE-1123: Request failed with status code 401
  • EMULATOR-5554: Request failed with status code 401

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@diegolmello diegolmello temporarily deployed to experimental_android_build May 7, 2026 20:50 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to official_android_build May 7, 2026 20:50 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to official_ios_build May 7, 2026 20:50 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_ios_build May 7, 2026 20:50 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/maestro-android.yml (1)

41-48: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Shard 14 can poison the shared AVD cache, defeating the snapshot optimization for all other shards

The Cache Android AVD step has no if condition, so shard 14 participates in both cache restore and save under the same key (avd-${{ runner.os }}-api34).

On a cold run, all 14 shards race to save to that key (GitHub Actions is first-writer-wins). If shard 14 wins, the cache stores only Pixel_API_34_Keyboard.avd + Pixel_API_34_Keyboard.ini. On subsequent runs:

  1. Non-keyboard shards see steps.avd-cache.outputs.cache-hit == 'true'
  2. The "Generate AVD snapshot" step is skipped (its condition checks cache-hit != 'true')
  3. The test step runs with force-avd-creation: false — but the expected default-profile AVD is absent from the restored cache

The behavior of reactivecircus/android-emulator-runner when force-avd-creation: false and the named AVD doesn't exist is unspecified; it may silently cold-boot (losing the optimization) or fail outright. Either way, the caching strategy is silently broken.

🐛 Proposed fix — exclude shard 14 from AVD caching
      - name: Cache Android AVD
+       if: ${{ inputs.shard != '14' }}
        id: avd-cache
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd-${{ runner.os }}-api34
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/maestro-android.yml around lines 41 - 48, The "Cache
Android AVD" step (id: avd-cache, name: Cache Android AVD, key: avd-${{
runner.os }}-api34) must be excluded from shard 14 so it doesn't poison the
shared AVD cache; update the step to run only when the shard is not 14 (e.g. add
an if condition referencing your matrix/shard variable such as if: matrix.shard
!= 14) so shard 14 neither restores nor saves to the common key, leaving other
shards to generate and cache the full AVD snapshot correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/maestro-android.yml:
- Around line 24-33: The workflow currently uses the jlumbroso/free-disk-space
action with swap-storage: true while configuring the emulator's ram-size: 6144M,
which disables swap and leaves under ~800MB host memory — change either the
swap-storage or ram-size to avoid OOMs: set swap-storage: false to retain the
runner swapfile, or reduce ram-size to 5120M or 4608M so host+emulator fit in
physical RAM; update the keys swap-storage and ram-size in the action usage
(uses: jlumbroso/free-disk-space@...) and apply the same change to the other
occurrences noted (the other blocks referenced) so all workflow entries are
consistent.

In @.github/workflows/maestro-ios.yml:
- Around line 14-15: The comment incorrectly mentions the Android-specific
"dadb"/ADB change; update the comment text that currently references "dadb" and
ADB to an iOS-appropriate note explaining that iOS Maestro uses
idb/libimobiledevice (not ADB) and that the Android-specific CLI 2.5.0 change
does not apply to the iOS workflow; either remove the ADB-specific sentence or
replace it with a short iOS-focused explanation and keep or adjust the release
link as needed so the comment accurately reflects iOS tooling.

---

Outside diff comments:
In @.github/workflows/maestro-android.yml:
- Around line 41-48: The "Cache Android AVD" step (id: avd-cache, name: Cache
Android AVD, key: avd-${{ runner.os }}-api34) must be excluded from shard 14 so
it doesn't poison the shared AVD cache; update the step to run only when the
shard is not 14 (e.g. add an if condition referencing your matrix/shard variable
such as if: matrix.shard != 14) so shard 14 neither restores nor saves to the
common key, leaving other shards to generate and cache the full AVD snapshot
correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee299d9c-ce31-45fd-89b1-673983985558

📥 Commits

Reviewing files that changed from the base of the PR and between 8b70425 and 5ee7fad.

📒 Files selected for processing (3)
  • .github/scripts/run-maestro.sh
  • .github/workflows/maestro-android.yml
  • .github/workflows/maestro-ios.yml
💤 Files with no reviewable changes (1)
  • .github/scripts/run-maestro.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: E2E Build Android / android-build
  • GitHub Check: ESLint and Test / run-eslint-and-test

Comment thread .github/workflows/maestro-android.yml Outdated
Comment thread .github/workflows/maestro-ios.yml Outdated
@diegolmello diegolmello deployed to upload_official_android May 7, 2026 21:30 — with GitHub Actions Active
@diegolmello diegolmello temporarily deployed to upload_experimental_android May 7, 2026 21:31 — with GitHub Actions Inactive
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Android Build Available

Rocket.Chat 4.72.0.108814

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Android Build Available

Rocket.Chat Experimental 4.72.0.108813

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Android Build Available

Rocket.Chat Experimental 4.72.0.108813

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNTowuRjjHlDYUgXqroMl8epJWmBJOAe-7N_6W5JjAcJyBHu-MfbZDIilMfFnPJkwzs7kKMzme1NVFTUUxnE

@diegolmello diegolmello had a problem deploying to upload_official_ios May 7, 2026 21:43 — with GitHub Actions Failure
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

iOS Build Available

Rocket.Chat Experimental 4.72.0.108816

@diegolmello diegolmello temporarily deployed to approve_e2e_testing May 8, 2026 08:04 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_ios_build May 8, 2026 08:09 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to official_ios_build May 8, 2026 08:09 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to official_android_build May 8, 2026 08:09 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_android_build May 8, 2026 08:09 — with GitHub Actions Inactive
@diegolmello diegolmello had a problem deploying to upload_experimental_android May 8, 2026 08:46 — with GitHub Actions Error
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Android Build Available

Rocket.Chat Experimental 4.72.0.108821

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNQLTMEQOTK7Yu4n98ufM0ImDLGPoEI7tdqqt4_8PqA3XXsk_0JhIS1tJIiRPRZJU0Eh3mtvcPjDUgnnZ0rq

@diegolmello diegolmello had a problem deploying to upload_official_android May 8, 2026 08:50 — with GitHub Actions Error
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

iOS Build Available

Rocket.Chat Experimental 4.72.0.108822

The iOS / Android Maestro workflows only uploaded *.png under
~/.maestro/tests. JUnit XML (maestro-report.xml,
maestro-rerun-round-*.xml) and Maestro's per-flow command logs were
discarded, so a CI failure surfaced only as a screenshot of the final
state, not the failing step or step trace.

Expand the upload-artifact globs on both workflows to include the
JUnit reports (in CWD) and the full ~/.maestro/tests tree.
@diegolmello diegolmello temporarily deployed to approve_e2e_testing May 18, 2026 17:26 — with GitHub Actions Inactive
@diegolmello diegolmello had a problem deploying to official_android_build May 18, 2026 17:30 — with GitHub Actions Error
@diegolmello diegolmello temporarily deployed to experimental_ios_build May 18, 2026 17:30 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_android_build May 18, 2026 17:30 — with GitHub Actions Inactive
@diegolmello diegolmello had a problem deploying to upload_experimental_android May 18, 2026 18:14 — with GitHub Actions Error
@github-actions
Copy link
Copy Markdown

Android Build Available

Rocket.Chat Experimental 4.73.0.108897

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNQyVMMK24jWLqKjDSQbDcUPeEB59eFY-bwI026Z4GFx0R-mxiTEbW8_vyD9bH1qpzhKxu4IDbvmZrAmznqQ

@github-actions
Copy link
Copy Markdown

iOS Build Available

Rocket.Chat Experimental 4.73.0.108898

Align Maestro iOS shards with e2e-build-ios so the artifact built against
the iOS 26 SDK is executed on an iOS 26 simulator runtime instead of the
macos-14 default (iOS 18.2). Cross-SDK execution surfaced an app crash on
the rocketchat://room?path= deeplink that does not reproduce on the
build-matched runtime.
@github-actions
Copy link
Copy Markdown

Android Build Available

Rocket.Chat Experimental 4.73.0.108901

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNQh6VvsjtzzmOd639neI-31XPTf_K-vXjBDTxIoegbfx4lvuJgJc76CYXq6F7yi0j9eyBM2Es0Q7Dx1zmBV

@github-actions
Copy link
Copy Markdown

iOS Build Available

Rocket.Chat Experimental 4.73.0.108902

The macos-26 image does not ship an "iPhone 16 Pro" device; Boot Simulator
failed with "Invalid device: iPhone 16 Pro" and aborted the shard before
maestro could run. Enumerate the available simulator catalog and select the
highest-numbered iPhone N Pro present so the workflow survives image rotation.
@github-actions
Copy link
Copy Markdown

Android Build Available

Rocket.Chat Experimental 4.73.0.108903

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNRCm1NlseKQgNjvjM3kdMrjI-p4inK5gzeYjtz6PVaTi2JKubKu_S--cqzoqVzffFfTUgpR3gCLx2TeZo6x

@github-actions
Copy link
Copy Markdown

iOS Build Available

Rocket.Chat Experimental 4.73.0.108904

iOS 26 surfaces a system "Save Password?" prompt after successful native
form submission. It is presented as a modal sheet on top of the rooms list,
which blocks XCUITest hit-testing for elements underneath. Maestro's
`extendedWaitUntil id: rooms-list-view-sidebar, enabled: true` therefore
never resolves and shard 9 (e2e-encryption) times out on the macos-26 /
iOS 26 runners (reliably green on macos-14 / iOS 18.2).

Dismiss the prompt with "Not Now" if visible, gated on iOS, in both
`helpers/login.yaml` (catches the modal immediately after submit) and
`tests/e2ee/utils/navigate-to-e2ee-security.yaml` (catches it if the
e2ee saga delays the modal past the login wait). On platforms or runs
where the prompt does not appear, the `runFlow when` block is a no-op.
Conflict in .github/workflows/maestro-ios.yml: this branch's dynamic
'highest iPhone N Pro' picker supersedes develop's static SIM_NAME
table (the macos-26 picker handled shard 14 fine in run 26065155352).
iOS Maestro tests were running each failing flow up to 8 times:
nick-fields/retry max_attempts=2 multiplied by run-maestro.sh's
internal 1 main + 3 rerun rounds. Deterministic failures wasted
~20 min/job; the wrapper also re-ran every flow in the shard, not
just the failed one, since it had no flow-level state.

Drop the wrapper on iOS (Android never had it) and lower
MAX_RERUN_ROUNDS from 3 to 2 so the script-internal loop alone
gives at most 3 runs per failing flow.
…ord flow

The "Save Password?" system sheet that iOS 26 shows after a native password
form submission is the root cause of the change-password.yaml shard-1 flake
(8/8 failure screenshots in run 26117774450 show the same sheet overlaying
rooms-list-view).

Two gaps in b04b5ab covered only login.yaml:

1. The change-password submit (`change-password-view-set-new-password-button`)
   also surfaces the sheet. Nothing dismissed it there, so the subsequent
   `assertVisible: rooms-list-view` was blocked by the modal.
2. The sheet has variable latency on iOS 26 (~0.5s–7s observed). The
   pre-existing one-shot `runFlow when: visible:` in login.yaml fires
   immediately after rooms-list-view becomes visible and frequently misses
   a late-rendering sheet, so the next interactive assertion times out.

Consolidate the dismiss into a shared `helpers/dismiss-save-password.yaml`
that waits up to 8s for the sheet with `optional: true` (no-op on Android /
iOS 18), then taps Not Now with `optional: true`. Call it from login.yaml,
change-password.yaml (both after new-password submit and before the final
re-login assertion), and the existing e2ee navigate helper.
iOS 26 surfaces a system "Save Password?" sheet asynchronously (0.5s–7s
variable latency) after any secureTextEntry field submit. It overlays
the app and blocks XCUITest hit-testing, causing Maestro change-password
shard-1 to fail at rooms-list-view assertions 100% on macos-26 runners
(8/8 failures in run 26117774450 show the same sheet over rooms-list-view).

Research summary: iOS sim has no documented kill switch (confirmed by
Detox #3761, Selenium #11426, Maestro #2089). Maestro has no
auto-dismiss and no workspace-level onFlowStart hook (#2063). iOS only
engages Password AutoFill on `secureTextEntry={true}` fields, regardless
of `textContentType` value, except `oneTimeCode`. Setting
`secureTextEntry={false}` declassifies the field and suppresses the
offer entirely — the same trick `RegisterView` already uses at
`register-view-password`.

Apply this gating once at `FormTextInput.tsx` so every password field
that uses the shared input (LoginView, ChangePasswordView, E2EE views,
RoomInfoEditView, etc.) is covered. Visual mask + show/hide eye icon
stay driven by the original `secureTextEntry` prop; only the native
prop passed to the underlying TextInput is suppressed. Plaintext
password rendering under E2E mirrors what RegisterView already does
and is acceptable for test environments that use throwaway credentials.

Revert b04b5ab + the dismiss-save-password helper added earlier on this
branch — no longer needed since the prompt never surfaces in E2E builds.

Note: TwoFactor, JoinCode, ProfileView ActionSheets and the generic
ActionSheetContentWithInputAndSubmit use raw TextInput (not
FormTextInput) and are not covered by this fix. They are not currently
exercised by any failing iOS Maestro shard; same pattern can be applied
locally there if a flow lands that exercises them on iOS 26.
iOS classifies a field as a credential for Password AutoFill / Save
Password via any of three signals: secureTextEntry, textContentType in
{password, newPassword, ...}, or autoComplete in {password, password-new,
...}. The previous patch flipped only secureTextEntry, so iOS still
classified LoginView and E2EEnterYourPasswordView (both hardcode
textContentType='password' + autoComplete='password' on iOS) as
credential fields and surfaced the "Save Password?" sheet on iPhone 17
Pro / iOS 26 fresh sims in CI, blocking shard 9 (e2e-encryption.yaml).

Extend the FormTextInput-level suppression to override all three under
RUNNING_E2E_TESTS on iOS so the underlying TextInput presents as a
neutral text field to UIKit. Visual masking and the show/hide eye icon
still follow the original secureTextEntry prop.
iOS shard 1's open-deeplink helper used `text: Open` which is a regex
match. On iOS 26 cold-launch the alert title "Open in 'Rocket.Chat
Experimental'?" also matches `Open`, and Maestro's index:0 hits the
title bounds (~275, 485 pt) instead of the button (~277, 573 pt), so
the dialog stays up and every flow in shard 1 chain-fails. Other shards
launch the app via UI first so the dialog either does not appear or its
hierarchy looks different — same regex happens to work there. Anchor
the selector to `^Open$`.

iOS Run Maestro Tests step was capped at 30 min after we dropped the
nick-fields/retry wrapper (which gave 2x30=60 min). Shard 12 ran ~35
min and was killed mid-flight; raise to 45 to match the longest passing
shard plus rerun budget.

Android AVD snapshot generation step was capped at 30 min. A cache miss
after the 4G→6G RAM bump pushed cold-boot + recreate past that. Raise
to 45 so a one-time cache repopulate succeeds and future runs hit cache.
All 14 Android shards start in parallel and check actions/cache at the
same instant. Nothing has been written yet, so every shard misses and
runs its own "Generate AVD snapshot for cache" step — burning ~90s per
shard on a 6 GB emulator boot the matrix could have shared. The repo
is also at ~12.5 GB of caches (over the 10 GB cap), so the AVD cache
is the LRU victim and gets evicted before the next run anyway.

Add a single serial `e2e-seed-android-avd` job between `e2e-hold` and
`e2e-run-android`. It restores or generates the AVD snapshot once,
post-uploads, and then the matrix kicks off — so every shard's
`Cache Android AVD` step now hits. The existing per-shard fallback
stays as defense in depth for the (rare) eviction-between-jobs case.
…undle

# Conflicts:
#	.github/scripts/run-maestro.sh
…em intact

`echo -e` with double quotes interprets backslash escapes (`\n`, `\t`, `\\`, …)
in the interpolated value. The Official keystore password contains a backslash,
so the gradle.properties row was written with a mangled value — every signed
APK build then failed with the misleading
`KeystoreHelper: keystore password was incorrect`, when the real cause is
`UnrecoverableKeyException: failed to decrypt safe contents entry`.

The production composite at `.github/actions/build-android/action.yml`
single-quotes the same two lines and signs successfully against the same
repo-level secret. Match it.

Also latent on develop after #7320 — worth back-porting.
Resolved conflicts:
- .github/scripts/run-maestro.sh: accept develop's flattened APK name
  (app-release.apk) while keeping our monkey-warmup removal.
- .github/workflows/e2e-build-android.yml: accept develop's full
  single-quoting of KEY_ALIAS/KEY_PASSWORD/BugsnagAPIKey, consistent
  with our keystore-password fix.

Also refreshed the Experimental reference in .maestro/helpers/open-deeplink.yaml
now that Experimental has been sunset on develop.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant