Skip to content

Commit 59a2664

Browse files
authored
Message Composer structural redesign (#6088)
* Support content alignment of Paparazzi snapshots * Change MessageInput to render the trailing content which contain the composer send action * Support composer floating style * Fix margins of ScrollToBottomButton * Fix docs * Renamed the `integrations` parameter in `MessageComposer` to `leadingContent` and remove the commands button from the default leading content. * Move `MessageComposer`'s default composables to the `internal` package. This change makes the following composables `internal`: - `DefaultMessageComposerHeaderContent` - `DefaultMessageComposerFooterInThreadMode` - `DefaultMessageComposerLeadingContent` - `DefaultComposerLabel` - `DefaultMessageComposerInput` - `DefaultMessageComposerInputTrailingContent` - `AttachmentsButton` - `CommandsButton` - `SendButton` * Update composer input max lines * Initial update of message composer actions * Update composer send and mic icons * Update DefaultMessageComposerInputTrailingContent content logic * Decouple MessageInput from InputField * - Update message input padding/margins - Introduce shadow in the message input on floating style mode on * Add composer with attachment previews * Update layout of composer message input * Update add icon * Support canceling link previews * Fix detekt * Fixes after merging from base branch * Support canceling link previews * Fix e2e tests * Fix message input animation * Update ScrollToBottomButton UI * Use StreamTokens * Fix detekt * Fix colors * Update screenshot golden files * Fix scroll to bottom button paddings * coderabbit review * Fix snapshots * apiDump * code review * Bump androidxUiAutomator from 2.4.0-alpha01 to 2.4.0-alpha05 * update snapshots * Fix e2e tests * Refactor message list page objects to use getters, to avoid getting stale reference errors * - Fix flaky quoted reply test. The `deleteMessage` test action was not reliable as it sometimes targeted the quoted message. - assert message with a text selector to prevent flakiness * merge from base branch
1 parent 0022337 commit 59a2664

File tree

76 files changed

+1634
-863
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1634
-863
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ androidxTestCore = "1.5.0"
2828
androidxTestJunit = "1.1.5"
2929
androidxTestMonitor = "1.7.2"
3030
androidxTestOrchestrator = "1.5.1"
31-
androidxUiAutomator = "2.4.0-alpha01"
31+
androidxUiAutomator = "2.4.0-alpha05"
3232
androidxViewPager2 = "1.1.0"
3333
androidxTest = "1.5.2"
3434
baseProfile = "1.3.1"

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/MessageListPage.kt

Lines changed: 92 additions & 93 deletions
Large diffs are not rendered by default.

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobot.kt

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,23 @@ class UserRobot {
8383
return this
8484
}
8585

86+
fun openContextMenu(messageText: String): UserRobot {
87+
val messageTextSelector = Message.text
88+
.text(messageText)
89+
.hasAncestor(MessageList.messages)
90+
val clickableTextSelector = Message.clickableText
91+
.text(messageText)
92+
.hasAncestor(MessageList.messages)
93+
94+
val target = when {
95+
clickableTextSelector.isDisplayed() -> clickableTextSelector
96+
else -> messageTextSelector
97+
}
98+
99+
target.waitToAppear().longPress()
100+
return this
101+
}
102+
86103
fun typeText(text: String): UserRobot {
87104
Composer.inputField.waitToAppear().typeText(text)
88105
return this
@@ -99,12 +116,12 @@ class UserRobot {
99116
}
100117

101118
fun tapOnSendButton(): UserRobot {
102-
Composer.sendButton.findObject().click()
119+
Composer.sendButton.waitToAppear().click()
103120
return this
104121
}
105122

106-
fun tapOnAttachmentCancelIcon(): UserRobot {
107-
Composer.attachmentCancelIcon.waitToAppear().click()
123+
fun tapOnLinkPreviewCancelButton(): UserRobot {
124+
Composer.linkPreviewCancelButton.waitToAppear().click()
108125
return this
109126
}
110127

@@ -121,6 +138,13 @@ class UserRobot {
121138
return this
122139
}
123140

141+
fun deleteMessage(text: String): UserRobot {
142+
openContextMenu(text)
143+
ContextMenu.delete.waitToAppear().click()
144+
ContextMenu.ok.waitToAppear().click()
145+
return this
146+
}
147+
124148
fun editMessage(newText: String, messageCellIndex: Int = 0): UserRobot {
125149
openContextMenu(messageCellIndex)
126150
ContextMenu.edit.waitToAppear().click()

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/robots/UserRobotMessageListAsserts.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ fun UserRobot.assertMessage(
4949
isClickable: Boolean = false,
5050
): UserRobot {
5151
if (isDisplayed) {
52-
val textLocator = if (isClickable) Message.clickableText else Message.text
53-
assertEquals(text, textLocator.waitToAppear().waitForText(text).text)
54-
assertTrue(textLocator.isDisplayed())
52+
val textLocator = (if (isClickable) Message.clickableText else Message.text)
53+
.text(text)
54+
assertTrue(textLocator.waitToAppear().isDisplayed())
5555
assertTrue(Message.timestamp.isDisplayed())
5656
} else {
5757
MessageListPage.MessageList.messages.findObjects().forEach {
@@ -140,11 +140,11 @@ fun UserRobot.assertDeletedMessage(text: String? = null, hard: Boolean = false):
140140
}
141141

142142
fun UserRobot.assertQuotedMessage(text: String, quote: String = "", isDisplayed: Boolean = true): UserRobot {
143+
val quotedMessageInList = Message.quotedMessage.hasAncestor(MessageListPage.MessageList.messages)
143144
if (isDisplayed) {
144-
assertEquals(quote, Message.quotedMessage.waitToAppear().text)
145-
assertTrue(Message.quotedMessageAvatar.isDisplayed())
145+
assertEquals(quote, quotedMessageInList.waitToAppear().text)
146146
} else {
147-
assertFalse(Message.quotedMessage.waitToDisappear().isDisplayed())
147+
assertFalse(quotedMessageInList.waitToDisappear().isDisplayed())
148148
}
149149
assertMessage(text, isDisplayed = isDisplayed)
150150
return this

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/GiphyTests.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class GiphyTests : StreamTestCase() {
154154
}
155155

156156
@AllureId("5823")
157+
@Ignore("https://linear.app/stream/issue/AND-1018")
157158
@Test
158159
fun test_userObservesAnimatedGiphy_afterAddingGiphyThroughComposerMenu() {
159160
step("GIVEN user opens a channel") {

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/HyperLinksTests.kt

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import io.getstream.chat.android.compose.robots.assertMessage
2222
import io.getstream.chat.android.compose.sample.ui.InitTestActivity
2323
import io.qameta.allure.kotlin.Allure.step
2424
import io.qameta.allure.kotlin.AllureId
25-
import org.junit.Ignore
2625
import org.junit.Test
2726

2827
class HyperLinksTests : StreamTestCase() {
@@ -55,7 +54,6 @@ class HyperLinksTests : StreamTestCase() {
5554
}
5655

5756
@AllureId("6830")
58-
@Ignore("https://linear.app/stream/issue/AND-309")
5957
@Test
6058
fun test_unsplashLinkWithoutPreview() {
6159
step("GIVEN user opens the channel") {
@@ -65,15 +63,15 @@ class HyperLinksTests : StreamTestCase() {
6563
userRobot.typeText(unsplashImageLink)
6664
}
6765
step("AND user cancels the link preview") {
68-
userRobot.tapOnAttachmentCancelIcon()
66+
userRobot.tapOnLinkPreviewCancelButton()
6967
}
7068
step("THEN link preview disappears") {
7169
userRobot.assertLinkPreviewInComposer(isDisplayed = false)
7270
}
7371
step("WHEN user taps on the send button") {
7472
userRobot.tapOnSendButton()
7573
}
76-
step("THEN user observes a message with link preview") {
74+
step("THEN user observes a message without link preview") {
7775
userRobot
7876
.assertMessage(unsplashImageLink, isClickable = true)
7977
.assertLinkPreviewInMessageList(isDisplayed = false)
@@ -103,7 +101,6 @@ class HyperLinksTests : StreamTestCase() {
103101
}
104102

105103
@AllureId("6831")
106-
@Ignore("https://linear.app/stream/issue/AND-309")
107104
@Test
108105
fun test_youtubeLinkWithoutPreview() {
109106
step("GIVEN user opens the channel") {
@@ -113,15 +110,15 @@ class HyperLinksTests : StreamTestCase() {
113110
userRobot.typeText(youtubeVideoLink)
114111
}
115112
step("AND user cancels the link preview") {
116-
userRobot.tapOnAttachmentCancelIcon()
113+
userRobot.tapOnLinkPreviewCancelButton()
117114
}
118115
step("THEN link preview disappears") {
119116
userRobot.assertLinkPreviewInComposer(isDisplayed = false)
120117
}
121118
step("WHEN user taps on the send button") {
122119
userRobot.tapOnSendButton()
123120
}
124-
step("THEN user observes a message with link preview") {
121+
step("THEN user observes a message without link preview") {
125122
userRobot
126123
.assertMessage(youtubeVideoLink, isClickable = true)
127124
.assertLinkPreviewInMessageList(isDisplayed = false)
@@ -151,7 +148,6 @@ class HyperLinksTests : StreamTestCase() {
151148
}
152149

153150
@AllureId("6833")
154-
@Ignore("https://linear.app/stream/issue/AND-309")
155151
@Test
156152
fun test_giphyLinkWithoutPreview() {
157153
step("GIVEN user opens the channel") {
@@ -161,15 +157,15 @@ class HyperLinksTests : StreamTestCase() {
161157
userRobot.typeText(giphyGifLink)
162158
}
163159
step("AND user cancels the link preview") {
164-
userRobot.tapOnAttachmentCancelIcon()
160+
userRobot.tapOnLinkPreviewCancelButton()
165161
}
166162
step("THEN link preview disappears") {
167163
userRobot.assertLinkPreviewInComposer(isDisplayed = false)
168164
}
169165
step("WHEN user taps on the send button") {
170166
userRobot.tapOnSendButton()
171167
}
172-
step("THEN user observes a message with link preview") {
168+
step("THEN user observes a message without link preview") {
173169
userRobot
174170
.assertMessage(giphyGifLink, isClickable = true)
175171
.assertLinkPreviewInMessageList(isDisplayed = false)
@@ -183,7 +179,7 @@ class HyperLinksTests : StreamTestCase() {
183179
userRobot.login().openChannel()
184180
}
185181
step("WHEN participant sends an unsplash url") {
186-
userRobot.sendMessage(unsplashImageLink)
182+
participantRobot.sendMessage(unsplashImageLink)
187183
}
188184
step("THEN user observes a message with link preview") {
189185
userRobot
@@ -199,7 +195,7 @@ class HyperLinksTests : StreamTestCase() {
199195
userRobot.login().openChannel()
200196
}
201197
step("WHEN participant sends a youtube url") {
202-
userRobot.sendMessage(youtubeVideoLink)
198+
participantRobot.sendMessage(youtubeVideoLink)
203199
}
204200
step("THEN user observes a message with link preview") {
205201
userRobot
@@ -215,7 +211,7 @@ class HyperLinksTests : StreamTestCase() {
215211
userRobot.login().openChannel()
216212
}
217213
step("WHEN participant sends a giphy url") {
218-
userRobot.sendMessage(giphyGifLink)
214+
participantRobot.sendMessage(giphyGifLink)
219215
}
220216
step("THEN user observes a message with link preview") {
221217
userRobot

stream-chat-android-compose-sample/src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/tests/QuotedReplyTests.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ class QuotedReplyTests : StreamTestCase() {
260260
userRobot.quoteMessage(quoteReply)
261261
}
262262
step("WHEN user deletes a quoted message") {
263-
userRobot.deleteMessage()
263+
userRobot.deleteMessage(quoteReply)
264264
}
265265
step("THEN user observes Message deleted") {
266266
userRobot
@@ -273,14 +273,18 @@ class QuotedReplyTests : StreamTestCase() {
273273
@Test
274274
fun test_originalQuoteIsDeletedByUser_deletedMessageIsShown() {
275275
step("GIVEN user opens the channel") {
276-
backendRobot.generateChannels(channelsCount = 1, messagesCount = 1)
276+
backendRobot.generateChannels(
277+
channelsCount = 1,
278+
messagesCount = 1,
279+
messagesText = sampleText,
280+
)
277281
userRobot.login().openChannel()
278282
}
279283
step("AND user adds a quoted reply") {
280284
userRobot.quoteMessage(quoteReply)
281285
}
282286
step("WHEN user deletes an original message") {
283-
userRobot.deleteMessage(messageCellIndex = 1)
287+
userRobot.deleteMessage(sampleText)
284288
}
285289
step("THEN deleted message is shown") {
286290
userRobot.assertDeletedMessage(quoteReply)
@@ -647,7 +651,7 @@ class QuotedReplyTests : StreamTestCase() {
647651
.quoteMessage(quoteReply)
648652
}
649653
step("WHEN user deletes a quoted message") {
650-
userRobot.deleteMessage()
654+
userRobot.deleteMessage(quoteReply)
651655
}
652656
step("THEN deleted message is shown") {
653657
userRobot
@@ -670,7 +674,7 @@ class QuotedReplyTests : StreamTestCase() {
670674
.quoteMessage(quoteReply)
671675
}
672676
step("WHEN user deletes an original message") {
673-
userRobot.deleteMessage(messageCellIndex = 1)
677+
userRobot.deleteMessage(sampleText)
674678
}
675679
step("THEN deleted message is shown") {
676680
userRobot.assertDeletedMessage(sampleText)

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/add/AddChannelScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ fun AddChannelScreen(
107107
}
108108
MessageComposer(
109109
viewModel = viewModel,
110-
integrations = {
110+
leadingContent = {
111111
Spacer(Modifier.width(8.dp))
112112
},
113113
onSendMessage = {

0 commit comments

Comments
 (0)