Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CI] Add ChannelList E2E tests #5552

Merged
merged 7 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"))
}
Loading