Skip to content

chore: stabilize Maestro CI#7311

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

chore: stabilize Maestro CI#7311
diegolmello wants to merge 80 commits into
developfrom
chore/maestro-ci-bundle

Conversation

@diegolmello

@diegolmello diegolmello commented May 7, 2026

Copy link
Copy Markdown
Member

Proposed changes

Stabilizes the Maestro E2E suite (CI infra + flaky-flow fixes) and folds in the app-code
fixes that unblock specific shards. The CI changes carry no app behavior change; the app
changes are listed first since they're what needs review.

App changes

  • Jump to message over DDP (NATIVE-1126) — sdk.ts appended the 2FA code as a trailing
    '' on every DDP call. Harmless until the server's loadSurroundingMessages grew a typed
    showThreadMessages: boolean 3rd param (RocketChat/Rocket.Chat#39092); the '' then fails
    check(…, Boolean) → 500 → the quoted-message jump never navigates. Fix: append the TOTP code
    only when a 2FA flow is in progress (matches the REST path), and clear it as soon as the retry
    consumes it — so a spent code never leaks into subsequent calls on the same connection. Non-2FA
    calls send exactly their declared params. Unit-tested (sdk.test.ts: no-2FA path, 2FA prompt +
    retry, non-leakage, cancellation).
  • Jump-to-message scroll race capRoomView raced the list scroll against a fixed 5s cap;
    off-screen targets on the slow CI emulator exceed it. Raised to 20s as an interim measure.
    The scroll-retry loop also now exits early when history stops loading: if the loaded-message
    count stays flat for 5 consecutive 600 ms rounds (~3 s), the target can't appear (deleted or
    unreachable message), so it resolves instead of holding the spinner for the full 20 s.
    Unit-tested (useScroll.test.ts). The proper O(1) anchored-window rework is not here — it
    ships separately under NATIVE-1224.
  • Quoted-reply accessibility — on iOS, a quoted reply's text is folded into the message's
    accessibility label so VoiceOver announces it (the nested <Markdown> is merged into the parent
    a11y element and never read on its own). On Android the suffix is omitted: TalkBack already
    enumerates the quote subtree, so appending it too would double-announce. Mirrors
    useImageDescriptionLabel; unit-tested on both platforms. Also unblocks the
    jump-to-message.yaml quote assertion.
  • Form keyboard handlingFormContainer swaps KeyboardAvoidingView + ScrollView for
    KeyboardAwareScrollView (react-native-keyboard-controller, already a dep). Affects the auth
    screens (Login, Register, ForgotPassword, SendEmailConfirmation, Workspace, NewServer) on both
    platforms — see How to test.
  • iOS Save Password suppression (E2E only) — iOS 26 surfaces an async system Save Password?
    sheet after credential-field submit that blocks XCUITest. Under RUNNING_E2E_TESTS=true on iOS,
    FormTextInput declassifies the field (drops secureTextEntry/textContentType/autoComplete).
    Production behavior is unchanged; mirrors what RegisterView already does.
  • Sidebar testIDSidebarView wraps the ScrollView in a View carrying testID; Android
    doesn't propagate testID from a ScrollView to the native tree. (Folded in from fix: restore sidebar-view testID visibility for Maestro #7319.)
CI / Maestro stabilization — infra only, no app behavior change

Versions & runners

  • Maestro 2.2.0 → 2.5.1 (both platforms); 2.5.0's dadb ADB socket kills the Android Broken pipe install flake.
  • iOS shards → macos-26 + Xcode 26.2.0 to match the iOS-26 build artifact.

Android caching / flake fixes

  • The AVD and SDK (emulator + system-image) caches are seeded once on develop and restored read-only by PR shards. A single writer means per-PR cache duplication no longer blows the 10 GB Actions cap and LRU-evicts the SDK cache; on a miss a shard cold-boots and installs on the fly.
  • Serialized, 3×-retried sdkmanager install (clears partial downloads) self-heals the Error on ZipFile unknown archive flake.
  • Emulator RAM 4 GB → 6 GB; dropped jlumbroso/free-disk-space (shards already start with ~89 GB free) and the monkey warmup.

