Skip to content

e2e: Make the remaining UserRobot clicks stale-safe - #6603

Merged
andremion merged 1 commit into
developfrom
andrerego/and-1344-e2e-make-the-remaining-userrobot-clicks-stale-safe
Jul 30, 2026
Merged

e2e: Make the remaining UserRobot clicks stale-safe#6603
andremion merged 1 commit into
developfrom
andrerego/and-1344-e2e-make-the-remaining-userrobot-clicks-stale-safe

Conversation

@andremion

@andremion andremion commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Goal

The last nightly run failed on API 35 because GiphyTests.test_userObservesAnimatedGiphy_afterAddingGiphyThroughComposerMenu failed all 3 retry attempts with StaleObjectException: https://github.com/GetStream/stream-chat-android/actions/runs/30414531872. The click landed on a composer button node that went stale between the find and the click.

#6588 introduced the stale-safe waitToAppearAndClick, but some UserRobot actions still click a found UiObject2 directly, so any of them can fail the same way when Compose recomposes at tap time. This PR routes every remaining click through the stale-safe helper.

Resolves AND-1344

Implementation

  • tapOnComposerConfirmButton now taps one combined selector, By.res(Pattern.compile("Stream_Composer(Send|Save)Button")), through waitToAppearAndClick, replacing the custom loop that polled the send and save buttons and clicked without stale protection. On timeout the error message now comes from waitToAppear instead of the custom text; the exception type is unchanged.
  • The 10 waitToAppear().click() call sites convert to waitToAppearAndClick(): copy, pin, unpin, message reaction, extended reactions picker (2 taps), scroll-to-first-unread button and its dismiss icon, channel swipe "more", and view channel info.
  • tapOnMessage is removed: it was the last unprotected click, and it has no callers.

Testing

Ran locally against the mock server (main) on an API 35 emulator with direct instrumentation:

  • GiphyTests: 10/10 passed in 106s, including the test that failed the nightly.
  • ReactionsTests, PinnedMessagesTests, ChannelActionsTests, MessageActionsTests (the classes that exercise the converted click sites): 21/21 passed in 257s.

No retries were needed in either run. To reproduce, build assembleE2eDebug and assembleE2eDebugAndroidTest of stream-chat-android-compose-sample, start the mock server (bundle exec fastlane start_mock_server), install both APKs, and run the classes above with adb shell am instrument.

No UI changes.

Summary by CodeRabbit

  • Tests
    • Improved automated coverage for message composition, including both sending messages and saving commands.
    • Increased reliability of UI interactions for pinning, reactions, unread indicators, and channel information.
    • Standardized interaction handling to reduce flaky end-to-end test behavior in the Compose sample app.

The composer confirm tap polls one combined send-or-save selector through
waitToAppearAndClick instead of clicking objects found by a hand-rolled
loop, the waitToAppear().click() call sites convert to waitToAppearAndClick,
and the caller-less tapOnMessage is removed.
@github-actions

github-actions Bot commented Jul 29, 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.

@andremion andremion added the pr:internal Internal changes / housekeeping label Jul 29, 2026
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 29, 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.

@andremion andremion added pr:test Test-only changes and removed pr:internal Internal changes / housekeeping labels Jul 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.96 MB 5.96 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.23 MB 11.23 MB 0.00 MB 🟢
stream-chat-android-compose 12.70 MB 12.70 MB 0.00 MB 🟢

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The Compose sample’s E2E robot now uses a shared regex selector for send/save confirmation buttons and wait-aware clicks for several message and channel actions. An unused message-tapping helper was removed.

Changes

Compose E2E robot behavior

Layer / File(s) Summary
Composer confirmation flow
stream-chat-android-compose-sample/.../pages/MessageListPage.kt, stream-chat-android-compose-sample/.../robots/UserRobot.kt
The composer confirmation selector matches both send and save buttons, and the robot clicks it directly.
Synchronized UI actions
stream-chat-android-compose-sample/.../robots/UserRobot.kt
Pinning, reactions, unread indicators, and channel info use waitToAppearAndClick(); the unused tapOnMessage helper is removed.

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

Possibly related PRs

Suggested labels: pr:bug

Suggested reviewers: gpunto, testableapple, velikovpetar

Poem

I’m a bunny with buttons to hop,
Send and Save now share one stop.
Wait, then click—no stale-node fright,
Reactions and menus behave just right.
Carrots for tests, and a tidy delight!

🚥 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 is concise and accurately summarizes the main change to stale-safe UserRobot clicks.
Description check ✅ Passed The description covers the goal, implementation, and testing, with a clear note that there are no UI changes.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 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-1344-e2e-make-the-remaining-userrobot-clicks-stale-safe

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.

@sonarqubecloud

Copy link
Copy Markdown

@andremion
andremion marked this pull request as ready for review July 29, 2026 14:30
@andremion
andremion requested a review from a team as a code owner July 29, 2026 14:30
@andremion
andremion enabled auto-merge July 29, 2026 14:30
@andremion
andremion added this pull request to the merge queue Jul 30, 2026
Merged via the queue into develop with commit f7d7ff3 Jul 30, 2026
20 of 22 checks passed
@andremion
andremion deleted the andrerego/and-1344-e2e-make-the-remaining-userrobot-clicks-stale-safe branch July 30, 2026 07:31
@stream-public-bot stream-public-bot added the released Included in a release label Jul 30, 2026
@stream-public-bot

Copy link
Copy Markdown
Contributor

🚀 Available in v7.7.0

andremion added a commit that referenced this pull request Jul 30, 2026
Aligns with #6603, which converted the remaining UserRobot clicks.
pull Bot pushed a commit to Siriusmene/stream-chat-android that referenced this pull request Jul 30, 2026
…tate (GetStream#6599)

* e2e: Re-enable the unread messages tests and cover mark-as-unread

The mock server now maintains per-user read state, so the unread
separator and jump-to-unread tests (11453-11455) run again. Add the
mark-as-unread flow (6073) and a channel list unread badge assertion,
waiting for the badge before reopening the channel so the sticky unread
label is computed from settled state instead of racing the event queue.

The badge exposes only a content description (clearAndSetSemantics in
UnreadCountIndicator removes the text and tag from the semantics tree),
so the assertion matches the stream_compose_channel_item_unread plural
and the stale resource-id selector is removed.

* e2e: Wait for the message delivery before the participant acts in the unread tests

On a slow emulator the participant's first message could reach the mock
server before the user's own message, changing the message order the
tests rely on for the separator position and the marked message index.

* e2e: Mark the message as unread by text instead of position

Selecting by cell index assumed both participant messages had rendered;
openContextMenu falls back to the last message when the index is out of
range, which could mark the wrong message on a slow emulator.

* ui-common: Compute the unread label before marking the channel read

Marking read zeroes the read state optimistically while keeping
last_read_message_id, and the unread label pipeline collects a
conflating flow. On a busy main thread the collector could observe only
the zeroed state, compute a zero-count label, and the sticky design
kept it forever, so the unread separator never rendered. Computing the
label from the current read state right before the mark-read call makes
the order deterministic, since the controller triggers both.

* ui-common: Keep the unread label recalculation open on null results

The read-state id was marked as processed before the calculator ran, so
a first emission arriving while the message list is still empty produced
no label and permanently blocked recalculation for that id. The id is
now recorded only when a label is produced, so the capture before
mark-read computes the label once the messages are loaded.

* e2e: Use the stale-safe click for the mark-as-unread menu option

Aligns with GetStream#6603, which converted the remaining UserRobot clicks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:test Test-only changes released Included in a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants