Skip to content

e2e: Re-find and retry clicks on stale nodes#6588

Open
andremion wants to merge 3 commits into
developfrom
andrerego/and-1326-fix-the-stale-object-click-path-in-the-e2e-tests
Open

e2e: Re-find and retry clicks on stale nodes#6588
andremion wants to merge 3 commits into
developfrom
andrerego/and-1326-fix-the-stale-object-click-path-in-the-e2e-tests

Conversation

@andremion

@andremion andremion commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Goal

test_uploadMultipleImages failed all 3 attempts on the 2026-07-24 nightly (run 30059419167, API 34) with StaleObjectException thrown by UiObject2.click in UserRobot.attachFile. The robots click through waitToAppear().click(): the wait helper absorbs staleness while finding the node, but the returned UiObject2 is held across the gap to the click. When the UI refreshes in that gap (the DocumentsUI roots list in this failure, recomposition in the app UI), the click lands on a recycled node and throws. This is the click-path variant of the read-path stale races fixed in #6570.

Resolves AND-1326

Implementation

  • Added BySelector.waitToAppearAndClick(timeOutMillis) to the shared UiAutomator toolkit (Wait.kt). It waits for the node and clicks it, and when the click throws StaleObjectException it re-finds the node and retries within the same timeout budget. After the timeout, the exception escapes as before.
  • First commit applies it to the three DocumentsUI click sites in UserRobot.attachFile (roots button, the Downloads root item where the nightly failed, and the file item).
  • Second commit converts the remaining pure waitToAppear().click() chains in the sample robots and tests (38 call sites in total across both commits). Call sites that use the returned object for other actions (longPress, typeText, clear, reading bounds) keep waitToAppear().

While investigating, the ticket's secondary observation (mock-server logs with no app traffic) turned out to be a misread of the artifacts: each attempt's per-test mock log shows the full login and channel flow, and the retries restarted the app against the fresh mock correctly. Details are on the ticket.

Testing

This changes only e2e test infrastructure, so the e2e suite itself is the test:

  1. The E2E Tests workflow on this PR should pass.
  2. Compare the suite duration and per-test timings of this PR's run against recent develop runs. The helper only adds work on a stale click (a re-find plus retry), so timings should stay flat.
  3. The specific flake is timing dependent, so the real confirmation is the nightly trend for test_uploadMultipleImages and test_deleteImage staying clean.

Summary by CodeRabbit

  • Bug Fixes
    • Improved automated UI interactions by retrying taps when elements become stale or temporarily unavailable.
    • Increased reliability across authentication, messaging, reactions, threads, attachments, GIFs, and mentions.
    • Reduced intermittent failures when selecting, sending, editing, deleting, or confirming actions.

@andremion andremion added the pr:test Test-only changes label Jul 24, 2026
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds a stale-object-safe waitToAppearAndClick() helper and replaces direct wait-then-click calls across authentication, messaging, threading, reactions, Giphy, attachments, mentions, and navigation end-to-end tests.

Changes

UI click reliability

Layer / File(s) Summary
Wait-and-click helper
stream-chat-android-e2e-test/.../uiautomator/Wait.kt
Adds a public retrying selector helper that waits for appearance, clicks, and retries stale-object failures until timeout.
Core robot interactions
stream-chat-android-compose-sample/.../robots/UserRobot.kt, stream-chat-android-compose-sample/.../tests/AuthTests.kt
Replaces two-step clicks across authentication, navigation, message actions, reactions, quoting, threading, and link-preview flows.
Composer and attachment interactions
stream-chat-android-compose-sample/.../robots/UserRobot.kt
Uses the helper for Giphy controls, file picker navigation, mentions, attachments, and message sending.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: pr:ci

Suggested reviewers: testableapple, velikovpetar

Poem

I’m a rabbit with clicks to spare,
Waiting for buttons to bloom in the air.
Stale taps hop back in line,
Giphy and messages now click just fine.
Auth and attachments dance—
Reliable paws at every chance! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: retrying stale clicks in E2E tests.
Description check ✅ Passed Goal, implementation, and testing are covered, but the UI Changes, GIF, and checklist sections from the template are not filled.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch andrerego/and-1326-fix-the-stale-object-click-path-in-the-e2e-tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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
`@stream-chat-android-e2e-test/src/main/kotlin/io/getstream/chat/android/e2e/test/uiautomator/Wait.kt`:
- Line 59: Update the wait-and-click flow around waitToAppear so it passes only
the nonnegative remaining timeout, without using maxOf to add
POLL_INTERVAL_MILLIS after the deadline. Ensure waitToAppear caps its final
sleep to the supplied duration, preserving the same timeout budget and
preventing clicks after timeOutMillis.
- Around line 55-65: Add tests covering Wait.kt’s waitToAppearAndClick behavior:
verify a stale first click is retried and succeeds, repeated
StaleObjectException failures are propagated after the timeout, and retries
never continue past the supplied timeOutMillis deadline. Use controlled timing
or test doubles so the boundary assertions are deterministic.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a014cebf-372c-4301-8b48-8650f2b428ba

📥 Commits

Reviewing files that changed from the base of the PR and between 79cffee and 4b97ce5.

📒 Files selected for processing (3)
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobot.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/AuthTests.kt
  • stream-chat-android-e2e-test/src/main/kotlin/io/getstream/chat/android/e2e/test/uiautomator/Wait.kt

@github-actions

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.95 MB 5.95 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.21 MB 11.21 MB 0.00 MB 🟢
stream-chat-android-compose 12.69 MB 12.69 MB 0.00 MB 🟢

@andremion
andremion marked this pull request as ready for review July 24, 2026 11:03
@andremion
andremion requested a review from a team as a code owner July 24, 2026 11:03
@sonarqubecloud

Copy link
Copy Markdown

@andremion
andremion enabled auto-merge (squash) July 24, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:test Test-only changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant