Regression test suite.
Affected: UI tests, Reply, ReplyAll and Forward message functionality (buttons are enabled after message is decrypted). MAILAND-1041
This commit is contained in:
parent
418429d78e
commit
c4a0f26283
|
@ -30,6 +30,8 @@ stages:
|
|||
#####################
|
||||
.detekt-analysis-common:
|
||||
stage: analyze
|
||||
except:
|
||||
- schedules
|
||||
tags:
|
||||
- android
|
||||
script:
|
||||
|
@ -52,6 +54,7 @@ detekt analysis:
|
|||
- release
|
||||
- prerelease
|
||||
- tags
|
||||
- schedules
|
||||
|
||||
build debug:
|
||||
stage: build
|
||||
|
@ -67,6 +70,8 @@ build debug:
|
|||
|
||||
build prerelease:
|
||||
stage: build
|
||||
except:
|
||||
- schedules
|
||||
only:
|
||||
- prerelease
|
||||
- tags
|
||||
|
@ -81,6 +86,8 @@ build prerelease:
|
|||
|
||||
build release:
|
||||
stage: build
|
||||
except:
|
||||
- schedules
|
||||
only:
|
||||
- releases
|
||||
tags:
|
||||
|
@ -95,6 +102,8 @@ build release:
|
|||
|
||||
unit tests:
|
||||
stage: test
|
||||
except:
|
||||
- schedules
|
||||
tags:
|
||||
- android
|
||||
script:
|
||||
|
@ -103,6 +112,8 @@ unit tests:
|
|||
|
||||
firebase tests:
|
||||
stage: test
|
||||
except:
|
||||
- schedules
|
||||
script:
|
||||
- wget --quiet --output-document=/tmp/google-cloud-sdk.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/google-cloud-sdk.tar.gz
|
||||
- mkdir -p /opt
|
||||
|
@ -121,13 +132,57 @@ firebase tests:
|
|||
--test-targets "class ch.protonmail.android.uitests.tests.suites.SmokeSuite"
|
||||
--use-orchestrator
|
||||
--num-flaky-test-attempts=2
|
||||
--timeout 30m
|
||||
|
||||
#UI tests:
|
||||
# stage: test
|
||||
# tags:
|
||||
# - android
|
||||
# script:
|
||||
# - ./gradlew eBDTOB -PUSER1="$USER1" -PUSER2="$USER2" -PUSER3="$USER3" -PUSER4="$USER4" -PRECIPIENT1="$RECIPIENT1" -PRECIPIENT2="$RECIPIENT2" -PRECIPIENT3="$RECIPIENT3" -PRECIPIENT4="$RECIPIENT4" -PBROWSERSTACK_USER="$BROWSERSTACK_USER" -PBROWSERSTACK_KEY="$BROWSERSTACK_KEY"
|
||||
firebase regression tests:
|
||||
stage: test
|
||||
rules:
|
||||
- if: '$TEST_TYPE == "regression"'
|
||||
script:
|
||||
- wget --quiet --output-document=/tmp/google-cloud-sdk.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/google-cloud-sdk.tar.gz
|
||||
- mkdir -p /opt
|
||||
- tar zxf /tmp/google-cloud-sdk.tar.gz --directory /opt
|
||||
- /opt/google-cloud-sdk/install.sh --quiet
|
||||
- source /opt/google-cloud-sdk/path.bash.inc
|
||||
- gcloud components update
|
||||
- echo $CLOUD_PROJECT_ID_MAIL
|
||||
- gcloud config set project $CLOUD_PROJECT_ID_MAIL
|
||||
- echo $SERVICE_ACCOUNT_MAIL > /tmp/service-account.json
|
||||
- gcloud auth activate-service-account --key-file /tmp/service-account.json
|
||||
- export CLOUDSDK_CORE_DISABLE_PROMPTS=1
|
||||
- gcloud beta --quiet firebase test android run
|
||||
--app app/build/outputs/apk/beta/debug/ProtonMail-Android-${VERSION_NAME}-beta-debug.apk
|
||||
--test app/build/outputs/apk/androidTest/beta/debug/ProtonMail-Android-${VERSION_NAME}-beta-debug-androidTest.apk
|
||||
--device model=Pixel2,version=$API_LEVEL
|
||||
--test-targets "class ch.protonmail.android.uitests.tests.suites.RegressionSuite"
|
||||
--use-orchestrator
|
||||
--num-uniform-shards=20
|
||||
--timeout 1h
|
||||
|
||||
firebase feature tests:
|
||||
stage: test
|
||||
rules:
|
||||
- if: '$TEST_TYPE == "feature"'
|
||||
script:
|
||||
- wget --quiet --output-document=/tmp/google-cloud-sdk.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/google-cloud-sdk.tar.gz
|
||||
- mkdir -p /opt
|
||||
- tar zxf /tmp/google-cloud-sdk.tar.gz --directory /opt
|
||||
- /opt/google-cloud-sdk/install.sh --quiet
|
||||
- source /opt/google-cloud-sdk/path.bash.inc
|
||||
- gcloud components update
|
||||
- echo $CLOUD_PROJECT_ID_MAIL
|
||||
- gcloud config set project $CLOUD_PROJECT_ID_MAIL
|
||||
- echo $SERVICE_ACCOUNT_MAIL > /tmp/service-account.json
|
||||
- gcloud auth activate-service-account --key-file /tmp/service-account.json
|
||||
- export CLOUDSDK_CORE_DISABLE_PROMPTS=1
|
||||
- gcloud --quiet firebase test android run
|
||||
--app app/build/outputs/apk/beta/debug/ProtonMail-Android-${VERSION_NAME}-beta-debug.apk
|
||||
--test app/build/outputs/apk/androidTest/beta/debug/ProtonMail-Android-${VERSION_NAME}-beta-debug-androidTest.apk
|
||||
--device model=Pixel2,version=$API_LEVEL
|
||||
--test-targets "class ch.protonmail.android.uitests.tests.$TEST_CLASS"
|
||||
--use-orchestrator
|
||||
--num-flaky-test-attempts=1
|
||||
--timeout 1h
|
||||
|
||||
include:
|
||||
- project: 'translations/generator'
|
||||
|
@ -147,13 +202,18 @@ i18n-sync-crowdin:
|
|||
variables:
|
||||
I18N_SYNC_CROWDIN_PROJECT: 'android-mail'
|
||||
extends: .i18n-sync-crowdin-shared
|
||||
except:
|
||||
variables:
|
||||
- $TEST_TYPE == "feature" || $TEST_TYPE == "regression"
|
||||
|
||||
i18n-commit-locales:
|
||||
stage: bot-i18n
|
||||
variables:
|
||||
I18N_COMMIT_CROWDIN_PROJECT: 'android-mail'
|
||||
extends: .i18n-commit-locales-shared
|
||||
|
||||
except:
|
||||
variables:
|
||||
- $TEST_TYPE == "feature" || $TEST_TYPE == "regression"
|
||||
|
||||
release-publish-github:
|
||||
stage: manual-release
|
||||
|
@ -185,5 +245,3 @@ publish-github:
|
|||
RELEASE_GITHUB_REPOSITORY: ProtonMail/proton-mail-android
|
||||
RELEASE_GITHUB_BRANCH: 'release'
|
||||
extends: .release-make-release
|
||||
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ import ch.protonmail.android.utils.ui.MODE_ACCORDION
|
|||
import ch.protonmail.android.utils.ui.dialogs.DialogUtils.Companion.showDeleteConfirmationDialog
|
||||
import ch.protonmail.android.utils.ui.dialogs.DialogUtils.Companion.showInfoDialogWithTwoButtons
|
||||
import ch.protonmail.android.utils.ui.dialogs.DialogUtils.Companion.showSignedInSnack
|
||||
import ch.protonmail.android.views.MessageActionButton
|
||||
import ch.protonmail.android.views.PMWebViewClient
|
||||
import ch.protonmail.android.worker.KEY_POST_LABEL_WORKER_RESULT_ERROR
|
||||
import ch.protonmail.android.worker.PostLabelWorker
|
||||
|
@ -205,6 +206,10 @@ internal class MessageDetailsActivity :
|
|||
} else {
|
||||
continueSetup()
|
||||
}
|
||||
|
||||
findViewById<MessageActionButton>(R.id.reply).isEnabled = false
|
||||
findViewById<MessageActionButton>(R.id.reply_all).isEnabled = false
|
||||
findViewById<MessageActionButton>(R.id.forward).isEnabled = false
|
||||
}
|
||||
|
||||
private fun continueSetup() {
|
||||
|
@ -870,6 +875,10 @@ internal class MessageDetailsActivity :
|
|||
UiUtil.showInfoSnack(mSnackLayout, this@MessageDetailsActivity, R.string.decryption_error_desc).show()
|
||||
return
|
||||
}
|
||||
findViewById<MessageActionButton>(R.id.reply).isEnabled = true
|
||||
findViewById<MessageActionButton>(R.id.reply_all).isEnabled = true
|
||||
findViewById<MessageActionButton>(R.id.forward).isEnabled = true
|
||||
|
||||
messageExpandableAdapter.setMessageData(message)
|
||||
messageExpandableAdapter.refreshRecipientsLayout()
|
||||
if (viewModel.refreshedKeys) {
|
||||
|
|
|
@ -277,7 +277,7 @@ class ProtonRetrofitSecure(
|
|||
endpointUri,
|
||||
TEN_SECONDS,
|
||||
interceptor,
|
||||
HttpLoggingInterceptor.Level.BODY,
|
||||
HttpLoggingInterceptor.Level.BASIC,
|
||||
spec,
|
||||
serverTimeInterceptor
|
||||
)
|
||||
|
|
|
@ -52,7 +52,6 @@ class AddContactRobot {
|
|||
|
||||
private fun save(): ContactsRobot {
|
||||
UIActions.id.clickViewWithId(R.id.action_save)
|
||||
UIActions.wait.forViewWithText(R.string.contact_saved)
|
||||
return ContactsRobot()
|
||||
}
|
||||
}
|
|
@ -123,8 +123,12 @@ object ContactsMatchers {
|
|||
return object : BoundedMatcher<RecyclerView.ViewHolder,
|
||||
RecyclerView.ViewHolder>(RecyclerView.ViewHolder::class.java) {
|
||||
|
||||
val contactGroupsList = ArrayList<String>()
|
||||
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("With contact group name: \"$name\"")
|
||||
description.appendText("Here is the actual list of groups:\n")
|
||||
contactGroupsList.forEach { description.appendText(" - \"$it\"\n") }
|
||||
}
|
||||
|
||||
override fun matchesSafely(item: RecyclerView.ViewHolder): Boolean {
|
||||
|
@ -135,6 +139,7 @@ object ContactsMatchers {
|
|||
.findViewById<TextView>(R.id.contact_name).text.toString()
|
||||
val groupMembersCount = contactDataParent
|
||||
.findViewById<TextView>(R.id.contact_email).text.toString()
|
||||
contactGroupsList.add(groupName)
|
||||
return groupName == name && groupMembersCount == membersCount
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.hamcrest.CoreMatchers.instanceOf
|
|||
/**
|
||||
* [ContactsRobot] class contains actions and verifications for Contacts functionality.
|
||||
*/
|
||||
open class ContactsRobot {
|
||||
class ContactsRobot {
|
||||
|
||||
fun addContact(): AddContactRobot {
|
||||
UIActions.allOf.clickMatchedView(
|
||||
|
@ -60,7 +60,7 @@ open class ContactsRobot {
|
|||
|
||||
|
||||
fun openOptionsMenu(): ContactsMoreOptions {
|
||||
UIActions.system.clickMoreOptionsButton()
|
||||
UIActions.system.waitForMoreOptionsButton().click()
|
||||
return ContactsMoreOptions()
|
||||
}
|
||||
|
||||
|
@ -81,10 +81,10 @@ open class ContactsRobot {
|
|||
}
|
||||
|
||||
fun clickContactByEmail(email: String): ContactDetailsRobot {
|
||||
UIActions.wait.forViewWithId(contactsRecyclerView)
|
||||
UIActions.recyclerView
|
||||
.waitForBeingPopulated(contactsRecyclerView)
|
||||
.waitForItemWithIdAndText(contactsRecyclerView, R.id.contact_email, email)
|
||||
.clickContactItem(contactsRecyclerView, email)
|
||||
.clickContactItemWithRetry(contactsRecyclerView, email)
|
||||
return ContactDetailsRobot()
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,12 @@ open class ContactsRobot {
|
|||
return ContactDetailsRobot()
|
||||
}
|
||||
|
||||
fun navigateUpToInbox(): InboxRobot {
|
||||
UIActions.wait.forViewWithId(contactsRecyclerView)
|
||||
UIActions.system.clickHamburgerOrUpButton()
|
||||
return InboxRobot()
|
||||
}
|
||||
|
||||
fun clickSendMessageToContact(contactName: String): ComposerRobot {
|
||||
UIActions.recyclerView
|
||||
.waitForBeingPopulated(contactsRecyclerView)
|
||||
|
@ -109,6 +115,12 @@ open class ContactsRobot {
|
|||
|
||||
class ContactsGroupView {
|
||||
|
||||
fun navigateUpToInbox(): InboxRobot {
|
||||
UIActions.wait.forViewWithId(contactGroupsRecyclerView)
|
||||
UIActions.system.clickHamburgerOrUpButton()
|
||||
return InboxRobot()
|
||||
}
|
||||
|
||||
fun clickGroup(withName: String): GroupDetailsRobot {
|
||||
UIActions.recyclerView
|
||||
.waitForBeingPopulated(R.id.contactGroupsRecyclerView)
|
||||
|
@ -117,10 +129,10 @@ open class ContactsRobot {
|
|||
}
|
||||
|
||||
fun clickGroupWithMembersCount(name: String, membersCount: String): GroupDetailsRobot {
|
||||
UIActions.wait.forViewWithId(contactGroupsRecyclerView)
|
||||
UIActions.recyclerView
|
||||
.waitForBeingPopulated(contactGroupsRecyclerView)
|
||||
.waitForItemWithIdAndText(contactGroupsRecyclerView, R.id.contact_name, name)
|
||||
.clickOnRecyclerViewMatchedItem(
|
||||
.clickOnRecyclerViewMatchedItemWithRetry(
|
||||
contactGroupsRecyclerView,
|
||||
withContactGroupNameAndMembersCount(name, membersCount)
|
||||
)
|
||||
|
@ -177,19 +189,17 @@ open class ContactsRobot {
|
|||
|
||||
fun contactExists(name: String, email: String) {
|
||||
UIActions.recyclerView
|
||||
.waitForBeingPopulated(contactsRecyclerView)
|
||||
.scrollToRecyclerViewMatchedItem(contactsRecyclerView, withContactNameAndEmail(name, email))
|
||||
}
|
||||
|
||||
fun contactDoesNotExists(name: String, email: String) {
|
||||
UIActions.wait.forViewWithId(contactsRecyclerView)
|
||||
UIActions.recyclerView
|
||||
.waitForBeingPopulated(contactsRecyclerView)
|
||||
.checkDoesNotContainContact(contactsRecyclerView, name, email)
|
||||
}
|
||||
|
||||
fun contactsRefreshed() {
|
||||
UIActions.wait.forViewWithText(R.string.fetching_contacts)
|
||||
UIActions.wait.untilViewWithIdIsGone(R.id.progress_bar)
|
||||
UIActions.wait.untilViewWithIdDisabled(R.id.progress_bar)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ open class GroupDetailsRobot {
|
|||
}
|
||||
|
||||
private fun confirmDeletion(): ContactsRobot {
|
||||
UIActions.system.clickPositiveDialogButton()
|
||||
UIActions.wait.forViewWithId(android.R.id.button1).click()
|
||||
return ContactsRobot()
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import ch.protonmail.android.R
|
|||
import ch.protonmail.android.uitests.robots.mailbox.inbox.InboxRobot
|
||||
import ch.protonmail.android.uitests.testsHelper.UIActions
|
||||
import ch.protonmail.android.uitests.testsHelper.User
|
||||
import ch.protonmail.android.uitests.testsHelper.click
|
||||
import ch.protonmail.android.uitests.testsHelper.insert
|
||||
|
||||
/**
|
||||
|
@ -88,12 +89,12 @@ class LoginRobot {
|
|||
}
|
||||
|
||||
private fun confirm2Fa(): InboxRobot {
|
||||
UIActions.system.clickPositiveDialogButton()
|
||||
UIActions.wait.forViewWithId(android.R.id.button1).click()
|
||||
return InboxRobot()
|
||||
}
|
||||
|
||||
private fun confirm2FaMailbox(): MailboxPasswordRobot {
|
||||
UIActions.system.clickPositiveDialogButton()
|
||||
UIActions.wait.untilViewWithIdEnabled(android.R.id.button1).click()
|
||||
return MailboxPasswordRobot()
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import ch.protonmail.android.uitests.robots.mailbox.search.SearchRobot
|
|||
import ch.protonmail.android.uitests.robots.menu.MenuRobot
|
||||
import ch.protonmail.android.uitests.testsHelper.UIActions
|
||||
import ch.protonmail.android.uitests.testsHelper.click
|
||||
import ch.protonmail.android.uitests.testsHelper.swipeViewDown
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.instanceOf
|
||||
|
||||
|
@ -75,7 +76,7 @@ interface MailboxRobotInterface {
|
|||
}
|
||||
|
||||
fun menuDrawer(): MenuRobot {
|
||||
UIActions.wait.forViewWithId(drawerLayoutId)
|
||||
UIActions.wait.forViewWithId(drawerLayoutId, 15_000L)
|
||||
UIActions.id.openMenuDrawerWithId(drawerLayoutId)
|
||||
return MenuRobot()
|
||||
}
|
||||
|
@ -88,13 +89,6 @@ interface MailboxRobotInterface {
|
|||
}
|
||||
|
||||
fun clickMessageBySubject(subject: String): MessageRobot {
|
||||
UIActions.wait
|
||||
.forViewByViewInteraction(onView(
|
||||
allOf(
|
||||
instanceOf(ImageView::class.java),
|
||||
withParent(withId(R.id.messages_list_view))
|
||||
)
|
||||
))
|
||||
UIActions.wait
|
||||
.untilViewByViewInteractionIsGone(onView(
|
||||
allOf(
|
||||
|
@ -108,6 +102,11 @@ interface MailboxRobotInterface {
|
|||
return MessageRobot()
|
||||
}
|
||||
|
||||
fun refreshMessageList(): Any {
|
||||
UIActions.wait.forViewWithId(messagesRecyclerViewId).swipeViewDown()
|
||||
return Any()
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains all the validations that can be performed by [InboxRobot].
|
||||
*/
|
||||
|
|
|
@ -33,6 +33,7 @@ import ch.protonmail.android.uitests.testsHelper.TestData
|
|||
import ch.protonmail.android.uitests.testsHelper.UIActions
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.setValueInNumberPicker
|
||||
import ch.protonmail.android.uitests.testsHelper.click
|
||||
import ch.protonmail.android.uitests.testsHelper.insert
|
||||
import ch.protonmail.android.uitests.testsHelper.type
|
||||
import org.hamcrest.CoreMatchers.`is`
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
|
@ -54,15 +55,21 @@ class ComposerRobot {
|
|||
.body(body)
|
||||
.sendToContact()
|
||||
|
||||
fun sendMessageToGroup(subject: String, body: String): ContactsRobot.ContactsGroupView {
|
||||
subject(subject)
|
||||
.body(body)
|
||||
.sendToContact()
|
||||
return ContactsRobot.ContactsGroupView()
|
||||
}
|
||||
|
||||
fun forwardMessage(to: String, body: String): MessageRobot =
|
||||
recipients(to)
|
||||
.body(body)
|
||||
.forward()
|
||||
|
||||
fun changeSubjectAndForwardMessage(to: String, subject: String, body: String): MessageRobot =
|
||||
fun changeSubjectAndForwardMessage(to: String, subject: String): MessageRobot =
|
||||
recipients(to)
|
||||
.subject(subject)
|
||||
.body(body)
|
||||
.updateSubject(subject)
|
||||
.forward()
|
||||
|
||||
fun sendMessageTOandCC(to: String, cc: String, subject: String, body: String): InboxRobot =
|
||||
|
@ -135,6 +142,25 @@ class ComposerRobot {
|
|||
.addImageCaptureAttachment(logoDrawable)
|
||||
.send()
|
||||
|
||||
fun sendMessageEOAndExpiryTimeWithAttachmentAndConfirmation(
|
||||
to: String,
|
||||
subject: String,
|
||||
body: String,
|
||||
days: Int,
|
||||
password: String,
|
||||
hint: String
|
||||
): InboxRobot =
|
||||
composeMessage(to, subject, body)
|
||||
.setMessagePassword()
|
||||
.definePasswordWithHint(password, hint)
|
||||
.messageExpiration()
|
||||
.setExpirationInDays(days)
|
||||
.hideExpirationView()
|
||||
.attachments()
|
||||
.addImageCaptureAttachment(logoDrawable)
|
||||
.sendWithNotSupportedExpiryConfirmation()
|
||||
.sendAnyway()
|
||||
|
||||
fun sendMessageCameraCaptureAttachment(to: String, subject: String, body: String): InboxRobot =
|
||||
composeMessage(to, subject, body)
|
||||
.attachments()
|
||||
|
@ -168,7 +194,8 @@ class ComposerRobot {
|
|||
.addImageCaptureAttachment(logoDrawable)
|
||||
}
|
||||
|
||||
fun editBodyAndReply(messageBody: String): MessageRobot = body(messageBody).reply()
|
||||
fun editBodyAndReply(currentBody: String, newBody: String): MessageRobot =
|
||||
body(newBody).reply()
|
||||
|
||||
fun clickUpButton(): ComposerRobot {
|
||||
UIActions.system.clickHamburgerOrUpButton()
|
||||
|
@ -191,6 +218,7 @@ class ComposerRobot {
|
|||
.body(body)
|
||||
|
||||
fun recipients(email: String): ComposerRobot {
|
||||
UIActions.wait.forViewWithId(R.id.to_recipients)
|
||||
UIActions.id.typeTextIntoFieldWithIdAndPressImeAction(R.id.to_recipients, email)
|
||||
return this
|
||||
}
|
||||
|
@ -222,13 +250,18 @@ class ComposerRobot {
|
|||
return this
|
||||
}
|
||||
|
||||
fun updateSubject(text: String): ComposerRobot {
|
||||
UIActions.wait.forViewWithId(R.id.message_title).insert(text)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun body(text: String): ComposerRobot {
|
||||
UIActions.id.insertTextIntoFieldWithId(R.id.message_body, text)
|
||||
UIActions.wait.forViewWithId(R.id.message_body).insert(text)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun showAdditionalRows(): ComposerRobot {
|
||||
UIActions.id.clickViewWithId(R.id.show_additional_rows)
|
||||
UIActions.wait.forViewWithId(R.id.show_additional_rows).click()
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -278,10 +311,9 @@ class ComposerRobot {
|
|||
}
|
||||
|
||||
private fun waitForConditionAndSend() {
|
||||
UIActions.wait.forViewWithId(R.id.tokenPgpText)
|
||||
UIActions.wait.untilViewWithIdIsGone(R.id.text1)
|
||||
UIActions.wait.untilViewWithIdEnabled(sendMessageId)
|
||||
UIActions.id.clickViewWithId(sendMessageId)
|
||||
UIActions.wait.forViewWithText(R.string.message_sent)
|
||||
UIActions.wait.untilViewWithTextIsGone(R.string.message_sent)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,6 +45,11 @@ class DraftsRobot : MailboxRobotInterface {
|
|||
return this
|
||||
}
|
||||
|
||||
override fun refreshMessageList(): DraftsRobot {
|
||||
super.refreshMessageList()
|
||||
return this
|
||||
}
|
||||
|
||||
fun moreOptions(): DraftsRobot {
|
||||
UIActions.system.clickMoreOptionsButton()
|
||||
return this
|
||||
|
|
|
@ -22,6 +22,7 @@ import ch.protonmail.android.R
|
|||
import ch.protonmail.android.uitests.robots.mailbox.MailboxRobotInterface
|
||||
import ch.protonmail.android.uitests.robots.mailbox.MoveToFolderRobotInterface
|
||||
import ch.protonmail.android.uitests.robots.mailbox.SelectionStateRobotInterface
|
||||
import ch.protonmail.android.uitests.robots.mailbox.sent.SentRobot
|
||||
import ch.protonmail.android.uitests.testsHelper.UIActions
|
||||
|
||||
/**
|
||||
|
@ -45,6 +46,11 @@ class InboxRobot : MailboxRobotInterface {
|
|||
return this
|
||||
}
|
||||
|
||||
override fun refreshMessageList(): SentRobot {
|
||||
super.refreshMessageList()
|
||||
return SentRobot()
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains all the validations that can be performed by [InboxRobot].
|
||||
*/
|
||||
|
|
|
@ -57,18 +57,20 @@ class MessageRobot {
|
|||
}
|
||||
|
||||
fun reply(): ComposerRobot {
|
||||
UIActions.wait.forViewWithId(R.id.reply).click()
|
||||
UIActions.wait.forViewWithId(R.id.reply)
|
||||
UIActions.wait.untilViewWithIdEnabled(R.id.reply).click()
|
||||
return ComposerRobot()
|
||||
}
|
||||
|
||||
fun replyAll(): ComposerRobot {
|
||||
UIActions.wait.forViewWithId(R.id.reply_all).click()
|
||||
UIActions.wait.forViewWithId(R.id.reply_all)
|
||||
UIActions.wait.untilViewWithIdEnabled(R.id.reply_all).click()
|
||||
return ComposerRobot()
|
||||
}
|
||||
|
||||
fun forward(): ComposerRobot {
|
||||
UIActions.wait.forViewWithId(R.id.message_body)
|
||||
UIActions.wait.forViewWithId(R.id.forward).click()
|
||||
UIActions.wait.forViewWithId(R.id.forward)
|
||||
UIActions.wait.untilViewWithIdEnabled(R.id.forward).click()
|
||||
return ComposerRobot()
|
||||
}
|
||||
|
||||
|
@ -78,11 +80,13 @@ class MessageRobot {
|
|||
}
|
||||
|
||||
fun navigateUpToSearch(): SearchRobot {
|
||||
UIActions.wait.forViewWithId(R.id.messageWebViewContainer)
|
||||
UIActions.system.clickHamburgerOrUpButton()
|
||||
return SearchRobot()
|
||||
}
|
||||
|
||||
fun navigateUpToSent(): SentRobot {
|
||||
UIActions.wait.forViewWithId(R.id.reply_all)
|
||||
UIActions.system.clickHamburgerOrUpButton()
|
||||
return SentRobot()
|
||||
}
|
||||
|
@ -121,6 +125,10 @@ class MessageRobot {
|
|||
fun pgpIconShown() {
|
||||
UIActions.wait.forViewWithId(R.id.pgp_icon)
|
||||
}
|
||||
|
||||
fun messageWebViewContainerShown() {
|
||||
UIActions.wait.forViewWithId(R.id.messageWebViewContainer)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun verify(block: Verify.() -> Unit) = Verify().apply(block)
|
||||
|
|
|
@ -32,7 +32,7 @@ class ViewHeadersRobot {
|
|||
*/
|
||||
class Verify {
|
||||
fun messageHeadersDisplayed() {
|
||||
UIActions.check.viewWithIdIsDisplayed(R.id.viewHeadersText)
|
||||
UIActions.wait.forViewWithId(R.id.viewHeadersText)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import ch.protonmail.android.uitests.testsHelper.UIActions
|
|||
class SearchRobot {
|
||||
|
||||
fun searchMessageText(subject: String): SearchRobot {
|
||||
UIActions.id.typeTextIntoFieldWithIdAndPressImeAction(R.id.search_src_text, subject)
|
||||
UIActions.id.insertTextInFieldWithIdAndPressImeAction(R.id.search_src_text, subject)
|
||||
return this
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,11 @@ class SentRobot : MailboxRobotInterface {
|
|||
return this
|
||||
}
|
||||
|
||||
override fun refreshMessageList(): SentRobot {
|
||||
super.refreshMessageList()
|
||||
return SentRobot()
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Mailbox selection state actions and verifications after user long click one of the messages.
|
||||
*/
|
||||
|
|
|
@ -6,6 +6,7 @@ import ch.protonmail.android.uitests.robots.mailbox.inbox.InboxRobot
|
|||
import ch.protonmail.android.uitests.robots.manageaccounts.ManageAccountsMatchers.withPrimaryAccountInAccountManager
|
||||
import ch.protonmail.android.uitests.testsHelper.StringUtils.stringFromResource
|
||||
import ch.protonmail.android.uitests.testsHelper.UIActions
|
||||
import ch.protonmail.android.uitests.testsHelper.click
|
||||
|
||||
/**
|
||||
* [AccountManagerRobot] class contains actions and verifications for Account Manager functionality.
|
||||
|
@ -55,7 +56,7 @@ open class AccountManagerRobot {
|
|||
}
|
||||
|
||||
private fun logout(): AccountManagerRobot {
|
||||
UIActions.text.clickViewWithText(R.string.logout)
|
||||
UIActions.wait.forViewWithText(R.string.logout).click()
|
||||
return AccountManagerRobot()
|
||||
}
|
||||
|
||||
|
@ -75,7 +76,7 @@ open class AccountManagerRobot {
|
|||
}
|
||||
|
||||
private fun confirmLastAccountLogout(): LoginRobot {
|
||||
UIActions.system.clickPositiveButtonInDialogRoot()
|
||||
UIActions.wait.forViewWithId(android.R.id.button1).click()
|
||||
return LoginRobot()
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ package ch.protonmail.android.uitests.tests
|
|||
import android.Manifest.permission.READ_CONTACTS
|
||||
import android.Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
import android.app.Activity
|
||||
import android.app.Instrumentation
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
|
@ -29,6 +31,7 @@ import android.widget.Toast
|
|||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import androidx.test.espresso.intent.Intents
|
||||
import androidx.test.espresso.intent.matcher.IntentMatchers.isInternal
|
||||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
|
@ -41,6 +44,7 @@ import ch.protonmail.android.uitests.testsHelper.TestData
|
|||
import ch.protonmail.android.uitests.testsHelper.TestExecutionWatcher
|
||||
import ch.protonmail.android.uitests.testsHelper.User
|
||||
import ch.protonmail.android.uitests.testsHelper.testRail.TestRailService
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
|
@ -72,8 +76,10 @@ open class BaseTest {
|
|||
Log.d(testTag, "Starting test execution for test: ${testName.methodName}")
|
||||
// Show toast with test case name for better test analysis in recorded videos especially on Firebase.
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
||||
Toast.makeText(targetContext, testName.methodName, twoSeconds).show()
|
||||
Toast.makeText(targetContext, testName.methodName, tenSeconds).show()
|
||||
}
|
||||
Intents.intending(not(isInternal()))
|
||||
.respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null))
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -107,7 +113,7 @@ open class BaseTest {
|
|||
private const val password = 1
|
||||
private const val mailboxPassword = 2
|
||||
private const val twoFaKey = 3
|
||||
private const val twoSeconds = 2000
|
||||
private const val tenSeconds = 10000
|
||||
val device: UiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -52,6 +52,7 @@ class ForwardMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.forward()
|
||||
.forwardMessage(to, body)
|
||||
|
@ -69,6 +70,7 @@ class ForwardMessageTests : BaseTest() {
|
|||
.sendMessageWithFileAttachment(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.forward()
|
||||
.forwardMessage(to, body)
|
||||
|
@ -88,7 +90,7 @@ class ForwardMessageTests : BaseTest() {
|
|||
.searchMessageText(reSubject(searchMessageSubject))
|
||||
.clickSearchedMessageBySubjectPart(searchMessageSubjectPart)
|
||||
.forward()
|
||||
.changeSubjectAndForwardMessage(to, subject, body)
|
||||
.changeSubjectAndForwardMessage(to, subject)
|
||||
.navigateUpToSearch()
|
||||
.navigateUpToInbox()
|
||||
.menuDrawer()
|
||||
|
|
|
@ -22,8 +22,8 @@ import ch.protonmail.android.uitests.robots.login.LoginRobot
|
|||
import ch.protonmail.android.uitests.tests.BaseTest
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.onePassUser
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.TestId
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.experimental.categories.Category
|
||||
|
@ -52,9 +52,10 @@ class ReplyToMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.reply()
|
||||
.editBodyAndReply("Robot Reply")
|
||||
.editBodyAndReply(body, "Robot Reply")
|
||||
.navigateUpToSent()
|
||||
.verify {
|
||||
messageWithSubjectExists(TestData.reSubject(subject))
|
||||
|
@ -71,9 +72,10 @@ class ReplyToMessageTests : BaseTest() {
|
|||
.sendMessageCameraCaptureAttachment(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.reply()
|
||||
.editBodyAndReply("Robot Reply With Attachment ")
|
||||
.editBodyAndReply(body, "Robot Reply With Attachment ")
|
||||
.navigateUpToSent()
|
||||
.verify { messageWithSubjectExists(TestData.reSubject(subject)) }
|
||||
}
|
||||
|
@ -88,9 +90,10 @@ class ReplyToMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.replyAll()
|
||||
.editBodyAndReply("Robot ReplyAll ")
|
||||
.editBodyAndReply(body, "Robot ReplyAll ")
|
||||
.navigateUpToSent()
|
||||
.verify { messageWithSubjectExists(TestData.reSubject(subject)) }
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ import ch.protonmail.android.uitests.testsHelper.TestData.internalEmailNotTruste
|
|||
import ch.protonmail.android.uitests.testsHelper.TestData.internalEmailTrustedKeys
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.onePassUser
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.twoPassUser
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.TestId
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.experimental.categories.Category
|
||||
|
@ -58,6 +58,7 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
|
@ -71,13 +72,14 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1543")
|
||||
@Category(SmokeTest::class)
|
||||
@Test
|
||||
fun sendMessageToPGPEncryptedContact() {
|
||||
fun sendExternalMessageToPGPEncryptedContact() {
|
||||
val to = externalGmailPGPEncrypted.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
|
@ -85,13 +87,14 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1544")
|
||||
@Category(SmokeTest::class)
|
||||
@Test
|
||||
fun sendMessageToPGPSignedContact() {
|
||||
fun sendExternalMessageToPGPSignedContact() {
|
||||
val to = externalGmailPGPEncrypted.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
|
@ -99,19 +102,21 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sendMessageTOandCC() {
|
||||
val to = internalEmailTrustedKeys.email
|
||||
val cc = externalOutlookPGPSigned.email
|
||||
val cc = internalEmailNotTrustedKeys.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageTOandCC(to, cc, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
|
@ -127,54 +132,28 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessageTOandCCandBCC(to, cc, bcc, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1542")
|
||||
@Test
|
||||
fun sendMessageEO() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
val password = editedPassword
|
||||
val hint = editedPasswordHint
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageWithPassword(to, subject, body, password, hint)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1550")
|
||||
@Test
|
||||
fun sendMessageExpiryTime() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
fun sendMessageWithExpiryTime() {
|
||||
val to = internalEmailTrustedKeys.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageExpiryTimeInDays(to, subject, body, 2)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1548")
|
||||
@Test
|
||||
fun sendMessageExpiryTimeExternalContact() {
|
||||
val to = externalGmailPGPEncrypted.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageExpiryTimeInDaysWithConfirmation(to, subject, body, 2)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("21090")
|
||||
@Test
|
||||
fun sendMessageEOAndExpiryTime() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
fun sendMessageWithPasswordAndExpiryTime() {
|
||||
val to = internalEmailTrustedKeys.email
|
||||
val password = editedPassword
|
||||
val hint = editedPasswordHint
|
||||
loginRobot
|
||||
|
@ -184,91 +163,50 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessageEOAndExpiryTime(to, subject, body, 1, password, hint)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("21091")
|
||||
@Test
|
||||
fun sendMessageEOAndExpiryTimeWithAttachment() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
val password = editedPassword
|
||||
val hint = editedPasswordHint
|
||||
loginRobot
|
||||
.loginTwoPasswordUser(twoPassUser)
|
||||
.decryptMailbox(password)
|
||||
.compose()
|
||||
.sendMessageEOAndExpiryTimeWithAttachment(to, subject, body, 1, password, hint)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sendMessageToInternalTrustedContactCameraCaptureAttachment() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
fun sendMessageToInternalTrustedContactWithCameraCaptureAttachment() {
|
||||
val to = internalEmailTrustedKeys.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageCameraCaptureAttachment(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sendMessageToInternalNotTrustedContactChooseAttachment() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
fun sendMessageToInternalNotTrustedContactWithAttachment() {
|
||||
val to = internalEmailNotTrustedKeys.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageWithFileAttachment(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sendMessageToInternalContactWithTwoAttachments() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
val to = internalEmailTrustedKeys.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageTwoImageCaptureAttachments(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("15539")
|
||||
@Test
|
||||
fun sendMessageToExternalContactWithOneAttachment() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageCameraCaptureAttachment(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("15540")
|
||||
@Test
|
||||
fun sendMessageToExternalContactWithTwoAttachments() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageTwoImageCaptureAttachments(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("C1484")
|
||||
@TestId("1484")
|
||||
@Test
|
||||
fun sendMessageFromPmMe() {
|
||||
val onePassUserPmMeAddress = onePassUser.pmMe
|
||||
|
@ -280,10 +218,11 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessage(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("C1485")
|
||||
@TestId("1485")
|
||||
@Test
|
||||
fun sendMessageWithAttachmentFromPmMe() {
|
||||
val onePassUserPmMeAddress = onePassUser.pmMe
|
||||
|
@ -295,6 +234,82 @@ class SendNewMessageTests : BaseTest() {
|
|||
.sendMessageWithFileAttachment(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1542")
|
||||
//TODO - fix failing test
|
||||
fun sendMessageWithPasswordToExternalContact() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
val password = editedPassword
|
||||
val hint = editedPasswordHint
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageWithPassword(to, subject, body, password, hint)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("21091")
|
||||
//TODO - enable back after MAILAND-789 is fixed
|
||||
fun sendExternalMessageWithPasswordExpiryTimeAndAttachment() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
val password = editedPassword
|
||||
val hint = editedPasswordHint
|
||||
loginRobot
|
||||
.loginTwoPasswordUser(twoPassUser)
|
||||
.decryptMailbox(password)
|
||||
.compose()
|
||||
.sendMessageEOAndExpiryTimeWithAttachment(to, subject, body, 1, password, hint)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("15539")
|
||||
//TODO - enable back after MAILAND-789 is fixed
|
||||
fun sendExternalMessageWithOneAttachment() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageCameraCaptureAttachment(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1548")
|
||||
//TODO - enable back after MAILAND-789 is fixed
|
||||
fun sendExternalMessageWithExpiryTime() {
|
||||
val to = externalGmailPGPEncrypted.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageExpiryTimeInDaysWithConfirmation(to, subject, body, 2)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("15540")
|
||||
//TODO - enable back after MAILAND-789 is fixed
|
||||
fun sendExternalMessageWithTwoAttachments() {
|
||||
val to = externalOutlookPGPSigned.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.sendMessageTwoImageCaptureAttachments(to, subject, body)
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package ch.protonmail.android.uitests.tests.contacts
|
||||
|
||||
import androidx.test.filters.LargeTest
|
||||
import ch.protonmail.android.R
|
||||
import ch.protonmail.android.uitests.robots.contacts.ContactsRobot
|
||||
import ch.protonmail.android.uitests.robots.login.LoginRobot
|
||||
|
@ -28,16 +27,12 @@ import ch.protonmail.android.uitests.testsHelper.TestData
|
|||
import ch.protonmail.android.uitests.testsHelper.TestData.internalEmailTrustedKeys
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.onePassUser
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.checkGroupDoesNotExist
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.TestId
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import org.junit.Before
|
||||
import org.junit.FixMethodOrder
|
||||
import org.junit.Test
|
||||
import org.junit.experimental.categories.Category
|
||||
import org.junit.runners.MethodSorters
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@LargeTest
|
||||
class ContactsTests : BaseTest() {
|
||||
|
||||
private lateinit var contactsRobot: ContactsRobot
|
||||
|
@ -52,7 +47,6 @@ class ContactsTests : BaseTest() {
|
|||
.contacts()
|
||||
}
|
||||
|
||||
@TestId("1419")
|
||||
@Test
|
||||
fun createContact() {
|
||||
val name = TestData.newContactName
|
||||
|
@ -60,6 +54,8 @@ class ContactsTests : BaseTest() {
|
|||
contactsRobot
|
||||
.addContact()
|
||||
.setNameEmailAndSave(name, email)
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.clickContactByEmail(email)
|
||||
.deleteContact()
|
||||
.verify { contactDoesNotExists(name, email) }
|
||||
|
@ -76,6 +72,8 @@ class ContactsTests : BaseTest() {
|
|||
contactsRobot
|
||||
.addContact()
|
||||
.setNameEmailAndSave(name, email)
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.clickContactByEmail(email)
|
||||
.editContact()
|
||||
.editNameEmailAndSave(editedName, editedEmail)
|
||||
|
@ -93,12 +91,15 @@ class ContactsTests : BaseTest() {
|
|||
contactsRobot
|
||||
.addContact()
|
||||
.setNameEmailAndSave(name, email)
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.clickContactByEmail(email)
|
||||
.deleteContact()
|
||||
.verify { contactDoesNotExists(name, email) }
|
||||
}
|
||||
|
||||
@TestId("1421")
|
||||
@Test
|
||||
fun createGroup() {
|
||||
val contactEmail = internalEmailTrustedKeys
|
||||
val groupName = getEmailString()
|
||||
|
@ -110,6 +111,8 @@ class ContactsTests : BaseTest() {
|
|||
.manageAddresses()
|
||||
.addContactToGroup(contactEmail.email)
|
||||
.done()
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.groupsView()
|
||||
.clickGroupWithMembersCount(groupName, groupMembersCount)
|
||||
.deleteGroup()
|
||||
|
@ -118,6 +121,7 @@ class ContactsTests : BaseTest() {
|
|||
}
|
||||
|
||||
@TestId("1422")
|
||||
@Test
|
||||
fun editGroup() {
|
||||
val contactEmail = internalEmailTrustedKeys
|
||||
val groupName = getEmailString()
|
||||
|
@ -130,11 +134,15 @@ class ContactsTests : BaseTest() {
|
|||
.manageAddresses()
|
||||
.addContactToGroup(contactEmail.email)
|
||||
.done()
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.groupsView()
|
||||
.clickGroup(groupName)
|
||||
.edit()
|
||||
.editNameAndSave(newGroupName)
|
||||
.navigateUp()
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.groupsView()
|
||||
.clickGroupWithMembersCount(newGroupName, groupMembersCount)
|
||||
.deleteGroup()
|
||||
|
@ -143,6 +151,7 @@ class ContactsTests : BaseTest() {
|
|||
}
|
||||
|
||||
@TestId("21240")
|
||||
@Test
|
||||
fun deleteGroup() {
|
||||
val contactEmail = internalEmailTrustedKeys
|
||||
val groupName = getEmailString()
|
||||
|
@ -154,6 +163,8 @@ class ContactsTests : BaseTest() {
|
|||
.manageAddresses()
|
||||
.addContactToGroup(contactEmail.email)
|
||||
.done()
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.groupsView()
|
||||
.clickGroupWithMembersCount(groupName, groupMembersCount)
|
||||
.deleteGroup()
|
||||
|
@ -161,15 +172,6 @@ class ContactsTests : BaseTest() {
|
|||
.verify { checkGroupDoesNotExist(groupName, groupMembersCount) }
|
||||
}
|
||||
|
||||
@TestId("1606")
|
||||
@Test
|
||||
fun contactListRefresh() {
|
||||
contactsRobot
|
||||
.openOptionsMenu()
|
||||
.refresh()
|
||||
.verify { contactsRefreshed() }
|
||||
}
|
||||
|
||||
@TestId("30833")
|
||||
@Category(SmokeTest::class)
|
||||
@Test
|
||||
|
@ -183,9 +185,8 @@ class ContactsTests : BaseTest() {
|
|||
.navigateUpToInbox()
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.verify {
|
||||
messageWithSubjectExists(subject)
|
||||
}
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("1423")
|
||||
|
@ -197,12 +198,11 @@ class ContactsTests : BaseTest() {
|
|||
contactsRobot
|
||||
.groupsView()
|
||||
.clickSendMessageToGroup(groupName)
|
||||
.sendMessageToContact(subject, body)
|
||||
.sendMessageToGroup(subject, body)
|
||||
.navigateUpToInbox()
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.verify {
|
||||
messageWithSubjectExists(subject)
|
||||
}
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ import ch.protonmail.android.uitests.tests.BaseTest
|
|||
import ch.protonmail.android.uitests.testsHelper.TestData
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.internalEmailTrustedKeys
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.onePassUser
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.TestId
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.experimental.categories.Category
|
||||
|
@ -56,6 +56,7 @@ class DraftsTests : BaseTest() {
|
|||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
|
@ -66,29 +67,15 @@ class DraftsTests : BaseTest() {
|
|||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.draftSubjectBody(subject, body)
|
||||
.draftSubjectBodyAttachment(to, subject, body)
|
||||
.clickUpButton()
|
||||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
// Ignore test until https://jira.protontech.ch/browse/MAILAND-982 is fixed.
|
||||
@TestId("1382")
|
||||
fun openDraftFromSearch() {
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.draftSubjectBody(subject, body)
|
||||
.clickUpButton()
|
||||
.confirmDraftSaving()
|
||||
.searchBar()
|
||||
.searchMessageText(subject)
|
||||
.clickSearchedDraftBySubject(subject)
|
||||
.verify { messageWithSubjectOpened(subject) }
|
||||
}
|
||||
|
||||
@TestId("1383")
|
||||
@Test
|
||||
fun sendDraftWithAttachment() {
|
||||
|
@ -100,13 +87,37 @@ class DraftsTests : BaseTest() {
|
|||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.refreshMessageList()
|
||||
.clickDraftBySubject(subject)
|
||||
.send()
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.refreshMessageList()
|
||||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("4278")
|
||||
@Test
|
||||
fun changeDraftSender() {
|
||||
val onePassUserSecondEmail = "2${onePassUser.email}"
|
||||
val to = internalEmailTrustedKeys.email
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.draftToSubjectBody(to, subject, body)
|
||||
.clickUpButton()
|
||||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.clickDraftBySubject(subject)
|
||||
.recipients(to)
|
||||
.changeSenderTo(onePassUserSecondEmail)
|
||||
.clickUpButton()
|
||||
.confirmDraftSavingFromDrafts()
|
||||
.clickDraftBySubject(subject)
|
||||
.verify { fromEmailIs(onePassUserSecondEmail) }
|
||||
}
|
||||
|
||||
@TestId("1384")
|
||||
@Test
|
||||
fun addRecipientsToDraft() {
|
||||
|
@ -119,6 +130,7 @@ class DraftsTests : BaseTest() {
|
|||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.refreshMessageList()
|
||||
.clickDraftBySubject(subject)
|
||||
.recipients(to)
|
||||
.clickUpButton()
|
||||
|
@ -126,25 +138,18 @@ class DraftsTests : BaseTest() {
|
|||
.verify { messageWithSubjectAndRecipientExists(subject, to) }
|
||||
}
|
||||
|
||||
@TestId("4278")
|
||||
@Test
|
||||
fun changeDraftSender() {
|
||||
val onePassUserSecondEmail = "2${onePassUser.email}"
|
||||
val to = internalEmailTrustedKeys.email
|
||||
// Ignore test until MAILAND-982 is fixed.
|
||||
// @RailId("1382")
|
||||
fun openDraftFromSearch() {
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.compose()
|
||||
.draftSubjectBody(subject, body)
|
||||
.draftToSubjectBody(to, subject, body)
|
||||
.clickUpButton()
|
||||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.clickDraftBySubject(subject)
|
||||
.recipients(to)
|
||||
.changeSenderTo(onePassUserSecondEmail)
|
||||
.clickUpButton()
|
||||
.confirmDraftSavingFromDrafts()
|
||||
.clickDraftBySubject(subject)
|
||||
.verify { fromEmailIs(onePassUserSecondEmail) }
|
||||
.searchBar()
|
||||
.searchMessageText(subject)
|
||||
.clickSearchedDraftBySubject(subject)
|
||||
.verify { messageWithSubjectOpened(subject) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,10 +30,9 @@ import ch.protonmail.android.uitests.tests.BaseTest
|
|||
import ch.protonmail.android.uitests.testsHelper.TestData
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.externalGmailPGPEncrypted
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.externalOutlookPGPSigned
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.internalEmailTrustedKeys
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.onePassUser
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.TestId
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import ch.protonmail.android.uitests.testsHelper.mailer.Mail
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
@ -61,8 +60,9 @@ class InboxTests : BaseTest() {
|
|||
val to = onePassUser
|
||||
Mail.gmail.from(from).to(to).withSubject(subject).withBody(body).send()
|
||||
inboxRobot
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.verify { pgpIconShown() }
|
||||
.verify { messageWebViewContainerShown() }
|
||||
}
|
||||
|
||||
@TestId("29747")
|
||||
|
@ -72,22 +72,24 @@ class InboxTests : BaseTest() {
|
|||
val to = onePassUser
|
||||
Mail.outlook.from(from).to(to).withSubject(subject).withBody(body).send()
|
||||
inboxRobot
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.verify { pgpIconShown() }
|
||||
.verify { messageWebViewContainerShown() }
|
||||
}
|
||||
|
||||
@TestId("C1486")
|
||||
@TestId("1486")
|
||||
@Test
|
||||
fun receiveMessageOnPmMe() {
|
||||
val from = externalOutlookPGPSigned
|
||||
val to = onePassUser
|
||||
Mail.outlook.from(from).to(to).withSubject(subject).withBody(body).sendToPmMe()
|
||||
inboxRobot
|
||||
.refreshMessageList()
|
||||
.clickMessageBySubject(subject)
|
||||
.verify { pgpIconShown() }
|
||||
.verify { messageWebViewContainerShown() }
|
||||
}
|
||||
|
||||
@TestId("C1487")
|
||||
@TestId("1487")
|
||||
@Test
|
||||
fun receiveMessageWithAttachmentOnPmMe() {
|
||||
loginRobot
|
||||
|
@ -125,19 +127,6 @@ class InboxTests : BaseTest() {
|
|||
.verify { messageWithSubjectExists(subject) }
|
||||
}
|
||||
|
||||
@TestId("29722")
|
||||
@Test
|
||||
fun deleteMessageLongClick() {
|
||||
inboxRobot
|
||||
.menuDrawer()
|
||||
.sent()
|
||||
.longClickMessageOnPosition(0)
|
||||
.moveToTrash()
|
||||
.verify {
|
||||
messageDeleted(longClickedMessageSubject, longClickedMessageDate)
|
||||
}
|
||||
}
|
||||
|
||||
@TestId("29723")
|
||||
@Category(SmokeTest::class)
|
||||
@Test
|
||||
|
@ -191,17 +180,6 @@ class InboxTests : BaseTest() {
|
|||
.verify { messageMoved(longClickedMessageSubject) }
|
||||
}
|
||||
|
||||
//TODO create a bug - app hangs in loading state after trying to empty the trash folder
|
||||
fun emptyTrash() {
|
||||
inboxRobot
|
||||
.menuDrawer()
|
||||
.trash()
|
||||
.moreOptions()
|
||||
.emptyFolder()
|
||||
.confirm()
|
||||
.verify { folderEmpty() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun messageDetailsViewHeaders() {
|
||||
inboxRobot
|
||||
|
@ -213,32 +191,16 @@ class InboxTests : BaseTest() {
|
|||
.verify { messageHeadersDisplayed() }
|
||||
}
|
||||
|
||||
@TestId("29722")
|
||||
@Test
|
||||
fun saveDraft() {
|
||||
val draftSubject = "Draft ${TestData.messageSubject}"
|
||||
val body = "Draft ${TestData.messageBody}"
|
||||
fun deleteMessageLongClick() {
|
||||
inboxRobot
|
||||
.compose()
|
||||
.draftToSubjectBody(internalEmailTrustedKeys.email, draftSubject, body)
|
||||
.clickUpButton()
|
||||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.verify { draftMessageSaved(draftSubject) }
|
||||
}
|
||||
|
||||
@Category(SmokeTest::class)
|
||||
@Test
|
||||
fun saveDraftWithAttachment() {
|
||||
val draftSubject = "Draft ${TestData.messageSubject}"
|
||||
val body = "Draft ${TestData.messageBody}"
|
||||
inboxRobot
|
||||
.compose()
|
||||
.draftSubjectBodyAttachment(internalEmailTrustedKeys.email, draftSubject, body)
|
||||
.clickUpButton()
|
||||
.confirmDraftSaving()
|
||||
.menuDrawer()
|
||||
.drafts()
|
||||
.verify { draftWithAttachmentSaved(draftSubject) }
|
||||
.sent()
|
||||
.longClickMessageOnPosition(0)
|
||||
.moveToTrash()
|
||||
.verify {
|
||||
messageDeleted(longClickedMessageSubject, longClickedMessageDate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,6 @@ class LoginTests : BaseTest() {
|
|||
.verify { mailboxLayoutShown() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun loginWithTwoPassAnd2Fa() {
|
||||
loginRobot
|
||||
.loginUserWithTwoFa(twoPassUserWith2FA)
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package ch.protonmail.android.uitests.tests.manageaccounts
|
||||
|
||||
import androidx.test.filters.LargeTest
|
||||
import ch.protonmail.android.uitests.robots.login.LoginRobot
|
||||
import ch.protonmail.android.uitests.tests.BaseTest
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData.onePassUser
|
||||
|
@ -29,7 +28,6 @@ import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
|||
import org.junit.Test
|
||||
import org.junit.experimental.categories.Category
|
||||
|
||||
@LargeTest
|
||||
class MultiuserManagementTests : BaseTest() {
|
||||
|
||||
private val loginRobot = LoginRobot()
|
||||
|
@ -63,20 +61,6 @@ class MultiuserManagementTests : BaseTest() {
|
|||
.verify { accountAdded(twoPassUser.email) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun connectTwoPassAccountWithTwoFa() {
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.menuDrawer()
|
||||
.accountsList()
|
||||
.manageAccounts()
|
||||
.addAccount()
|
||||
.connectTwoPassAccountWithTwoFa(twoPassUserWith2FA)
|
||||
.menuDrawer()
|
||||
.accountsList()
|
||||
.verify { accountAdded(twoPassUserWith2FA.email) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun connectOnePassAccountWithTwoFa() {
|
||||
loginRobot
|
||||
|
@ -233,20 +217,6 @@ class MultiuserManagementTests : BaseTest() {
|
|||
.verify { accountLoggedOut(onePassUserWith2FA.name) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addTwoFreeAccounts() {
|
||||
loginRobot
|
||||
.loginUserWithTwoFa(twoPassUserWith2FA)
|
||||
.provideTwoFaCodeMailbox(twoPassUserWith2FA.twoFaCode)
|
||||
.decryptMailbox(twoPassUserWith2FA.mailboxPassword)
|
||||
.menuDrawer()
|
||||
.accountsList()
|
||||
.manageAccounts()
|
||||
.addAccount()
|
||||
.connectSecondFreeOnePassAccountWithTwoFa(onePassUserWith2FA)
|
||||
.verify { limitReachedDialogDisplayed() }
|
||||
}
|
||||
|
||||
@Category(SmokeTest::class)
|
||||
@Test
|
||||
fun switchAccount() {
|
||||
|
@ -264,4 +234,30 @@ class MultiuserManagementTests : BaseTest() {
|
|||
.manageAccounts()
|
||||
.verify { switchedToAccount(onePassUser.name) }
|
||||
}
|
||||
|
||||
fun addTwoFreeAccounts() {
|
||||
loginRobot
|
||||
.loginUserWithTwoFa(twoPassUserWith2FA)
|
||||
.provideTwoFaCodeMailbox(twoPassUserWith2FA.twoFaCode)
|
||||
.decryptMailbox(twoPassUserWith2FA.mailboxPassword)
|
||||
.menuDrawer()
|
||||
.accountsList()
|
||||
.manageAccounts()
|
||||
.addAccount()
|
||||
.connectSecondFreeOnePassAccountWithTwoFa(onePassUserWith2FA)
|
||||
.verify { limitReachedDialogDisplayed() }
|
||||
}
|
||||
|
||||
fun connectTwoPassAccountWithTwoFa() {
|
||||
loginRobot
|
||||
.loginUser(onePassUser)
|
||||
.menuDrawer()
|
||||
.accountsList()
|
||||
.manageAccounts()
|
||||
.addAccount()
|
||||
.connectTwoPassAccountWithTwoFa(twoPassUserWith2FA)
|
||||
.menuDrawer()
|
||||
.accountsList()
|
||||
.verify { accountAdded(twoPassUserWith2FA.email) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package ch.protonmail.android.uitests.tests.menu
|
||||
|
||||
import androidx.test.filters.LargeTest
|
||||
import ch.protonmail.android.uitests.robots.login.LoginRobot
|
||||
import ch.protonmail.android.uitests.robots.menu.MenuRobot
|
||||
import ch.protonmail.android.uitests.tests.BaseTest
|
||||
|
@ -26,7 +25,6 @@ import ch.protonmail.android.uitests.testsHelper.TestData
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@LargeTest
|
||||
class MenuTests : BaseTest() {
|
||||
|
||||
private lateinit var menuRobot: MenuRobot
|
||||
|
|
|
@ -18,18 +18,15 @@
|
|||
*/
|
||||
package ch.protonmail.android.uitests.tests.settings
|
||||
|
||||
import androidx.test.filters.LargeTest
|
||||
import ch.protonmail.android.uitests.actions.settings.account.AccountSettingsRobot
|
||||
import ch.protonmail.android.uitests.robots.login.LoginRobot
|
||||
import ch.protonmail.android.uitests.tests.BaseTest
|
||||
import ch.protonmail.android.uitests.testsHelper.StringUtils.getAlphaNumericStringWithSpecialCharacters
|
||||
import ch.protonmail.android.uitests.testsHelper.TestData
|
||||
import ch.protonmail.android.uitests.testsHelper.annotations.SmokeTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.experimental.categories.Category
|
||||
|
||||
@LargeTest
|
||||
class AccountSettingsTests : BaseTest() {
|
||||
|
||||
private val accountSettingsRobot: AccountSettingsRobot = AccountSettingsRobot()
|
||||
|
@ -52,25 +49,6 @@ class AccountSettingsTests : BaseTest() {
|
|||
.verify { subscriptionViewShown() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeLoginPassword() {
|
||||
accountSettingsRobot
|
||||
.passwordManagement()
|
||||
.changePassword(TestData.twoPassUser)
|
||||
.verify {
|
||||
accountSettingsOpened()
|
||||
passwordChanged()
|
||||
}
|
||||
}
|
||||
|
||||
//TODO enable when multiple user login per test class will be supported
|
||||
fun changeMailboxPassword() {
|
||||
accountSettingsRobot
|
||||
.passwordManagement()
|
||||
.changeMailboxPassword(TestData.twoPassUser)
|
||||
.verify { mailboxPasswordChanged() }
|
||||
}
|
||||
|
||||
@Category(SmokeTest::class)
|
||||
@Test
|
||||
fun changeRecoveryEmail() {
|
||||
|
@ -120,25 +98,21 @@ class AccountSettingsTests : BaseTest() {
|
|||
.verify { mobileSignatureToggleCheckedStateIs(true) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createLabel() {
|
||||
val labelName = getAlphaNumericStringWithSpecialCharacters()
|
||||
fun changeLoginPassword() {
|
||||
accountSettingsRobot
|
||||
.foldersAndLabels()
|
||||
// TODO enable after MAILAND-750 will be fixed.
|
||||
// .labelsManager()
|
||||
// .addLabel(labelName)
|
||||
// .verify { labelWithNameShown(labelName) }
|
||||
.passwordManagement()
|
||||
.changePassword(TestData.twoPassUser)
|
||||
.verify {
|
||||
accountSettingsOpened()
|
||||
passwordChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFolder() {
|
||||
val folderName = getAlphaNumericStringWithSpecialCharacters()
|
||||
accountSettingsRobot
|
||||
.foldersAndLabels()
|
||||
// TODO enable after MAILAND-750 will be fixed.
|
||||
// .foldersManager()
|
||||
// .addFolder(folderName)
|
||||
// .verify { folderWithNameShown(folderName) }
|
||||
}
|
||||
// //TODO enable when multiple user login per test class will be supported
|
||||
// fun changeMailboxPassword() {
|
||||
// accountSettingsRobot
|
||||
// .passwordManagement()
|
||||
// .changeMailboxPassword(TestData.twoPassUser)
|
||||
// .verify { mailboxPasswordChanged() }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import ch.protonmail.android.uitests.tests.composer.ForwardMessageTests
|
|||
import ch.protonmail.android.uitests.tests.composer.ReplyToMessageTests
|
||||
import ch.protonmail.android.uitests.tests.composer.SendNewMessageTests
|
||||
import ch.protonmail.android.uitests.tests.contacts.ContactsTests
|
||||
import ch.protonmail.android.uitests.tests.drafts.DraftsTests
|
||||
import ch.protonmail.android.uitests.tests.inbox.InboxTests
|
||||
import ch.protonmail.android.uitests.tests.inbox.SearchTests
|
||||
import ch.protonmail.android.uitests.tests.login.LoginTests
|
||||
|
@ -42,6 +43,8 @@ import org.junit.runners.Suite
|
|||
ReplyToMessageTests::class,
|
||||
// Contacts tests
|
||||
ContactsTests::class,
|
||||
// Drafts tests
|
||||
DraftsTests::class,
|
||||
// Inbox tests
|
||||
InboxTests::class,
|
||||
// Login tests
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package ch.protonmail.android.uitests.testsHelper
|
||||
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import android.app.Activity
|
||||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
|
||||
import androidx.test.runner.lifecycle.Stage
|
||||
|
@ -27,17 +27,17 @@ import androidx.test.runner.lifecycle.Stage
|
|||
* Provides an activity which is in [Stage.RESUMED].
|
||||
*/
|
||||
object ActivityProvider {
|
||||
val currentActivity: FragmentActivity? get() = getActivity()
|
||||
val currentActivity: Activity? get() = getActivity()
|
||||
|
||||
private fun getActivity(): FragmentActivity? {
|
||||
val currentActivity = arrayOfNulls<FragmentActivity>(1)
|
||||
private fun getActivity(): Activity? {
|
||||
val currentActivity = arrayOfNulls<Activity>(1)
|
||||
getInstrumentation().runOnMainSync {
|
||||
val activities = ActivityLifecycleMonitorRegistry
|
||||
.getInstance()
|
||||
.getActivitiesInStage(Stage.RESUMED)
|
||||
|
||||
if (activities.iterator().hasNext()) {
|
||||
currentActivity[0] = activities.iterator().next() as FragmentActivity
|
||||
currentActivity[0] = activities.iterator().next() as Activity
|
||||
}
|
||||
}
|
||||
return currentActivity[0]
|
||||
|
|
|
@ -37,16 +37,13 @@ class ProtonFailureHandler(instrumentation: Instrumentation) : FailureHandler {
|
|||
}
|
||||
|
||||
override fun handle(error: Throwable, viewMatcher: Matcher<View>) {
|
||||
when (ProtonWatcher.status) {
|
||||
ProtonWatcher.CONDITION_NOT_MET -> {
|
||||
// just delegate as we are in the condition check loop
|
||||
delegate.handle(error, viewMatcher)
|
||||
}
|
||||
else -> {
|
||||
val file = File(artifactsPath, "${testName.methodName}-screenshot.png")
|
||||
Falcon.takeScreenshot(ActivityProvider.currentActivity, file)
|
||||
delegate.handle(error, viewMatcher)
|
||||
}
|
||||
if (ProtonWatcher.status == ProtonWatcher.CONDITION_NOT_MET) {
|
||||
// just delegate as we are in the condition check loop
|
||||
delegate.handle(error, viewMatcher)
|
||||
} else {
|
||||
val file = File(artifactsPath, "${testName.methodName}-screenshot.png")
|
||||
Falcon.takeScreenshot(ActivityProvider.currentActivity, file)
|
||||
delegate.handle(error, viewMatcher)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ class ProtonWatcher {
|
|||
private val instance = ProtonWatcher()
|
||||
|
||||
fun waitForCondition(condition: Condition) {
|
||||
// reset to initial state
|
||||
status = 0
|
||||
var timeInterval = 0L
|
||||
while (status != CONDITION_MET) {
|
||||
if (condition.checkCondition()) {
|
||||
|
@ -49,12 +51,9 @@ class ProtonWatcher {
|
|||
Thread.sleep(instance.watchInterval)
|
||||
} else {
|
||||
status = TIMEOUT
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// reset to initial state
|
||||
status = 0
|
||||
}
|
||||
|
||||
fun setTimeout(ms: Long) {
|
||||
|
|
|
@ -34,6 +34,7 @@ import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
|
|||
import androidx.test.espresso.action.ViewActions.longClick
|
||||
import androidx.test.espresso.action.ViewActions.pressImeActionButton
|
||||
import androidx.test.espresso.action.ViewActions.replaceText
|
||||
import androidx.test.espresso.action.ViewActions.swipeDown
|
||||
import androidx.test.espresso.action.ViewActions.swipeLeft
|
||||
import androidx.test.espresso.action.ViewActions.swipeRight
|
||||
import androidx.test.espresso.action.ViewActions.typeText
|
||||
|
@ -49,6 +50,7 @@ import androidx.test.espresso.matcher.ViewMatchers.Visibility
|
|||
import androidx.test.espresso.matcher.ViewMatchers.isChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isEnabled
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
|
||||
|
@ -67,8 +69,10 @@ import ch.protonmail.android.uitests.testsHelper.StringUtils.stringFromResource
|
|||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.checkContactDoesNotExist
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.checkMessageDoesNotExist
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.clickOnChildWithId
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.performActionWithRetry
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.saveMessageSubject
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.waitForAdapterItemWithIdAndText
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.waitUntilMatcherFulfilled
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.waitUntilRecyclerViewPopulated
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.waitUntilViewAppears
|
||||
import ch.protonmail.android.uitests.testsHelper.UICustomViewActions.waitUntilViewIsGone
|
||||
|
@ -88,6 +92,9 @@ fun ViewInteraction.insert(text: String): ViewInteraction =
|
|||
fun ViewInteraction.type(text: String): ViewInteraction =
|
||||
this.perform(typeText(text), closeSoftKeyboard())
|
||||
|
||||
fun ViewInteraction.swipeViewDown(): ViewInteraction =
|
||||
this.perform(swipeDown())
|
||||
|
||||
object UIActions {
|
||||
|
||||
private val targetContext: Context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
|
@ -219,6 +226,8 @@ object UIActions {
|
|||
|
||||
fun swipeLeftViewWithId(@IdRes id: Int): ViewInteraction = onView(withId(id)).perform(swipeLeft())
|
||||
|
||||
fun swipeDownViewWithId(@IdRes id: Int): ViewInteraction = onView(withId(id)).perform(swipeDown())
|
||||
|
||||
fun typeTextIntoFieldWithIdAndPressImeAction(@IdRes id: Int, text: String): ViewInteraction =
|
||||
onView(withId(id)).perform(click(), typeText(text), pressImeActionButton())
|
||||
|
||||
|
@ -236,9 +245,17 @@ object UIActions {
|
|||
): ViewInteraction =
|
||||
onView(withId(recyclerViewId)).perform(actionOnHolderItem(withMatcher, click()))
|
||||
|
||||
fun clickOnRecyclerViewMatchedItemWithRetry(
|
||||
@IdRes recyclerViewId: Int,
|
||||
withMatcher: Matcher<RecyclerView.ViewHolder>
|
||||
): ViewInteraction = performActionWithRetry(onView(withId(recyclerViewId)), actionOnHolderItem(withMatcher, click()))
|
||||
|
||||
fun clickContactItem(@IdRes recyclerViewId: Int, withEmail: String): ViewInteraction =
|
||||
onView(withId(recyclerViewId)).perform(actionOnHolderItem(withContactEmail(withEmail), click()))
|
||||
|
||||
fun clickContactItemWithRetry(@IdRes recyclerViewId: Int, withEmail: String): ViewInteraction =
|
||||
performActionWithRetry(onView(withId(recyclerViewId)), actionOnHolderItem(withContactEmail(withEmail), click()))
|
||||
|
||||
fun clickContactItemView(
|
||||
@IdRes recyclerViewId: Int,
|
||||
withEmail: String,
|
||||
|
@ -296,6 +313,10 @@ object UIActions {
|
|||
onView(withId(recyclerViewId))
|
||||
.perform(actionOnItemAtPosition<RecyclerView.ViewHolder>(childPosition, swipeRight()))
|
||||
|
||||
fun swipeDownToRightOnPosition(@IdRes recyclerViewId: Int, childPosition: Int): ViewInteraction =
|
||||
onView(withId(recyclerViewId))
|
||||
.perform(actionOnItemAtPosition<RecyclerView.ViewHolder>(childPosition, swipeDown()))
|
||||
|
||||
fun swipeRightToLeftObjectWithIdAtPosition(@IdRes recyclerViewId: Int, childPosition: Int): ViewInteraction =
|
||||
onView(withId(recyclerViewId))
|
||||
.perform(actionOnItemAtPosition<RecyclerView.ViewHolder>(childPosition, swipeLeft()))
|
||||
|
@ -320,6 +341,12 @@ object UIActions {
|
|||
fun clickHamburgerOrUpButtonInAnimatedToolbar(): ViewInteraction =
|
||||
allOf.clickViewWithParentIdAndClass(R.id.animToolbar, AppCompatImageButton::class.java)
|
||||
|
||||
fun waitForMoreOptionsButton(): ViewInteraction =
|
||||
wait.forViewByViewInteraction(onView(allOf(
|
||||
instanceOf(AppCompatImageView::class.java),
|
||||
withParent(instanceOf(ActionMenuView::class.java))))
|
||||
)
|
||||
|
||||
fun clickMoreOptionsButton(): ViewInteraction =
|
||||
allOf.clickViewByClassAndParentClass(AppCompatImageView::class.java, ActionMenuView::class.java)
|
||||
|
||||
|
@ -362,12 +389,11 @@ object UIActions {
|
|||
fun forViewWithText(@StringRes textId: Int): ViewInteraction =
|
||||
waitUntilViewAppears(onView(withText(stringFromResource(textId))))
|
||||
|
||||
|
||||
fun forViewWithText(text: String): ViewInteraction =
|
||||
waitUntilViewAppears(onView(withText(text)))
|
||||
|
||||
fun forViewWithId(@IdRes id: Int): ViewInteraction =
|
||||
waitUntilViewAppears(onView(withId(id)))
|
||||
fun forViewWithId(@IdRes id: Int, timeout: Long = 10_000L): ViewInteraction =
|
||||
waitUntilViewAppears(onView(withId(id)), timeout)
|
||||
|
||||
fun forViewWithTextAndParentId(@StringRes text: Int, @IdRes parentId: Int): ViewInteraction =
|
||||
waitUntilViewAppears(onView(allOf(withText(text), withParent(withId(parentId)))))
|
||||
|
@ -378,6 +404,12 @@ object UIActions {
|
|||
fun forViewByViewInteraction(interaction: ViewInteraction): ViewInteraction =
|
||||
waitUntilViewAppears(interaction)
|
||||
|
||||
fun untilViewWithIdEnabled(@IdRes id: Int): ViewInteraction =
|
||||
waitUntilMatcherFulfilled(onView(withId(id)), matches(isEnabled()))
|
||||
|
||||
fun untilViewWithIdDisabled(@IdRes id: Int): ViewInteraction =
|
||||
waitUntilMatcherFulfilled(onView(withId(id)), matches(isEnabled()))
|
||||
|
||||
fun untilViewWithIdIsGone(@IdRes id: Int): ViewInteraction =
|
||||
waitUntilViewIsGone(onView(withId(id)))
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import androidx.test.espresso.NoMatchingViewException
|
|||
import androidx.test.espresso.PerformException
|
||||
import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import androidx.test.espresso.ViewAssertion
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
|
@ -40,6 +41,8 @@ import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
|
|||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import ch.protonmail.android.R
|
||||
import ch.protonmail.android.contacts.list.listView.ContactsListAdapter
|
||||
import ch.protonmail.android.uitests.testsHelper.ActivityProvider.currentActivity
|
||||
import junit.framework.AssertionFailedError
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.Matcher
|
||||
|
@ -52,92 +55,165 @@ object UICustomViewActions {
|
|||
private val targetContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
|
||||
fun waitUntilViewAppears(interaction: ViewInteraction, timeout: Long = TIMEOUT_10S): ViewInteraction {
|
||||
try {
|
||||
ProtonWatcher.setTimeout(timeout)
|
||||
ProtonWatcher.waitForCondition(object : ProtonWatcher.Condition() {
|
||||
var errorMessage = ""
|
||||
|
||||
override fun getDescription() = "UICustomViewActions.waitUntilViewAppears $errorMessage"
|
||||
|
||||
override fun checkCondition(): Boolean {
|
||||
return try {
|
||||
interaction.check(matches(isDisplayed()))
|
||||
true
|
||||
} catch (e: PerformException) {
|
||||
errorMessage = "${e.viewDescription}, Action: ${e.actionDescription}"
|
||||
false
|
||||
} catch (e: NoMatchingViewException) {
|
||||
errorMessage = e.viewMatcherDescription
|
||||
false
|
||||
} catch (e: NoMatchingRootException) {
|
||||
false
|
||||
} catch (e: AppNotIdleException) {
|
||||
false
|
||||
} catch (e: AmbiguousViewMatcherException) {
|
||||
false
|
||||
} catch (e: AssertionFailedError) {
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (e: Throwable) {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
return interaction
|
||||
val errorDescription = "UICustomViewActions.waitUntilViewAppears"
|
||||
return waitUntilMatcherFulfilled(
|
||||
interaction,
|
||||
assertion = matches(isDisplayed()),
|
||||
timeout = timeout,
|
||||
errorDescription = errorDescription
|
||||
)
|
||||
}
|
||||
|
||||
fun waitUntilViewIsGone(interaction: ViewInteraction, timeout: Long = TIMEOUT_10S): ViewInteraction {
|
||||
try {
|
||||
ProtonWatcher.setTimeout(timeout)
|
||||
ProtonWatcher.waitForCondition(object : ProtonWatcher.Condition() {
|
||||
var errorMessage = ""
|
||||
val errorDescription = "UICustomViewActions.waitUntilViewAppears"
|
||||
return waitUntilMatcherFulfilled(
|
||||
interaction,
|
||||
assertion = doesNotExist(),
|
||||
timeout = timeout,
|
||||
errorDescription = errorDescription
|
||||
)
|
||||
}
|
||||
|
||||
override fun getDescription() = "waitForElement - $errorMessage"
|
||||
fun waitUntilMatcherFulfilled(
|
||||
interaction: ViewInteraction,
|
||||
assertion: ViewAssertion,
|
||||
timeout: Long = TIMEOUT_10S,
|
||||
errorDescription: String = ""
|
||||
): ViewInteraction {
|
||||
ProtonWatcher.setTimeout(timeout)
|
||||
ProtonWatcher.waitForCondition(object : ProtonWatcher.Condition() {
|
||||
var errorMessage = ""
|
||||
|
||||
override fun checkCondition() = try {
|
||||
interaction.check(doesNotExist())
|
||||
override fun getDescription() = "UICustomViewActions.waitUntilMatcherFulfilled $errorMessage"
|
||||
|
||||
override fun checkCondition(): Boolean {
|
||||
return try {
|
||||
interaction.check(assertion)
|
||||
true
|
||||
} catch (e: PerformException) {
|
||||
errorMessage = "${e.viewDescription}, Action: ${e.actionDescription}"
|
||||
false
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: NoMatchingViewException) {
|
||||
errorMessage = e.viewMatcherDescription
|
||||
false
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: NoMatchingRootException) {
|
||||
false
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: AppNotIdleException) {
|
||||
false
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: AmbiguousViewMatcherException) {
|
||||
false
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: AssertionFailedError) {
|
||||
false
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (e: Throwable) {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
})
|
||||
return interaction
|
||||
}
|
||||
|
||||
fun performActionWithRetry(
|
||||
interaction: ViewInteraction,
|
||||
action: ViewAction,
|
||||
timeout: Long = TIMEOUT_10S
|
||||
): ViewInteraction {
|
||||
ProtonWatcher.setTimeout(timeout)
|
||||
ProtonWatcher.waitForCondition(object : ProtonWatcher.Condition() {
|
||||
var errorMessage = ""
|
||||
|
||||
override fun getDescription() = "UICustomViewActions.waitUntilMatcherFulfilled $errorMessage"
|
||||
|
||||
override fun checkCondition(): Boolean {
|
||||
return try {
|
||||
interaction.perform(action)
|
||||
true
|
||||
} catch (e: PerformException) {
|
||||
errorMessage = "${e.viewDescription}, Action: ${e.actionDescription}"
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: NoMatchingViewException) {
|
||||
errorMessage = e.viewMatcherDescription
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: NoMatchingRootException) {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: AppNotIdleException) {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: AmbiguousViewMatcherException) {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} catch (e: AssertionFailedError) {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw e
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return interaction
|
||||
}
|
||||
|
||||
fun waitUntilRecyclerViewPopulated(@IdRes id: Int, timeout: Long = TIMEOUT_10S) {
|
||||
ProtonWatcher.setTimeout(timeout)
|
||||
ProtonWatcher.waitForCondition(object : ProtonWatcher.Condition() {
|
||||
var errorMessage = ""
|
||||
|
||||
override fun getDescription() =
|
||||
"RecyclerView: ${targetContext.resources.getResourceName(id)} was not populated with items"
|
||||
|
||||
override fun checkCondition() = try {
|
||||
val rv = ActivityProvider.currentActivity!!.findViewById<RecyclerView>(id)
|
||||
waitUntilLoaded { rv }
|
||||
rv.adapter!!.itemCount > 0
|
||||
} catch (e: Exception) {
|
||||
errorMessage = e.message.toString()
|
||||
false
|
||||
val rv = currentActivity!!.findViewById<RecyclerView>(id)
|
||||
if (rv != null) {
|
||||
waitUntilLoaded { rv }
|
||||
rv.adapter!!.itemCount > 0
|
||||
} else {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw Exception(getDescription())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
throw e
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -150,29 +226,28 @@ object UICustomViewActions {
|
|||
) {
|
||||
ProtonWatcher.setTimeout(timeout)
|
||||
ProtonWatcher.waitForCondition(object : ProtonWatcher.Condition() {
|
||||
var errorMessage = ""
|
||||
|
||||
override fun getDescription() =
|
||||
"RecyclerView: ${targetContext.resources.getResourceName(recyclerViewId)} was not populated with items"
|
||||
|
||||
override fun checkCondition(): Boolean {
|
||||
try {
|
||||
val rv = ActivityProvider.currentActivity!!.findViewById<RecyclerView>(recyclerViewId)
|
||||
val rv = currentActivity!!.findViewById<RecyclerView>(recyclerViewId)
|
||||
waitUntilLoaded { rv }
|
||||
var isMatches: Boolean
|
||||
var actualText: String
|
||||
for (i in 0..rv.adapter!!.itemCount) {
|
||||
val item = rv.getChildAt(i)
|
||||
if (item != null) {
|
||||
actualText = item.findViewById<TextView>(viewId)?.text.toString()
|
||||
isMatches = actualText == text
|
||||
if (isMatches) {
|
||||
return true
|
||||
|
||||
(rv.adapter!! as ContactsListAdapter).items.forEach {
|
||||
return if (it.getEmail() == text) {
|
||||
return true
|
||||
} else {
|
||||
if (ProtonWatcher.status == ProtonWatcher.TIMEOUT) {
|
||||
throw Exception(getDescription())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
errorMessage = e.message.toString()
|
||||
throw e
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -219,9 +294,9 @@ object UICustomViewActions {
|
|||
val recyclerView = view as RecyclerView
|
||||
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||
val messageSubject = layoutManager.getChildAt(position)
|
||||
?.findViewById<TextView>(R.id.messageTitleTextView)!!.text.toString()
|
||||
?.findViewById<TextView>(R.id.messageTitleTextView)?.text.toString()
|
||||
val messageDate = layoutManager.getChildAt(position)
|
||||
?.findViewById<TextView>(R.id.messageDateTextView)!!.text.toString()
|
||||
?.findViewById<TextView>(R.id.messageDateTextView)?.text.toString()
|
||||
saveSubject.invoke(messageSubject, messageDate)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue