Skip to content

Commit

Permalink
Refactor e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
anjmao committed Dec 18, 2019
1 parent 46b3f32 commit e8a5172
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 164 deletions.
161 changes: 8 additions & 153 deletions android/app/src/androidTest/java/network/mysterium/BasicFlowTest.kt
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
package network.mysterium


import android.view.View
import android.view.ViewGroup
import androidx.test.espresso.Espresso.onData
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
import kotlinx.coroutines.delay
import network.mysterium.ui.ProposalsListAdapter
import network.mysterium.vpn.R
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matchers.*
import org.hamcrest.TypeSafeMatcher
import org.hamcrest.core.IsInstanceOf
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -36,148 +18,21 @@ class BasicFlowTest {

@Test
fun registeredIdentityFlowTest() {
val linearLayout = onView(
allOf(withId(R.id.vpn_account_balance_layout),
childAtPosition(
allOf(withId(R.id.vpn_top_status_layout),
childAtPosition(
withId(R.id.linearLayout2),
0)),
1),
isDisplayed()))
linearLayout.perform(click())

val appCompatImageButton = onView(
allOf(childAtPosition(
allOf(withId(R.id.account_toolbar),
childAtPosition(
withClassName(`is`("com.google.android.material.appbar.AppBarLayout")),
0)),
1),
isDisplayed()))
appCompatImageButton.perform(click())

val textView2 = onView(
allOf(withId(R.id.vpn_status_label), withText("Disconnected"),
childAtPosition(
allOf(withId(R.id.vpn_top_status_layout),
childAtPosition(
withId(R.id.linearLayout2),
0)),
2),
isDisplayed()))
textView2.check(matches(withText("Disconnected")))

val constraintLayout = onView(
allOf(withId(R.id.vpn_select_proposal_layout),
childAtPosition(
allOf(withId(R.id.vpn_proposal_picker_layout),
childAtPosition(
withId(R.id.vpn_picker_and_button_layout),
0)),
0),
isDisplayed()))
constraintLayout.perform(click())
Views.checkStatusLabel("Disconnected")
Views.selectProposalLayout.perform(click())

// Wait for proposals to load.
Thread.sleep(5000)

val appCompatEditText = onView(
allOf(withId(R.id.proposals_search_input),
childAtPosition(
allOf(withId(R.id.proposals_header_layout),
childAtPosition(
withClassName(`is`("androidx.constraintlayout.widget.ConstraintLayout")),
0)),
1),
isDisplayed()))
appCompatEditText.perform(replaceText("0x67"), closeSoftKeyboard())
Views.proposalSearchInput.perform(replaceText("0xfbf"), closeSoftKeyboard())

Views.selectProposalItem(0)

onView(withId(R.id.proposals_list))
.perform(actionOnItemAtPosition<ProposalsListAdapter.ProposalViewHolder>(0, click()))
Views.connectionButton.perform(click())

val materialButton2 = onView(
allOf(withId(R.id.vpn_connection_button), withText("Connect"),
childAtPosition(
allOf(withId(R.id.vpn_picker_and_button_layout),
childAtPosition(
withId(R.id.vpn_center_bg_layout),
1)),
1),
isDisplayed()))
materialButton2.perform(click())
Views.checkStatusLabel("Connected")

// Wait to connect
Thread.sleep(5000)

val textView3 = onView(
allOf(withId(R.id.vpn_status_label), withText("Connected"),
childAtPosition(
allOf(withId(R.id.vpn_top_status_layout),
childAtPosition(
withId(R.id.linearLayout2),
0)),
2),
isDisplayed()))
textView3.check(matches(withText("Connected")))

val materialButton3 = onView(
allOf(withId(R.id.vpn_connection_button), withText("Disconnect"),
childAtPosition(
allOf(withId(R.id.vpn_picker_and_button_layout),
childAtPosition(
withId(R.id.vpn_center_bg_layout),
1)),
1),
isDisplayed()))
materialButton3.perform(click())

// Wait to disconnect
Thread.sleep(5000)

val textView4 = onView(
allOf(withId(R.id.vpn_status_label), withText("Disconnected"),
childAtPosition(
allOf(withId(R.id.vpn_top_status_layout),
childAtPosition(
withId(R.id.linearLayout2),
0)),
2),
isDisplayed()))
textView4.check(matches(withText("Disconnected")))
}

fun onViewWait(viewMatcher: Matcher<View>): ViewInteraction {
for (i in 1..3) {
try {
val v = onView(viewMatcher)
v.perform(click())
return v
} catch (e: Throwable) {
if (i == 3) {
throw e
}
Thread.sleep(2000)
}
}
throw Throwable("view not found")
}

private fun childAtPosition(
parentMatcher: Matcher<View>, position: Int): Matcher<View> {

return object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description) {
description.appendText("Child at position $position in parent ")
parentMatcher.describeTo(description)
}
Views.connectionButton.perform(click())

public override fun matchesSafely(view: View): Boolean {
val parent = view.parent
return parent is ViewGroup && parentMatcher.matches(parent)
&& view == parent.getChildAt(position)
}
}
Views.checkStatusLabel("Disconnected")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package network.mysterium

import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@LargeTest
@RunWith(AndroidJUnit4::class)
class BasicFlowWithRegistrationTest {

@Rule
@JvmField
var mActivityTestRule = ActivityTestRule(MainActivity::class.java)

// TODO: For some reasons this fails with Failed to grant permissions, see logcat for details error.
// @Rule
// @JvmField
// val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.BIND_VPN_SERVICE)

@Test
fun basicFlowWithRegistrationTest() {
Views.acceptTermsButton.perform(click())

Views.balanceLabel.perform(click())

Views.registrationPleaseWaitLabel.check(matches(withText("Please wait")))

Views.topUpButton.check(matches(isDisplayed()))

Views.navBackButton.perform(click())

Views.selectProposalLayout.perform(click())

Views.proposalSearchInput.perform(replaceText("0xfbf"), closeSoftKeyboard())

Views.selectProposalItem(0)

Views.connectionButton.perform(click())

Views.checkStatusLabel("Connected")

Views.connectionButton.perform(click())

Views.checkStatusLabel("Disconnected")
}
}
43 changes: 43 additions & 0 deletions android/app/src/androidTest/java/network/mysterium/Helpers.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package network.mysterium

import android.view.View
import android.view.ViewGroup
import androidx.test.espresso.Espresso
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.ViewMatchers
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeMatcher

fun onViewReady(viewMatcher: Matcher<View>, count: Int = 3, sleepMillis: Long = 2000): ViewInteraction {
for (i in 1..count) {
try {
return Espresso.onView(viewMatcher).check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
} catch (e: NoMatchingViewException) {
if (i == count) {
throw e
}
Thread.sleep(sleepMillis)
}
}
throw Throwable("view not found")
}

fun childAtPosition(
parentMatcher: Matcher<View>, position: Int): Matcher<View> {

return object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description) {
description.appendText("Child at position $position in parent ")
parentMatcher.describeTo(description)
}

public override fun matchesSafely(view: View): Boolean {
val parent = view.parent
return parent is ViewGroup && parentMatcher.matches(parent)
&& view == parent.getChildAt(position)
}
}
}
Loading

0 comments on commit e8a5172

Please sign in to comment.