Skip to content

e2e: Cover pinned messages, search, moderation, channel actions, threads and reminders - #6610

Merged
andremion merged 5 commits into
developfrom
andrerego/and-1356-e2e-coverage-remaining-compose-features
Jul 31, 2026
Merged

e2e: Cover pinned messages, search, moderation, channel actions, threads and reminders#6610
andremion merged 5 commits into
developfrom
andrerego/and-1356-e2e-coverage-remaining-compose-features

Conversation

@andremion

@andremion andremion commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Goal

Several Compose sample screens have no e2e coverage, even though the mock server already serves every endpoint they call. This adds that coverage for the pinned messages screen, message search, flagging a message, the channel actions sheet, the thread list and the reminders screen.

Resolves AND-1356

Implementation

13 tests, grouped by area:

  • PinnedMessagesTests: the pinned message is listed on the pinned messages screen, and the screen is empty after unpinning.
  • SearchTests: the message is found from the channel list header, and tapping the result opens it.
  • ModerationTests: flagging another user's message shows the confirmation, and the message stays after confirming.
  • ChannelActionsTests: leave a group and delete a group, both through the confirmation dialog.
  • ThreadListTests: the list is empty when there are no threads, a thread is listed with its reply count, and tapping it opens the thread.
  • RemindersTests: the screen is empty when there are no reminders, and both a reminder saved for later and a scheduled one are listed.

New page objects for the channel info, pinned messages, thread list and reminders screens. Their rows carry no test tags, so the assertions go through the visible text. Two details behind the selectors:

  • The pinned row renders the message text through the preview formatter, which appends a trailing space to it, so the text is matched by its start.
  • The bottom bar tabs get test tags, because the threads tab label and the thread list header title are both "Threads".

BackendRobot.createReminder seeds a reminder on the last message, since the sample has no way to create one.

Every test is bound to a QA case with @AllureId.

Six more tests were written and then removed here: mute, unmute, block and unblock the message author, and mute and unmute the channel from the swipe action. The mock server pushes a health check payload built once at startup, with an empty mutes list, an empty channel mutes list and no blocked users, every two seconds, and the client applies every own-user event as a full current-user update. The state those tests assert therefore disappears about two seconds after the action, so they pass locally and flake on the slower CI emulator. They move to AND-1359, which collects the coverage that needs mock server changes first.

Testing

The e2e workflow on this PR runs the whole suite, which is the main check.

Locally, every new test was run one at a time on an API 35 emulator against the mock server, with the app data cleared between runs, and all of them pass. Running a whole class in one go locally is not a valid check: without the orchestrator there is no clearPackageData, so a test can fail because of the state the previous one left behind.

To reproduce a single test locally:

  1. In stream-chat-test-mock-server, run bundle install and then bundle exec ruby driver.rb.
  2. ./gradlew :stream-chat-android-compose-sample:installE2eDebug :stream-chat-android-compose-sample:installE2eDebugAndroidTest
  3. adb shell pm clear io.getstream.chat.android.compose.sample.e2etest.debug
  4. adb shell am instrument -w -r -e class io.getstream.chat.android.compose.tests.RemindersTests#test_reminderSavedForLaterIsShownOnTheRemindersScreen io.getstream.chat.android.compose.sample.e2etest.debug.test/io.qameta.allure.android.runners.AllureAndroidJUnitRunner

The Allure runner always reports a TestStorageException in this setup, because the test storage service is not reachable without the orchestrator. Judge the result by the absence of a failure named after the test.

spotlessCheck and detekt pass.

Summary by CodeRabbit

  • Tests
    • Added end-to-end coverage for leaving and deleting channels, message search, pinned messages, reminders, threads, and message moderation.
    • Added validation for saved-for-later and scheduled reminders, search navigation, message status changes, reply counts, and empty states.
    • Expanded localized UI checks for titles, menus, dialogs, and navigation.
  • Chores
    • Added test identifiers for chat, thread, and reminder interactions to improve UI test reliability.

…ads and reminders

Add 16 tests for the Compose sample screens the mock server already supports:
the pinned messages screen, message search from the channel list header, flag,
mute, unmute, block and unblock from the message menu, leave group, delete
group and the swipe mute, the thread list, and the reminders screen.

New page objects for the channel info, pinned messages, thread list and
reminders screens. Their rows carry no test tags, so the assertions go through
the visible text. The pinned row is matched by the text start, because the
message preview formatter appends a trailing space to the message text.

BackendRobot.createReminder seeds a reminder on the last message, since the
sample has no way to create one.

The bottom bar tabs get test tags, because the threads tab label and the thread
list header title are both "Threads".

Only Allure 5935 and 6071 are bound. 5934 needs channel search, which the
sample does not wire, and 6070 and 6072 need a direct message channel, which
the current mock fixture does not have.
@andremion andremion added the pr:test Test-only changes label Jul 31, 2026
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

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

@github-actions

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 31, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds Compose UI page objects, robot actions, assertions, test tags, backend reminder seeding, and end-to-end coverage for channel actions, moderation, pinned messages, reminders, search, and thread lists.

Changes

Compose E2E coverage

Layer / File(s) Summary
UI selectors and test tags
stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/.../pages/*, stream-chat-android-compose-sample/src/main/java/.../AppBottomBar.kt, stream-chat-android-compose-sample/src/main/java/.../feature/reminders/*
Adds localized selectors for channel, moderation, pinned-message, reminder, and thread screens. Adds bottom-bar and reminder-item test tags. Applies SampleChatTheme to the reminders activity.
Robot interactions and assertions
stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/.../robots/*
Adds navigation, channel action, moderation, pinned-message, reminder, and thread-list robot helpers and assertions.
Channel and moderation scenarios
stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/.../tests/{ChannelActionsTests,ModerationTests}.kt
Adds tests for leaving, deleting, and flagging messages.
Pinned, reminder, search, and thread workflows
stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/.../tests/{PinnedMessagesTests,RemindersTests,SearchTests,ThreadListTests}.kt, stream-chat-android-e2e-test/src/main/kotlin/.../BackendRobot.kt
Adds tests for pinned messages, reminders, message search, and thread navigation. Adds backend reminder creation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: gpunto, velikovpetar

Poem

A rabbit checks each screen,
Channels and threads now align.
Reminders appear when seeded,
Pinned messages are verified,
E2E tests hop in line.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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 clearly summarizes the primary change: new end-to-end coverage for the listed Compose sample features.
Description check ✅ Passed The description covers the goal, implementation, tests, issue reference, limitations, and validation results, although optional UI and checklist sections are not completed.
✨ Finishing Touches 💡 1
📝 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-1356-e2e-coverage-remaining-compose-features

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: 1

🤖 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-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotRemindersAsserts.kt`:
- Around line 35-38: Update UserRobot.assertReminderSavedForLater to locate the
reminder row identified by messageText and assert savedForLaterStatus within
that row, rather than using the global RemindersPage.savedForLaterStatus
selector.
🪄 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: 746f317b-59e0-4846-875a-8fc233f164d2

📥 Commits

Reviewing files that changed from the base of the PR and between f0a5137 and 6c41232.

📒 Files selected for processing (20)
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/ChannelInfoPage.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/ChannelListPage.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/MessageListPage.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/PinnedMessagesPage.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/RemindersPage.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/ThreadListPage.kt
  • 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/robots/UserRobotChannelListAsserts.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotMessageListAsserts.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotPinnedMessagesAsserts.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotRemindersAsserts.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotThreadListAsserts.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/ChannelActionsTests.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/ModerationTests.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/PinnedMessagesTests.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/RemindersTests.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/SearchTests.kt
  • stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/ThreadListTests.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/AppBottomBar.kt
  • stream-chat-android-e2e-test/src/main/kotlin/io/getstream/chat/android/e2e/test/robots/BackendRobot.kt

The status was matched anywhere on the screen, so another reminder's status
could satisfy the assertion. The reminder row now carries a test tag, and both
the reminder and its status are looked up inside the row of the asserted
message.

The reminders screen uses SampleChatTheme, because test tags are only exposed
as resource ids under that wrapper.
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

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

@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.22 MB 11.22 MB 0.00 MB 🟢
stream-chat-android-compose 12.71 MB 12.71 MB 0.00 MB 🟢

The message menu builds its options when it opens and keeps them while it stays
open, so the option label only reflects a mute or a block that landed before the
open. On the CI emulator the mute response took 527ms, which is longer than the
tap and the reopen, so the reopened menu was built from the old state and the
assertion waited on a label that never changed. It made
test_userMutesMessageAuthor and test_userBlocksMessageAuthor fail on API 36
while they passed locally, where the same request takes a few milliseconds.

The moderation assertions now open the menu themselves and reopen it while the
expected option is missing, and the unmute and unblock actions do the same
before they tap.

Bind the QA cases that TestOps created for the tests of the previous commit.
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

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

The mock server rebuilds no state into its health check: it pushes a payload
made once at startup, with an empty mutes list, an empty channel mutes list and
no blocked users, every two seconds. The client applies every own-user event as
a full current-user update, so a mute or a block disappears about two seconds
after it lands, and the message menu label goes back to its original wording.
The assertions only hold while they run inside that window, which is why they
passed locally and failed on the slower CI emulator.

Remove the four message-menu tests and the two channel swipe tests that depend
on that state, together with the selectors and robot actions only they used.
They come back in AND-1359 once the mock sends the live own user.

Flagging a message stays, because it asserts the dialog and not user state.
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 31, 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 marked this pull request as ready for review July 31, 2026 15:29
@andremion
andremion requested a review from a team as a code owner July 31, 2026 15:29
@andremion
andremion enabled auto-merge July 31, 2026 15:36
@andremion
andremion added this pull request to the merge queue Jul 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 31, 2026
@andremion
andremion enabled auto-merge July 31, 2026 18:43
@sonarqubecloud

Copy link
Copy Markdown

@andremion
andremion added this pull request to the merge queue Jul 31, 2026
Merged via the queue into develop with commit 8aa103b Jul 31, 2026
19 checks passed
@andremion
andremion deleted the andrerego/and-1356-e2e-coverage-remaining-compose-features branch July 31, 2026 20:04
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.

2 participants