iOS speed-ups

  • Dropped idb-companion (Maestro's iOS driver uses XCUITest since 1.18.0) — ~110s/shard.
  • Start the async simulator boot right after Configure Simulator (before Java / app download / E2E account / Maestro setup) so the cold boot overlaps that work; block later on bootstatus -b.
  • Trimmed Wait for Simulator Ready: dropped the redundant simctl launch booted com.apple.springboard + sleep 5 — SpringBoard is already up once bootstatus -b returns.
  • Fixed UIAnimationDragCoefficient: it is a duration multiplier, so the prior -float 10 made every UIKit / native-stack transition 10× slower (the opposite of the "disable animations" intent). Set 0.0001 so transitions are near-instant and Maestro never waits on them — the iOS analogue of Android's disable-animations.
  • The simulator device is resolved at runtime by family rather than a pinned name (image rotation renames devices): the small-screen shard runs the smallest iPhone (preferring an SE), the rest the largest iPhone N Pro. No match fails the shard loudly instead of silently falling back.

Both platforms

  • The Maestro install is cached once by each platform's e2e build job (the single writer) and restored read-only by every shard, so all shards get a deterministic cache hit — no per-shard install and no concurrent first-writer save race. The cache holds only the install dirs (bin/lib/deps), never run logs — so the server-flake log scan can't be fooled by a restored prior run. Shards keep a cache-miss install as a fallback.
  • Server preflight (/api/info before flows) + mid-run scan of Maestro logs → a server outage/blip renders as a single red job annotation instead of opaque [Failed] <flow>. If the server URL can't be scraped from the test config the job fails loudly (a CI-config error), rather than silently using a fallback.
  • A wedged maestro test is bounded in-script (timeout -k 30s 35m) and annotated as an environment failure, with a 40-min job backstop above it. This replaces the old whole-suite startup retry: a run that produces no report now goes red for a human to re-run, rather than auto-retrying and masking real startup breakage. Per-flow rerun rounds 3 → 2.
  • Uploaded Maestro logs are scrubbed of the &token=… session token the deeplink-login flow writes (the logs ship as a public artifact).
  • A shard-coverage preflight is the single source of the shard list both platforms fan out over: it asserts every flow under .maestro/tests is tagged within the declared range and every shard in the range has a flow, then emits the list as JSON for the matrices. A mistagged or orphaned flow fails fast instead of silently never running.
  • Shard 9 restored (it had been folded into 3); both matrices now run 14 shards from the preflight list.
  • Artifact globs expanded to JUnit XMLs + the full ~/.maestro/tests tree.

Flaky-flow fixes

  • open-deeplink: anchor the dialog tap to ^Open$ (unanchored Open matched the iOS 26 alert title).
  • profile: collapse 3 rate-limited users.updateOwnBasicInfo submits into one; hide-keyboard before clipped fields.
  • room-actions: scrollUntilVisible the Unstar item instead of asserting after one swipe.
  • search-room / discussion / create-team / login: more robust waits and testID/header-back selectors.

Known remaining flaky flows (tracked as follow-ups)

  • Jump to message (both platforms) — pending the O(1) anchored-window rework (NATIVE-1224); the 20s scroll cap here is interim.
  • Keyboard Navigation (Android) — components / room / onboarding don't reach the rooms list.
  • Room Actions (both platforms) — usually passes on rerun; occasionally fails outright on a member-list / writing-toggle step.
  • Ignore User (iOS) — fails its first attempt, passes on rerun.

Server / emulator-infra blips (workspace outages, adb socket loss) surface as a single red annotation, not app or test regressions.

Issue(s)

Fixes NATIVE-1123 · NATIVE-1126
Related (deferred, not fixed here): NATIVE-1125 · NATIVE-1128 · NATIVE-1224

How to test or reproduce

  1. Run the Build PR workflow; the 14 Android + 14 iOS Maestro shards should pass.
  2. Manual QA the auth screens (Login, Register, ForgotPassword, SendEmailConfirmation, Workspace,
    NewServer) on iOS and Android after the KeyboardAwareScrollView swap — focus each field with the
    keyboard open/closed and confirm no clipping or scroll regressions, on phone and tablet.
  3. Quoted-message Jump to message loads surroundings and scrolls to the target (NATIVE-1126).
  4. VoiceOver on a quoted reply (iOS) announces the quoted text; TalkBack (Android) reads it once, not twice.

Screenshots

n/a

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)

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 (a11y hook unit tests; CI flows cover the rest)
  • Any dependent changes have been merged and published in downstream modules

