Skip to content

Commit

Permalink
[CI] Add ChannelList E2E tests (#5552)
Browse files Browse the repository at this point in the history
* [CI] Add ChannelList E2E tests

* Resolve lint issues

* Resolve syntax issue

* Fix flaky test
  • Loading branch information
testableapple authored Jan 15, 2025
1 parent 1e20a0f commit 0615579
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class UserRobot {
return this
}

fun waitForChannelListToLoad(): UserRobot {
ChannelListPage.ChannelList.channels.wait()
return this
}

fun openChannel(channelCellIndex: Int = 0): UserRobot {
ChannelListPage.ChannelList.channels.wait().findObjects()[channelCellIndex].click()
return this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.getstream.chat.android.compose.pages.ChannelListPage.ChannelList.Chann
import io.getstream.chat.android.compose.uiautomator.isDisplayed
import io.getstream.chat.android.compose.uiautomator.wait
import io.getstream.chat.android.compose.uiautomator.waitToAppear
import io.getstream.chat.android.compose.uiautomator.waitToDisappear
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
Expand All @@ -36,8 +37,8 @@ fun UserRobot.assertMessageInChannelPreview(text: String, fromCurrentUser: Boole
return this
}

fun UserRobot.assertMessageDeliveryStatus(shouldBeVisible: Boolean, shouldBeRead: Boolean = false): UserRobot {
if (shouldBeVisible) {
fun UserRobot.assertMessageDeliveryStatus(isDisplayed: Boolean, shouldBeRead: Boolean = false): UserRobot {
if (isDisplayed) {
val readStatus = if (shouldBeRead) Channel.readStatusIsRead else Channel.readStatusIsSent
assertTrue(readStatus.wait().isDisplayed())
} else {
Expand All @@ -46,3 +47,12 @@ fun UserRobot.assertMessageDeliveryStatus(shouldBeVisible: Boolean, shouldBeRead
}
return this
}

fun UserRobot.assertMessagePreviewTimestamp(isDisplayed: Boolean = true): UserRobot {
if (isDisplayed) {
assertTrue(Channel.timestamp.waitToAppear().isDisplayed())
} else {
assertFalse(Channel.timestamp.waitToDisappear().isDisplayed())
}
return this
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ fun UserRobot.assertComposerSize(isChangeable: Boolean): UserRobot {
} else {
val text = "1\n2\n3\n4\n5\n6"
typeText(text)
sleep(500)
initialComposerHeight = composer.findObject().height
typeText("${text}\n7")
assertEquals(initialComposerHeight, composer.findObject().height)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ package io.getstream.chat.android.compose.tests
import io.getstream.chat.android.compose.robots.assertChannelAvatar
import io.getstream.chat.android.compose.robots.assertMessageDeliveryStatus
import io.getstream.chat.android.compose.robots.assertMessageInChannelPreview
import io.getstream.chat.android.compose.robots.assertMessagePreviewTimestamp
import io.getstream.chat.android.compose.uiautomator.device
import io.getstream.chat.android.compose.uiautomator.disableInternetConnection
import io.getstream.chat.android.compose.uiautomator.enableInternetConnection
import io.qameta.allure.kotlin.Allure.step
import io.qameta.allure.kotlin.AllureId
import org.junit.Ignore
import org.junit.Test

class ChannelListTests : StreamTestCase() {
Expand All @@ -31,9 +36,7 @@ class ChannelListTests : StreamTestCase() {
@Test
fun test_channelPreviewUpdates_whenParticipantSendsMessage() {
step("GIVEN user opens a channel") {
userRobot
.login()
.openChannel()
userRobot.login().openChannel()
}
step("WHEN participant sends a message") {
participantRobot.sendMessage(sampleText)
Expand All @@ -44,7 +47,7 @@ class ChannelListTests : StreamTestCase() {
step("THEN user observes the new message in preview") {
userRobot
.assertMessageInChannelPreview(sampleText, false)
.assertMessageDeliveryStatus(shouldBeVisible = false)
.assertMessageDeliveryStatus(isDisplayed = false)
.assertChannelAvatar()
}
}
Expand All @@ -53,9 +56,7 @@ class ChannelListTests : StreamTestCase() {
@Test
fun test_channelPreviewUpdates_whenUserSendsMessage() {
step("GIVEN user opens a channel") {
userRobot
.login()
.openChannel()
userRobot.login().openChannel()
}
step("WHEN user sends a message") {
userRobot.sendMessage("Test")
Expand All @@ -66,14 +67,203 @@ class ChannelListTests : StreamTestCase() {
step("THEN user observes the new message in preview") {
userRobot
.assertMessageInChannelPreview(sampleText, true)
.assertMessageDeliveryStatus(shouldBeVisible = true, shouldBeRead = false)
.assertMessageDeliveryStatus(isDisplayed = true, shouldBeRead = false)
.assertChannelAvatar()
}
step("WHEN participant reads the message") {
participantRobot.readMessage()
}
step("THEN user observes the new message in preview") {
userRobot.assertMessageDeliveryStatus(shouldBeVisible = true, shouldBeRead = true)
userRobot.assertMessageDeliveryStatus(isDisplayed = true, shouldBeRead = true)
}
}

@AllureId("6679")
@Test
fun test_channelPreviewUpdates_whenUserIsOfflineAndParticipantSendsMessage() {
step("GIVEN user opens a channel list") {
userRobot.login().waitForChannelListToLoad()
}
step("AND user goes offline") {
device.disableInternetConnection()
}
step("WHEN participant sends a message") {
participantRobot.sendMessage(sampleText)
}
step("AND user goes back online") {
device.enableInternetConnection()
}
step("THEN user observes the new message in preview") {
userRobot.assertMessageInChannelPreview(sampleText, false)
}
}

@AllureId("5785")
@Test
fun test_errorMessageIsNotShownInChannelPreview() {
step("GIVEN user opens the channel") {
userRobot.login().openChannel()
}
step("AND participant sends a message") {
participantRobot.sendMessage(sampleText)
}
step("WHEN user sends a message with invalid command") {
userRobot.sendMessage("/test")
}
step("AND user goes back to the channel list") {
userRobot.tapOnBackButton()
}
step("THEN the error message is not shown in preview") {
userRobot
.assertMessageInChannelPreview(sampleText, false)
.assertMessagePreviewTimestamp()
}
}

@AllureId("5796")
@Ignore("https://linear.app/stream/issue/AND-218")
@Test
fun test_channelPreviewShowsNoMessages_whenChannelIsEmpty() {
step("WHEN user opens channel list") {
userRobot.login()
}
step("AND the channel has no messages") {
// No actions required as the channel is empty by default
}
step("THEN the channel preview shows No messages") {
userRobot.assertMessageInChannelPreview("No messages", fromCurrentUser = false)
}
step("AND the message timestamp is hidden") {
userRobot.assertMessagePreviewTimestamp(isDisplayed = false)
}
}

@AllureId("5798")
@Ignore("https://linear.app/stream/issue/AND-218")
@Test
fun test_channelPreviewShowsNoMessages_whenTheOnlyMessageInChannelIsDeleted() {
step("GIVEN user opens the channel") {
userRobot.login().openChannel()
}
step("AND participant sends a message") {
participantRobot.sendMessage(sampleText)
}
step("AND participant deletes the message") {
participantRobot.deleteMessage()
}
step("WHEN user goes back to the channel list") {
userRobot.tapOnBackButton()
}
step("THEN the channel preview shows No messages") {
userRobot.assertMessageInChannelPreview("No messages", fromCurrentUser = false)
}
step("AND the message timestamp is hidden") {
userRobot.assertMessagePreviewTimestamp(isDisplayed = false)
}
}

@AllureId("5821")
@Test
fun test_channelPreviewShowsPreviousMessage_whenLastMessageIsDeleted() {
val oldMessage = "Old"
val newMessage = "New"

step("GIVEN user opens the channel") {
userRobot.login().openChannel()
}
step("AND participant sends 2 messages") {
participantRobot
.sendMessage(oldMessage)
.sendMessage(newMessage)
}
step("AND participant deletes the last message") {
participantRobot.deleteMessage()
}
step("WHEN user goes back to the channel list") {
userRobot.tapOnBackButton()
}
step("THEN the channel preview shows previous message") {
userRobot.assertMessageInChannelPreview(oldMessage, fromCurrentUser = false)
}
step("AND the message timestamp is shown") {
userRobot.assertMessagePreviewTimestamp(isDisplayed = true)
}
}

@AllureId("5799")
@Test
fun test_channelPreviewIsNotUpdated_whenThreadReplyIsSent() {
val channelMessage = "Channel message"
val threadReply = "Thread reply"

step("GIVEN user opens the channel") {
userRobot.login().openChannel()
}
step("AND participant sends a message") {
participantRobot.sendMessage(channelMessage)
}
step("AND participant adds thread reply to this message") {
participantRobot.sendMessageInThread(threadReply)
}
step("WHEN user goes back to the channel list") {
userRobot.tapOnBackButton()
}
step("THEN the channel preview shows the channel message preview") {
userRobot.assertMessageInChannelPreview(channelMessage, fromCurrentUser = false)
}
step("AND the message timestamp is shown") {
userRobot.assertMessagePreviewTimestamp(isDisplayed = true)
}
}

@AllureId("6680")
@Test
fun test_channelPreviewIsUpdated_whenThreadReplyIsSentAlsoInTheChannel() {
val channelMessage = "Channel message"
val threadReply = "Thread reply"

step("GIVEN user opens the channel") {
userRobot.login().openChannel()
}
step("AND user sends a message") {
userRobot.sendMessage(channelMessage)
}
step("AND user adds thread reply to this message also in the channel") {
userRobot.openThread().sendMessageInThread(threadReply, alsoSendInChannel = true)
}
step("WHEN user goes back to the channel list") {
userRobot.moveToChannelListFromThreadList()
}
step("THEN the channel preview shows the thread message preview") {
userRobot.assertMessageInChannelPreview(threadReply, fromCurrentUser = true)
}
step("AND the message timestamp is shown") {
userRobot.assertMessagePreviewTimestamp(isDisplayed = true)
}
}

@AllureId("5820")
@Test
fun test_channelPreviewIsUpdated_whenPreviewMessageIsEdited() {
val editedMessage = "edited message"

step("GIVEN user opens the channel") {
userRobot.login().openChannel()
}
step("AND participant sends a message") {
participantRobot.sendMessage(sampleText)
}
step("WHEN participant edits the message") {
participantRobot.editMessage(editedMessage)
}
step("AND user goes back to the channel list") {
userRobot.tapOnBackButton()
}
step("THEN the channel preview shows edited message") {
userRobot.assertMessageInChannelPreview(editedMessage, fromCurrentUser = false)
}
step("AND the message timestamp is shown") {
userRobot.assertMessagePreviewTimestamp(isDisplayed = true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class GiphyTests : StreamTestCase() {
}
step("AND the previous message has timestamp and delivery status shown") {
userRobot
.assertMessageDeliveryStatus(shouldBeVisible = true)
.assertMessageDeliveryStatus(isDisplayed = true)
.assertMessageTimestamps(count = 1)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ class MessageListTests : StreamTestCase() {
@Test
fun test_messageListUpdates_whenParticipantSendsMessage() {
step("GIVEN user opens a channel") {
userRobot
.login()
.openChannel()
userRobot.login().openChannel()
}
step("WHEN participant sends a message") {
participantRobot.sendMessage(sampleText)
Expand All @@ -75,9 +73,7 @@ class MessageListTests : StreamTestCase() {
@Test
fun test_messageListUpdates_whenUserSendsMessage() {
step("GIVEN user opens a channel") {
userRobot
.login()
.openChannel()
userRobot.login().openChannel()
}
step("WHEN user sends a message") {
userRobot.sendMessage(sampleText)
Expand Down Expand Up @@ -257,10 +253,8 @@ class MessageListTests : StreamTestCase() {
@Test
fun test_typingIndicator() {
step("GIVEN user opens the channel") {
userRobot
.login()
.openChannel()
.sendMessage(sampleText)
backendRobot.generateChannels(channelsCount = 1, messagesCount = 1)
userRobot.login().openChannel()
}
step("WHEN participant starts typing") {
participantRobot.startTyping()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
public final class io/getstream/chat/android/compose/uiautomator/ActionsKt {
public static final fun disableInternetConnection (Landroidx/test/uiautomator/UiDevice;)V
public static final fun dumpWindowHierarchy (Landroidx/test/uiautomator/UiDevice;)V
public static final fun enableInternetConnection (Landroidx/test/uiautomator/UiDevice;)V
public static final fun goToBackground (Landroidx/test/uiautomator/UiDevice;)V
public static final fun goToForeground (Landroidx/test/uiautomator/UiDevice;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.content.Intent
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiObject2
import io.getstream.chat.android.e2e.test.mockserver.mockServerUrl
import java.io.ByteArrayOutputStream

public fun UiDevice.startApp() {
val intent = testContext.packageManager.getLaunchIntentForPackage(packageName)
Expand Down Expand Up @@ -99,3 +100,9 @@ public fun UiDevice.disableInternetConnection() {
executeShellCommand("svc data disable")
executeShellCommand("svc wifi disable")
}

public fun UiDevice.dumpWindowHierarchy() {
val outputStream = ByteArrayOutputStream()
device.dumpWindowHierarchy(outputStream)
println(outputStream.toString("UTF-8"))
}

0 comments on commit 0615579

Please sign in to comment.