Skip to content

Commit

Permalink
[CI] Add Attachments and Link previews related E2E tests
Browse files Browse the repository at this point in the history
  • Loading branch information
testableapple committed Feb 7, 2025
1 parent 9195931 commit 7967ceb
Show file tree
Hide file tree
Showing 19 changed files with 651 additions and 47 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/e2e-test-cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,4 @@ jobs:
if: failure()
with:
name: test_report
path: |
./**/build/reports/androidTests/*
fastlane/stream-chat-test-mock-server/logs/*
path: fastlane/stream-chat-test-mock-server/logs/*
5 changes: 2 additions & 3 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
include:
- batch: 0
- batch: 1
- batch: 2
fail-fast: false
env:
ANDROID_API_LEVEL: 34
Expand Down Expand Up @@ -77,6 +78,4 @@ jobs:
if: failure()
with:
name: test_report
path: |
./**/build/reports/androidTests/*
fastlane/stream-chat-test-mock-server/logs/*
path: fastlane/stream-chat-test-mock-server/logs/*
11 changes: 9 additions & 2 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ end

lane :build_and_run_e2e_test do |options|
build_e2e_test
run_e2e_test(batch: options[:batch], batch_count: options[:batch_count])
run_e2e_test(batch: options[:batch], batch_count: options[:batch_count], local_server: options[:local_server])
end

lane :build_e2e_test do
Expand All @@ -80,8 +80,9 @@ lane :run_e2e_test do |options|
sh("rm -rf #{allure_results_path}")
sh("adb shell rm -rf #{adb_test_results_path}/#{allure_results_path}")

start_mock_server
start_mock_server(local_server: options[:local_server])
install_test_services
upload_attachments

stream_apk_folder_path = is_ci ? '..' : "../#{test_flavor}/build/outputs/apk"
stream_app_path = "#{stream_apk_folder_path}/e2e/debug/stream-chat-android-compose-sample-e2e-debug.apk"
Expand Down Expand Up @@ -113,6 +114,12 @@ lane :run_e2e_test do |options|
UI.user_error!('Tests have failed!') if result.include?('Failures')
end

lane :upload_attachments do
['png', 'pdf'].each do |ext|
[1, 2].each { |i| sh("adb push attachments/file.#{ext} /sdcard/Download/file_#{i}.#{ext}") }
end
end

private_lane :batch_tests do |options|
if options[:batch] && options[:batch_count]
install(tool: :test_parser)
Expand Down
Binary file added fastlane/attachments/file.pdf
Binary file not shown.
Binary file added fastlane/attachments/file.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,16 @@ open class MessageListPage {
companion object {
val view = By.res("Stream_AttachmentsPicker")
val sendButton = By.res("Stream_AttachmentPickerSendButton")
val imagesTab = By.res("Stream_AttachmentPickerImagesTab")
val filesTab = By.res("Stream_AttachmentPickerFilesTab")
val mediaCaptureTab = By.res("Stream_AttachmentPickerMediaCaptureTab")
val pollsTab = By.res("Stream_AttachmentPickerPollsTab")
val sampleImage = By.res("Stream_AttachmentPickerSampleImage")
val findFilesButton = By.res("Stream_FindFilesButton")
val rootsButton = By.descContains("Show roots")
val downloadsView = By.text("Downloads")
val image1 = By.text("file_1.png")
val image2 = By.text("file_2.png")
val pdf1 = By.text("file_1.pdf")
val pdf2 = By.text("file_2.pdf")
}
}

Expand All @@ -67,6 +72,16 @@ open class MessageListPage {
val quotedMessage = By.res("Stream_QuotedMessage")
val quotedMessageAvatar = By.res("Stream_QuotedMessageAuthorAvatar")
val cancelButton = By.res("Stream_ComposerCancelButton")
val attachmentCancelIcon = By.res("Stream_AttachmentCancelIcon")
val columnWithMultipleFileAttachments = By.res("Stream_FileAttachmentPreviewContent")
val columnWithMultipleMediaAttachments = By.res("Stream_MediaAttachmentPreviewContent")
val mediaAttachment = By.res("Stream_MediaAttachmentPreviewItem")
val fileSize = By.res("Stream_FileSizeInPreview")
val fileName = By.res("Stream_FileNameInPreview")
val fileImage = MessageList.Message.fileImage
val linkPreviewImage = By.res("Stream_LinkPreviewImage")
val linkPreviewTitle = By.res("Stream_LinkPreviewTitle")
val linkPreviewDescription = By.res("Stream_LinkPreviewDescription")
}
}

Expand Down Expand Up @@ -102,16 +117,18 @@ open class MessageListPage {
val editedLabel = By.res("Stream_MessageEditedLabel")
val deletedMessage = By.res("Stream_MessageDeleted")
val messageHeaderLabel = By.res("Stream_MessageHeaderLabel") // e.g.: Pinned by you
val image = By.res("Stream_MediaContent")
val video = By.res("Stream_PlayButton")
val image = By.res("Stream_MediaContent_Image")
val video = By.res("Stream_MediaContent_Video")
val columnWithMultipleMediaAttachments = By.res("Stream_MultipleMediaAttachmentsColumn")
val fileImage = By.res("Stream_FileAttachmentImage")
val fileDescription = By.res("Stream_FileAttachmentDescription")
val fileName = By.res("Stream_FileAttachmentName")
val fileSize = By.res("Stream_FileAttachmentSize")
val fileDownloadButton = By.res("Stream_FileAttachmentDownloadButton")
val columnWithMultipleFileAttachments = By.res("Stream_MultipleFileAttachmentsColumn")
val giphy = By.res("Stream_GiphyContent")
val linkAttachmentPreview = By.res("Stream_LinkAttachmentPreview")
val linkAttachmentTitle = By.res("Stream_LinkAttachmentTitle")
val linkAttachmentDescription = By.res("Stream_LinkAttachmentDescription")
val linkPreviewImage = By.res("Stream_LinkAttachmentPreview")
val linkPreviewTitle = By.res("Stream_LinkAttachmentTitle")
val linkPreviewDescription = By.res("Stream_LinkAttachmentDescription")
}

class Reactions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.test.uiautomator.Direction
import io.getstream.chat.android.compose.pages.ChannelListPage
import io.getstream.chat.android.compose.pages.LoginPage
import io.getstream.chat.android.compose.pages.MessageListPage
import io.getstream.chat.android.compose.pages.MessageListPage.AttachmentPicker
import io.getstream.chat.android.compose.pages.MessageListPage.Composer
import io.getstream.chat.android.compose.pages.MessageListPage.MessageList
import io.getstream.chat.android.compose.pages.MessageListPage.MessageList.Message
Expand All @@ -30,6 +31,7 @@ import io.getstream.chat.android.compose.uiautomator.defaultTimeout
import io.getstream.chat.android.compose.uiautomator.device
import io.getstream.chat.android.compose.uiautomator.findObject
import io.getstream.chat.android.compose.uiautomator.findObjects
import io.getstream.chat.android.compose.uiautomator.isDisplayed
import io.getstream.chat.android.compose.uiautomator.longPress
import io.getstream.chat.android.compose.uiautomator.swipeDown
import io.getstream.chat.android.compose.uiautomator.swipeUp
Expand All @@ -38,6 +40,7 @@ import io.getstream.chat.android.compose.uiautomator.typeText
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 io.getstream.chat.android.e2e.test.mockserver.AttachmentType
import io.getstream.chat.android.e2e.test.mockserver.ReactionType
import io.getstream.chat.android.e2e.test.robots.ParticipantRobot

Expand Down Expand Up @@ -96,9 +99,19 @@ class UserRobot {
return this
}

fun tapOnSendButton(): UserRobot {
Composer.sendButton.findObject().click()
return this
}

fun tapOnAttachmentCancelIcon(): UserRobot {
Composer.attachmentCancelIcon.waitToAppear().click()
return this
}

fun sendMessage(text: String): UserRobot {
typeText(text)
Composer.sendButton.findObject().click()
tapOnSendButton()
return this
}

Expand Down Expand Up @@ -289,16 +302,37 @@ class UserRobot {
return this
}

fun uploadImage(count: Int = 1, send: Boolean = true): UserRobot {
fun uploadAttachment(type: AttachmentType, multiple: Boolean = false, send: Boolean = true): UserRobot {
val count = if (multiple) 2 else 1
repeat(count) {
Composer.attachmentsButton.waitToAppear().click()
MessageListPage.AttachmentPicker.sampleImage.waitToAppear().click()
MessageListPage.AttachmentPicker.sendButton.findObject().click()
AttachmentPicker.filesTab.waitToAppear().click()
AttachmentPicker.findFilesButton.waitToAppear().click()

if (!AttachmentPicker.downloadsView.isDisplayed()) {
AttachmentPicker.rootsButton.waitToAppear().click()
val documentsUiPackageName = device.currentPackageName
By.text("Downloads")
.hasAncestor(By.res("$documentsUiPackageName:id/roots_list"))
.waitToAppear()
.click()
}

if (type == AttachmentType.FILE) AttachmentPicker.pdf1 else AttachmentPicker.image1

if (it == 0) {
val attachment = if (type == AttachmentType.FILE) AttachmentPicker.pdf1 else AttachmentPicker.image1
attachment.waitToAppear().click()
} else {
val attachment = if (type == AttachmentType.FILE) AttachmentPicker.pdf2 else AttachmentPicker.image2
attachment.waitToAppear().click()
}
}

if (send) {
Composer.sendButton.waitToAppear().click()
}

return this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import io.getstream.chat.android.compose.uiautomator.findObjects
import io.getstream.chat.android.compose.uiautomator.height
import io.getstream.chat.android.compose.uiautomator.isDisplayed
import io.getstream.chat.android.compose.uiautomator.wait
import io.getstream.chat.android.compose.uiautomator.waitForCount
import io.getstream.chat.android.compose.uiautomator.waitForText
import io.getstream.chat.android.compose.uiautomator.waitToAppear
import io.getstream.chat.android.compose.uiautomator.waitToDisappear
Expand All @@ -40,10 +41,15 @@ import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertTrue

fun UserRobot.assertMessage(text: String, isDisplayed: Boolean = true): UserRobot {
fun UserRobot.assertMessage(
text: String,
isDisplayed: Boolean = true,
isClickable: Boolean = false,
): UserRobot {
if (isDisplayed) {
assertEquals(text, Message.text.waitToAppear().waitForText(text).text)
assertTrue(Message.text.isDisplayed())
val textLocator = if (isClickable) Message.clickableText else Message.text
assertEquals(text, textLocator.waitToAppear().waitForText(text).text)
assertTrue(textLocator.isDisplayed())
assertTrue(Message.timestamp.isDisplayed())
} else {
MessageListPage.MessageList.messages.findObjects().forEach {
Expand Down Expand Up @@ -117,15 +123,17 @@ fun UserRobot.assertEditedMessage(text: String): UserRobot {
return this
}

fun UserRobot.assertDeletedMessage(text: String, hard: Boolean = false): UserRobot {
fun UserRobot.assertDeletedMessage(text: String? = null, hard: Boolean = false): UserRobot {
if (hard) {
assertFalse(Message.deletedMessage.isDisplayed())
} else {
Message.deletedMessage.waitToAppear()
assertTrue(Message.deletedMessage.isDisplayed())
assertTrue(Message.timestamp.isDisplayed())
}
assertMessage(text, isDisplayed = false)
if (text != null) {
assertMessage(text, isDisplayed = false)
}
return this
}

Expand Down Expand Up @@ -241,13 +249,6 @@ fun UserRobot.assertScrollToBottomButton(isDisplayed: Boolean): UserRobot {
return this
}

fun UserRobot.assertLinkPreview(): UserRobot {
assertTrue(Message.linkAttachmentPreview.waitToAppear().isClickable)
assertTrue(Message.linkAttachmentTitle.findObject().text.isNotEmpty())
assertTrue(Message.linkAttachmentDescription.findObject().text.isNotEmpty())
return this
}

fun UserRobot.assertThreadIsOpen(): UserRobot {
assertTrue(ThreadPage.ThreadList.alsoSendToChannelCheckbox.waitToAppear().isDisplayed())
return this
Expand Down Expand Up @@ -375,3 +376,103 @@ fun UserRobot.assertMessages(text: String, count: Int): UserRobot {
assertEquals(count, actualCount)
return this
}

fun UserRobot.assertImage(isDisplayed: Boolean, count: Int = 1): UserRobot {
if (isDisplayed) {
assertEquals(count, Message.image.waitForCount(count).size)
if (count != 1) {
assertTrue(Message.columnWithMultipleMediaAttachments.isDisplayed())
}
} else {
assertFalse(Message.image.waitToDisappear().isDisplayed())
}
return this
}

fun UserRobot.assertVideo(isDisplayed: Boolean, count: Int = 1): UserRobot {
if (isDisplayed) {
assertEquals(count, Message.video.waitForCount(count).size)
if (count != 1) {
assertTrue(Message.columnWithMultipleMediaAttachments.waitToAppear().isDisplayed())
}
} else {
assertFalse(Message.video.waitToDisappear().isDisplayed())
}
return this
}

fun UserRobot.assertFile(isDisplayed: Boolean, count: Int = 1): UserRobot {
if (isDisplayed) {
assertEquals(count, Message.fileName.waitForCount(count).size)
assertEquals(count, Message.fileSize.findObjects().size)
assertEquals(count, Message.fileDownloadButton.findObjects().size)
assertEquals(count, Message.fileImage.waitForCount(count).size)
if (count > 1) {
assertTrue(Message.columnWithMultipleFileAttachments.isDisplayed())
}
} else {
assertFalse(Message.fileName.waitToDisappear().isDisplayed())
assertFalse(Message.fileSize.isDisplayed())
assertFalse(Message.fileImage.isDisplayed())
assertFalse(Message.fileDownloadButton.isDisplayed())
}
return this
}

fun UserRobot.assertMediaAttachmentInPreview(isDisplayed: Boolean, count: Int = 1): UserRobot {
if (isDisplayed) {
assertEquals(count, Composer.mediaAttachment.waitForCount(count).size)
assertEquals(count, Composer.attachmentCancelIcon.findObjects().size)
if (count != 1) {
assertTrue(Composer.columnWithMultipleMediaAttachments.isDisplayed())
}
} else {
assertFalse(Composer.mediaAttachment.waitToDisappear().isDisplayed())
assertFalse(Composer.attachmentCancelIcon.isDisplayed())
}
return this
}

fun UserRobot.assertFileAttachmentInPreview(isDisplayed: Boolean, count: Int = 1): UserRobot {
if (isDisplayed) {
assertTrue(Composer.fileName.waitToAppear().isDisplayed())
assertTrue(Composer.fileSize.isDisplayed())
assertTrue(Composer.fileImage.isDisplayed())
assertTrue(Composer.attachmentCancelIcon.isDisplayed())
if (count > 1) {
assertTrue(Composer.columnWithMultipleFileAttachments.isDisplayed())
}
} else {
assertFalse(Composer.fileName.waitToDisappear().isDisplayed())
assertFalse(Composer.fileSize.isDisplayed())
assertFalse(Composer.fileImage.isDisplayed())
assertFalse(Composer.attachmentCancelIcon.isDisplayed())
}
return this
}

fun UserRobot.assertLinkPreviewInMessageList(isDisplayed: Boolean): UserRobot {
if (isDisplayed) {
assertTrue(Message.linkPreviewImage.waitToAppear().isDisplayed())
assertTrue(Message.linkPreviewTitle.isDisplayed())
assertTrue(Message.linkPreviewDescription.isDisplayed())
} else {
assertFalse(Message.linkPreviewImage.waitToDisappear().isDisplayed())
assertFalse(Message.linkPreviewTitle.isDisplayed())
assertFalse(Message.linkPreviewDescription.isDisplayed())
}
return this
}

fun UserRobot.assertLinkPreviewInComposer(isDisplayed: Boolean): UserRobot {
if (isDisplayed) {
assertTrue(Composer.linkPreviewImage.waitToAppear().isDisplayed())
assertTrue(Composer.linkPreviewTitle.isDisplayed())
assertTrue(Composer.linkPreviewDescription.isDisplayed())
} else {
assertFalse(Composer.linkPreviewImage.waitToDisappear().isDisplayed())
assertFalse(Composer.linkPreviewTitle.isDisplayed())
assertFalse(Composer.linkPreviewDescription.isDisplayed())
}
return this
}
Loading

0 comments on commit 7967ceb

Please sign in to comment.