Further comments

The sidebar testID fix was originally #7319, 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.

@diegolmello diegolmello temporarily deployed to approve_e2e_testing May 7, 2026 20:45 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

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
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.
Title check ✅ Passed The title 'chore: stabilize Maestro CI' directly aligns with the main objective of improving Maestro-based test stability through Maestro version upgrades, emulator resource adjustments, and caching improvements.
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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

Android Build Available

Rocket.Chat 4.72.0.108814

@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

Android Build Available

Rocket.Chat Experimental 4.72.0.108813

@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

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

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

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

github-actions Bot commented May 8, 2026

Copy link
Copy Markdown

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

github-actions Bot commented May 8, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented May 8, 2026

Copy link
Copy Markdown

iOS Build Available

Rocket.Chat Experimental 4.72.0.108822

… shard

- maestro-ios.yml: start the simulator cold boot asynchronously before
  installing Maestro + idb so the ~3.5min cold boot overlaps the ~30s
  install, then block on bootstatus afterwards. Trim post-boot settle 15s -> 5s.
- Fold the lone shard-9 flow (e2e-encryption) into shard 3 and drop shard 9
  from both iOS and Android matrices, removing one cold boot per platform per run.
The android-emulator-runner action's internal 'Install Android SDK' step
re-downloads the emulator binary and the api-34 system image (~1 GB) from
dl.google.com on every one of the 13 parallel Maestro shards. Under that
concurrent load the download intermittently arrives corrupt/truncated and
sdkmanager dies with 'Error on ZipFile unknown archive', failing a random
shard before any test runs. The existing AVD cache only persists the AVD
instance (~/.android/avd), not the SDK packages.

Promote the e2e-seed-android-avd seed job to also seed the SDK packages:
- a separate read-write cache (key android-sdk-emu-<os>-api34) over the
  emulator + system-image dirs, and
- a single serialized, retried sdkmanager install (3x, clearing partial
  downloads between tries) that runs before the snapshot step, so a corrupt
  archive self-heals instead of failing the matrix.

Each Maestro shard restores that cache read-only (seed job is the single
writer), so android-emulator-runner's install becomes a no-op and the
per-shard dl.google.com download is eliminated.
#7311 carried the original cherry-pick base of the deeplink/orphan-socket
fix. The standalone PR #7380 refined it before merging to develop:
- guard the login gate against the connect-before-select race (METEOR.SUCCESS
  may fire before SERVER.SELECT_SUCCESS; the unconditional take would hang)
- added regression tests for that ordering + the call-push path
- clarified the SDK patch comments (FIX A primary/defense)

Bring app/sagas/deepLinking.js, its test, and the SDK patch in line with
develop's merged #7380 version so #7311 stops carrying a divergent copy.
The Android test shards start with ~89 GB free (/dev/root 145G, 39% used)
before anything runs; the emulator image + snapshot + downloaded APK use a
few GB against that. jlumbroso/free-disk-space cost ~62s on every shard to
free space nothing was competing for. The real emulator constraint is RAM,
which this action doesn't address (and swap-storage was already kept).

