Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com
* Contributors: denbond7
*/

package com.flowcrypt.email.junit.runner

import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import org.junit.runner.Runner
import org.junit.runners.Suite
import org.junit.runners.model.FrameworkMethod

/**
* A custom implementation of [Suite] which allows to run a test a few times naturally
* like [androidx.test.ext.junit.runners.AndroidJUnit4] does it.
* It helps debug issues with flaky tests when [com.flowcrypt.email.rules.RepeatRule] doesn't help.
*
* Inspired by [ParameterizedRobolectricTestRunner](https://github.com/robolectric/robolectric/blob/master/robolectric/src/main/java/org/robolectric/ParameterizedRobolectricTestRunner.java)
*
* @author Denys Bondarenko
*/
class RepeatableAndroidJUnit4ClassRunner(klass: Class<*>?) : Suite(klass, emptyList<Runner>()) {
private val runners = ArrayList<Runner?>()

init {
val attemptsCount =
testClass.getAnnotation(RepeatTest::class.java)?.value?.takeIf { it > 0 } ?: 1
for (i in 0 until attemptsCount) {
runners.add(
CustomAndroidJUnit4ClassRunner(
klass = testClass.javaClass,
postfix = "_${i + 1}".takeIf { attemptsCount > 1 } ?: ""
)
)
}
}

override fun getChildren(): MutableList<Runner?> = runners

/**
* Annotation for a class which provides attempts count
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class RepeatTest(
/**
* Should be a positive number
*/
val value: Int = 1
)

