e2e: Cover pinned messages, search, moderation, channel actions, threads and reminders - #6610
Conversation
…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.
|
@CodeRabbit review |
✅ Action performedReview finished.
|
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
WalkthroughAdds 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. ChangesCompose E2E coverage
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (20)
stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/ChannelInfoPage.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/ChannelListPage.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/MessageListPage.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/PinnedMessagesPage.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/RemindersPage.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/ThreadListPage.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobot.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotChannelListAsserts.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotMessageListAsserts.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotPinnedMessagesAsserts.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotRemindersAsserts.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotThreadListAsserts.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/ChannelActionsTests.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/ModerationTests.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/PinnedMessagesTests.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/RemindersTests.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/SearchTests.ktstream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/ThreadListTests.ktstream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/component/AppBottomBar.ktstream-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.
|
@CodeRabbit review |
✅ Action performedReview finished.
|
SDK Size Comparison 📏
|
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.
|
@CodeRabbit review |
✅ Action performedReview finished.
|
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.
|
@CodeRabbit review |
✅ Action performedReview finished.
|
…-compose-features
|



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:
BackendRobot.createReminderseeds 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:
stream-chat-test-mock-server, runbundle installand thenbundle exec ruby driver.rb../gradlew :stream-chat-android-compose-sample:installE2eDebug :stream-chat-android-compose-sample:installE2eDebugAndroidTestadb shell pm clear io.getstream.chat.android.compose.sample.e2etest.debugadb 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.AllureAndroidJUnitRunnerThe Allure runner always reports a
TestStorageExceptionin 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.spotlessCheckanddetektpass.Summary by CodeRabbit