Removes ~1 min from the matrix critical path and ~13 runner-minutes/run.
Android shards each persisted a ~3 GB AVD snapshot under a shared key.
With multiple open PRs this pushed the repo past GitHub's 10 GB Actions
cache cap, LRU-evicting the SDK system-image cache before the shards
restored it. Evicted shards then cold-booted and re-downloaded the
system image in a single unretried sdkmanager call, intermittently
hitting "Error on ZipFile unknown archive" and failing the shard.

- AVD cache -> actions/cache/restore (restore-only). The seed job is the
  single writer, so shards no longer duplicate the 3 GB snapshot per PR;
  the footprint stays under the 10 GB cap and the SDK cache survives.
- Add a 3x-retried sdkmanager install (mirrors the seed job), gated on an
  SDK-cache miss and run before any emulator boot, so a corrupt download
  self-heals on both the default cold-boot path and shard 14.
The Unstar step swiped the action sheet up once and asserted 'Unstar' was
visible, while the symmetric Star step uses scrollUntilVisible. When a single
swipe didn't fully expand the sheet, 'Unstar' stayed below the fold and the
shard failed with "Assertion is false: 'Unstar' is visible". Mirror the Star
step so the sheet is scrolled until the item is on screen.
Flows are driven by REST calls (login, users.create, …) that data-setup.js
makes to the test server. When the server is down or blips, a flow fails deep
inside an evalScript as an opaque "[Failed] <flow>" with no reason in the job
log — diagnosing it meant downloading the Maestro artifact and reading
maestro.log. Two shell-level signals (run-maestro.sh stdout is the job console,
so these render as GitHub annotations without opening logs):

- Preflight: probe <server>/api/info before running flows; on non-200 emit a
  red annotation and exit. A full outage makes every shard fail with the same
  clear reason instead of 13 mystery flow failures.
- Mid-run scan: on failure, grep the local Maestro logs for retryRequest's
  "Non-retryable error <code>" / connection-error fingerprints and annotate
  that the failure is likely a server/environment flake.
No code change. Re-run the Build PR matrix to get a fresh stability signal.
…che real

Maestro's iOS driver has used XCUITest since 1.18.0 and no longer needs
idb-companion to drive the simulator. Verified on Maestro 2.5.1 + iOS 26
with idb absent: launchApp, tapOn, assertVisible (hierarchy read), back and
takeScreenshot all pass. Removing `brew tap facebook/fb` + the idb install
drops ~110s per iOS shard (the tap triggers a full Homebrew auto-update),
~24 min cumulative macOS runner time per run across 13 shards.

Also gate the Maestro install on a cache hit on both platforms. The install
script (get.maestro.mobile.dev) rm -rf's ~/.maestro and re-downloads on every
run with no "already installed" check, so the existing Cache Maestro step was
overwritten and wasted. With the gate, warm runs skip the ~70s download.
…helper

- Extract the duplicated Android SDK preinstall block into a
  .github/actions/preinstall-android-sdk composite action; build-pr.yml
  (seed job) and maestro-android.yml now reference it instead of
  copy-pasting the serialized 3x-retried install.
- Remove the now-dead per-shard "Generate AVD snapshot" step in
  maestro-android.yml: e2e-seed-android-avd is a hard needs: and the
  single writer of the avd-<os>-api34 cache, so the shard restore always
  hits; the cold-boot fallback creates the AVD on the fly on a rare miss.
- Add getAttachmentText() in message/utils.ts as the single source of
  truth for a quote/reply's displayed text (text || title); Reply.tsx and
  useQuoteDescriptionLabel.ts both use it so the rendered quote and its
  VoiceOver label stay in sync.
When the Maestro session never produces a JUnit report (e.g. the iOS
XCUITest runner not attaching within MAESTRO_DRIVER_STARTUP_TIMEOUT),
run-maestro.sh exited 1 immediately. The existing per-flow rerun loop
can't recover that class — it needs a report to know which flows to
retry. Retry the whole suite once (MAX_STARTUP_RETRIES, default 1) when
no main report is produced, and on exhaustion annotate it as an
environment failure rather than an app/test regression. A report that
exists with failures is still routed to the per-flow rerun loop
unchanged.
- Drop redundant 'simctl launch booted com.apple.springboard' + sleep 5:
  SpringBoard is already up once bootstatus -b returns, so warming it was
  pure overhead (~20-90s/shard depending on runner).