/**
* A custom implementation of [AndroidJUnit4ClassRunner] which provides custom names for tests
* based on the given postfix.
*/
private class CustomAndroidJUnit4ClassRunner(
klass: Class<*>, private val postfix: String
) : AndroidJUnit4ClassRunner(klass) {
override fun testName(method: FrameworkMethod) = method.name + postfix
override fun toString() = "TestClassRunnerForParameters_$postfix"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@ package com.flowcrypt.email.matchers
import android.view.View
import com.google.android.material.textfield.TextInputLayout
import org.hamcrest.Description
import org.hamcrest.TypeSafeMatcher
import org.hamcrest.TypeSafeDiagnosingMatcher


/**
* @author Denys Bondarenko
*/
class TextInputLayoutErrorMatcher(private val expectedHint: String) : TypeSafeMatcher<View>() {
class TextInputLayoutErrorMatcher(private val expectedHint: String) :
TypeSafeDiagnosingMatcher<View>() {
override fun describeTo(description: Description) {
description.appendText("TextInputLayout with error = \"$expectedHint\"")
}

override fun matchesSafely(view: View): Boolean {
return expectedHint == (view as? TextInputLayout)?.error?.toString()
override fun matchesSafely(item: View?, mismatchDescription: Description?): Boolean {
val actualHint = (item as? TextInputLayout)?.error?.toString()
return (expectedHint == actualHint).apply {
if (!this && mismatchDescription !is Description.NullDescription) {
mismatchDescription?.appendText("Actual was: $actualHint")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com
* Contributors: DenBond7
* Contributors: denbond7
*/

package com.flowcrypt.email.ui
Expand Down Expand Up @@ -59,6 +59,8 @@ class AddOtherAccountFlowTest : AddOtherAccountBaseTest() {
.around(ScreenshotTestRule())

@Test
//@Ignore("flaky 8")
//RepeatableAndroidJUnit4ClassRunner 50 attempts passed
fun testShowWarningIfAuthFail() {
enableAdvancedMode()
val credentials = AuthCredentialsManager.getAuthCredentials("user_with_not_existed_server.json")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com
* Contributors: DenBond7
* Contributors: denbond7
*/

package com.flowcrypt.email.ui
Expand Down Expand Up @@ -181,6 +181,8 @@ class ComposeScreenDraftGmailAPIFlowTest : BaseComposeScreenTest() {
.around(ScreenshotTestRule())

@Test
//@Ignore("flaky 8")
//RepeatableAndroidJUnit4ClassRunner 50 attempts passed
fun testSavingDraftViaGmailAPI() {
activeActivityRule?.launch(intent)
registerAllIdlingResources()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.test.espresso.action.ViewActions.clearText
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.action.ViewActions.pressImeActionButton
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
Expand Down Expand Up @@ -97,7 +98,6 @@ import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
class ComposeScreenFlowTest : BaseComposeScreenTest() {
private val addPrivateKeyToDatabaseRule = AddPrivateKeyToDatabaseRule()
private val temporaryFolderRule = TemporaryFolder.builder().parentFolder(SHARED_FOLDER).build()

@get:Rule
var ruleChain: TestRule = RuleChain
Expand All @@ -106,7 +106,6 @@ class ComposeScreenFlowTest : BaseComposeScreenTest() {
.around(GrantPermissionRuleChooser.grant(android.Manifest.permission.POST_NOTIFICATIONS))
.around(addAccountToDatabaseRule)
.around(addPrivateKeyToDatabaseRule)
.around(temporaryFolderRule)
.around(activeActivityRule)
.around(ScreenshotTestRule())

Expand Down Expand Up @@ -163,24 +162,32 @@ class ComposeScreenFlowTest : BaseComposeScreenTest() {
}

@Test
//@Ignore("flaky 5")
//RepeatableAndroidJUnit4ClassRunner 50 attempts passed
fun testEmptyEmailMsg() {
activeActivityRule?.launch(intent)
registerAllIdlingResources()

onView(withId(R.id.editTextEmailAddress))
.perform(
typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER),
replaceText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER),
pressImeActionButton()
)
onView(withId(R.id.editTextEmailSubject))
.check(matches(isDisplayed()))
.perform(scrollTo(), click(), typeText(EMAIL_SUBJECT))
.perform(scrollTo(), click(), replaceText(EMAIL_SUBJECT))
onView(withId(R.id.editTextEmailMessage))
.perform(scrollTo())
.perform(scrollTo(), click(), replaceText(""))
.check(matches(withText(`is`(emptyString()))))
Espresso.closeSoftKeyboard()
onView(withId(R.id.menuActionSend))
.check(matches(isDisplayed()))
.perform(click())

waitForObjectWithText(
getResString(R.string.your_message_must_be_non_empty),
TimeUnit.SECONDS.toMillis(10)
)

onView(withText(getResString(R.string.your_message_must_be_non_empty)))
.check(matches(isDisplayed()))
}
Expand Down Expand Up @@ -327,6 +334,8 @@ class ComposeScreenFlowTest : BaseComposeScreenTest() {
}

@Test
//@Ignore("flaky 4")
//RepeatableAndroidJUnit4ClassRunner 50 attempts passed
fun testDeletingAtts() {
activeActivityRule?.launch(intent)
waitForObjectWithText(
Expand Down Expand Up @@ -544,7 +553,7 @@ class ComposeScreenFlowTest : BaseComposeScreenTest() {
TimeUnit.SECONDS.toMillis(10)
)

onView(withText(att?.name))
onView(withText(att.name))
.check(matches(isDisplayed()))
}

Expand Down Expand Up @@ -610,7 +619,7 @@ class ComposeScreenFlowTest : BaseComposeScreenTest() {
TimeUnit.SECONDS.toMillis(10)
)

onView(withText(att?.name))
onView(withText(att.name))
.check(matches(isDisplayed()))
}

Expand Down Expand Up @@ -907,7 +916,8 @@ class ComposeScreenFlowTest : BaseComposeScreenTest() {

@get:ClassRule
@JvmStatic
val temporaryFolderRule = TemporaryFolder.builder().parentFolder(SHARED_FOLDER).build()
val temporaryFolderRule: TemporaryFolder =
TemporaryFolder.builder().parentFolder(SHARED_FOLDER).build()

@get:ClassRule
@JvmStatic
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com
* Contributors: DenBond7
* Contributors: denbond7
*/

package com.flowcrypt.email.ui
Expand Down Expand Up @@ -90,6 +90,8 @@ class ComposeScreenImportRecipientPubKeyFlowTest : BaseComposeScreenTest() {
}

@Test
//@Ignore("flaky 7")
//RepeatableAndroidJUnit4ClassRunner 50 attempts passed
fun testImportRecipientPubKeyFromClipboard() {
fillDataAndMoveToImportPublicKeyScreen()
addTextToClipboard("public key", publicKey)
Expand Down
Loading