- Fix UIAnimationDragCoefficient: it is a duration MULTIPLIER, so the
  previous -float 10 made every UIKit/native-stack transition 10x SLOWER
  (the opposite of the 'Disabling animations' intent). Set 0.0001 so
  transitions are near-instant and Maestro never waits on them, mirroring
  Android's disable-animations.
- Start the async simctl boot right after Configure Simulator, before the
  Java/app-download/E2E-account/Maestro setup steps, so the cold boot
  overlaps that work instead of running after it.
…o job

The step exported $UDID to $GITHUB_ENV but nothing consumed it — Install App
uses the 'booted' keyword and Maestro auto-detects the single booted simulator.
Removing it so the workflow no longer implies a UDID is needed.
- AVD/SDK snapshot caches are written only on develop and restored read-only
  by PRs (a PR-scoped cache can't be shared across PRs); a miss cold-boots
  instead of skipping shards.
- Narrow the Maestro cache to bin/lib/deps so stale run logs can't be restored
  and mis-grepped as server flakes.
- Bound each `maestro test` with `timeout -k` and drop the in-script
  whole-suite startup retry; job timeouts sit just above the in-script bound.
- Single-source the shard list for both platforms via a preflight job that
  fails loud if the flow test-<N> set drifts from the declared 1..14 range;
  restore the missing test-9 (E2E encryption) shard.
- iOS small-screen shard picks the smallest available iPhone (SE) and fails
  loud if none resolves.
- Fail loud when the E2E server URL can't be scraped from data.js, and redact
  the session token from uploaded Maestro logs.

a11y: drop the quoted-reply suffix on Android (TalkBack already enumerates the
quote subtree, so the suffix double-announced); correct the FormTextInput note
on iOS E2E credential-masking suppression.
The preflight had no needs:, so it ran on every PR open in parallel with
lint — before the e2e approval gate. Add needs: [e2e-hold] so it runs only
once e2e is approved, alongside the e2e builds. A PR that never opts into
e2e no longer burns a runner here, nor gets a red X from the drift guard for
a suite it isn't running. The run matrices still consume its output, so
nothing downstream changes.
GNU `timeout` bounds each `maestro test`, but it ships as `timeout` only on
the Linux (Android) runners; macOS provides it as `gtimeout` (Homebrew
coreutils). The hardcoded `timeout` aborted every iOS shard with
`timeout: command not found` before Maestro ran, so no JUnit report was
produced and the run went red. Resolve whichever binary is present, falling
back to running unbounded under the job-level timeout-minutes backstop when
neither exists.
The e2e shards used actions/cache with a single static key
(maestro-<os>-<version>), so on a cold cache every shard in the first
runner wave missed, installed Maestro independently, then raced to save
the same key — one won and the rest logged "failed to save: another job
may be creating this cache". Whether a shard hit became a function of
which runner wave it landed in, not anything deterministic.

Populate the cache once in the e2e build jobs (e2e-build-ios on macOS,
e2e-build-android on Linux), which already run on the matching runner.os
and gate every shard via needs, and switch the shards to
actions/cache/restore. Every shard now gets a deterministic hit and only
restores: no per-shard install, no first-writer race, no save noise. The
build jobs use lookup-only + install/save on miss, so a warm cache is a
cheap existence check and they touch the Maestro CDN only on a version
bump or eviction. The shards keep their cache-miss Install Maestro step
as a fallback.

MAESTRO_VERSION is now pinned in the build workflows too; it must stay in
sync with the shard workflows or the cache key drifts.
…undle

# Conflicts:
#	app/containers/FormContainer.tsx
The single-use fix in PR #7311 prevents unconditional empty-string appending.
However, once any 2FA-protected call completes, this.code retains the TOTP
value and leaks it into every subsequent methodCall on that connection,
re-introducing the trailing-arg breakage and replaying a spent code.

Clear the field immediately after the initial attempt consumes it (no await
between write and read, so the retry sees the fresh value and only uses it
once). Covered by four test cases: no-2FA path, 2FA prompt + retry, code
non-leakage to subsequent calls, and 2FA cancellation.
When the target message id is not yet in the loaded list, the jump loop
retries every 600 ms by scrolling to the top to trigger onEndReached.
Previously it retried forever, so a deleted or unreachable message held
the spinner for the full caller-race timeout (up to 20 s).

Track the loaded-message count across retries; if it stays the same for
5 consecutive rounds (~3 s) the target cannot appear — reset and resolve
instead of waiting for the backstop timer.

Adds useScroll.test.ts covering: no-progress exit, growth keeps retrying,
cancel mid-loop, and counter reset between jumps.
Comment thread .github/workflows/build-pr.yml Outdated
Comment on lines +55 to +65
# Single source of the shard list both platforms fan out over, and the guard
# that keeps it honest: it asserts every flow under .maestro/tests is tagged
# test-<N> within the declared range and every shard in the range has a flow,
# then emits the list as JSON for the matrices below. A flow tagged outside
# the range, or a gap in the range, fails here instead of letting that flow
# silently never run. No AVD seeding happens on PRs — the avd/sdk caches are
# written only on develop (build-develop.yml's seed-android-avd); shards
# restore them read-only and cold-boot on a miss.
# Gated behind e2e-hold, alongside the e2e builds, so it runs only once e2e is
# approved — a PR that never opts into e2e neither burns a runner here nor gets
# a red X from the drift guard for a suite it isn't running.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Weird and long comment

Comment thread .github/workflows/e2e-build-android.yml Outdated
Comment on lines +20 to +21
# Single writer of the Maestro install cache the e2e Android shards
# restore. Keep in sync with maestro-android.yml — the key must match.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Remove

Comment thread .github/workflows/e2e-build-android.yml Outdated
Comment on lines +34 to +39
# Warm the Maestro install cache once here: this job is the single writer
# of the key the e2e Android shards restore (Linux runner — matching their
# runner.os — and it gates them via needs). Every shard then gets a
# deterministic cache hit and only restores: no per-shard install, no
# concurrent first-writer race. lookup-only skips pulling the payload this
# job never uses on a warm cache.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Too long

Comment thread .github/workflows/e2e-build-ios.yml Outdated
Comment on lines +28 to +29
# Single writer of the Maestro install cache the e2e iOS shards restore.
# Keep in sync with maestro-ios.yml — the cache key must match exactly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Remove

Comment thread .github/workflows/e2e-build-ios.yml Outdated
Comment on lines +39 to +44
# Warm the Maestro install cache once here: this job is the single writer
# of the key the e2e iOS shards restore (it runs on macOS — matching their
# runner.os — and gates them via needs). Every shard then gets a
# deterministic cache hit and only restores: no per-shard install, no
# concurrent first-writer race, no "failed to save" noise. lookup-only
# avoids pulling the ~200 MB payload this job never uses on a warm cache.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Too long

Comment thread .github/workflows/maestro-android.yml Outdated
Comment on lines +14 to +15
# Slowest passing shard ~27 min; bounds a wedged session above the in-script
# timeout -k wrap so a hang fails the job instead of burning the full 6h cap.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Remove

Comment thread .github/workflows/maestro-android.yml Outdated
Comment on lines +18 to +19
# 2.5.0 switched gRPC to dadb direct ADB socket — eliminates flaky TCP forwarding (Broken pipe at install).
# https://github.com/mobile-dev-inc/maestro/releases/tag/cli-2.5.0

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Remove

@github-actions

Copy link
Copy Markdown

iOS Build Available

Rocket.Chat 4.74.0.109084

@github-actions

Copy link
Copy Markdown

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