Skip to content

Commit f7e6b20

Browse files
maskaravivekdomdomegg
authored andcommitted
Make all UI tests pass and add more tests (#2700)
1 parent 239f749 commit f7e6b20

8 files changed

+214
-60
lines changed

app/build.gradle

+7
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ dependencies {
7474
androidTestImplementation 'androidx.annotation:annotation:1.0.2'
7575
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.10.0'
7676
androidTestImplementation 'org.mockito:mockito-core:2.10.0'
77+
androidTestUtil 'androidx.test:orchestrator:1.1.1'
7778

7879
// Debugging
7980
implementation 'com.facebook.stetho:stetho:1.5.0'
@@ -109,6 +110,12 @@ android {
109110
minSdkVersion 19
110111
targetSdkVersion 28
111112
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
113+
testInstrumentationRunnerArguments clearPackageData: 'true'
114+
115+
testOptions {
116+
execution 'ANDROIDX_TEST_ORCHESTRATOR'
117+
}
118+
112119
vectorDrawables.useSupportLibrary = true
113120
}
114121

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package fr.free.nrw.commons
2+
3+
import androidx.test.espresso.Espresso.onView
4+
import androidx.test.espresso.action.ViewActions.click
5+
import androidx.test.espresso.contrib.DrawerActions
6+
import androidx.test.espresso.intent.Intents
7+
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent
8+
import androidx.test.espresso.intent.rule.IntentsTestRule
9+
import androidx.test.espresso.matcher.ViewMatchers.withId
10+
import androidx.test.filters.MediumTest
11+
import androidx.test.runner.AndroidJUnit4
12+
import fr.free.nrw.commons.achievements.AchievementsActivity
13+
import fr.free.nrw.commons.auth.LoginActivity
14+
import org.junit.Before
15+
import org.junit.Rule
16+
import org.junit.Test
17+
import org.junit.runner.RunWith
18+
19+
@MediumTest
20+
@RunWith(AndroidJUnit4::class)
21+
class AchievementsActivityTest {
22+
@get:Rule
23+
var activityRule = IntentsTestRule(LoginActivity::class.java)
24+
25+
@Before
26+
fun setup() {
27+
UITestHelper.skipWelcome()
28+
UITestHelper.loginUser()
29+
}
30+
31+
@Test
32+
fun testAchievements() {
33+
onView(withId(R.id.drawer_layout)).perform(DrawerActions.open())
34+
onView(withId(R.id.user_icon)).perform(click())
35+
36+
Intents.intended(hasComponent(AchievementsActivity::class.java.name))
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,57 @@
11
package fr.free.nrw.commons
22

3+
import android.app.Activity
4+
import android.app.Instrumentation.ActivityResult
5+
import android.content.Intent
36
import androidx.test.espresso.Espresso
4-
import androidx.test.espresso.action.ViewActions.click
5-
import androidx.test.espresso.assertion.ViewAssertions
7+
import androidx.test.espresso.action.ViewActions
68
import androidx.test.espresso.intent.Intents
7-
import androidx.test.espresso.intent.Intents.intended
9+
import androidx.test.espresso.intent.Intents.intending
10+
import androidx.test.espresso.intent.matcher.IntentMatchers
811
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent
12+
import androidx.test.espresso.intent.matcher.IntentMatchers.isInternal
913
import androidx.test.espresso.matcher.ViewMatchers
10-
import androidx.test.espresso.matcher.ViewMatchers.withId
11-
import androidx.test.filters.LargeTest
14+
import androidx.test.filters.MediumTest
1215
import androidx.test.rule.ActivityTestRule
1316
import androidx.test.runner.AndroidJUnit4
1417
import fr.free.nrw.commons.auth.LoginActivity
15-
import fr.free.nrw.commons.auth.SignupActivity
18+
import fr.free.nrw.commons.contributions.MainActivity
19+
import org.hamcrest.CoreMatchers
20+
import org.hamcrest.CoreMatchers.not
21+
import org.junit.Before
1622
import org.junit.Rule
1723
import org.junit.Test
1824
import org.junit.runner.RunWith
1925

20-
@LargeTest
26+
27+
@MediumTest
2128
@RunWith(AndroidJUnit4::class)
2229
class LoginActivityTest {
2330
@get:Rule
24-
var activity: ActivityTestRule<*> = ActivityTestRule(LoginActivity::class.java)
31+
var activityRule = ActivityTestRule(LoginActivity::class.java)
32+
33+
@Before
34+
fun setup() {
35+
try {
36+
Intents.init()
37+
} catch (ex: IllegalStateException) {
38+
39+
}
40+
UITestHelper.skipWelcome()
41+
intending(not(isInternal())).respondWith(ActivityResult(Activity.RESULT_OK, null))
42+
}
43+
44+
@Test
45+
fun testLogin() {
46+
UITestHelper.loginUser()
47+
UITestHelper.sleep(10000)
48+
Intents.intended(hasComponent(MainActivity::class.java.name))
49+
}
2550

2651
@Test
27-
fun isSignUpButtonWorks() {
28-
// Clicks the SignUp Button
29-
Intents.init()
30-
Espresso.onView(withId(R.id.signupButton))
31-
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
32-
.perform(click())
33-
intended(hasComponent(SignupActivity::class.java.name))
34-
Intents.release()
52+
fun testForgotPassword() {
53+
Espresso.onView(ViewMatchers.withId(R.id.forgotPassword))
54+
.perform(ViewActions.click())
55+
Intents.intended(CoreMatchers.allOf(IntentMatchers.hasAction(Intent.ACTION_VIEW), IntentMatchers.hasData(BuildConfig.FORGOT_PASSWORD_URL)));
3556
}
3657
}

app/src/androidTest/java/fr/free/nrw/commons/NavigationBaseActivityTest.kt

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class NavigationBaseActivityTest {
6060

6161
private fun openNavigationDrawerAndNavigateTo(menuItemId: Int) {
6262
onView(withId(R.id.drawer_layout)).perform(DrawerActions.open())
63+
UITestHelper.sleep(500)
6364
onView(withId(R.id.navigation_view)).perform(NavigationViewActions.navigateTo(menuItemId))
6465
}
6566
}

app/src/androidTest/java/fr/free/nrw/commons/SettingsActivityTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ class SettingsActivityTest {
123123

124124
@Test
125125
fun useAuthorNameTogglesOn() {
126-
// Turn on "Use external storage" preference if currently off
127-
if (!defaultKvStore.getBoolean("useAuthorName", true)) {
126+
// Turn on "Use author name" preference if currently off
127+
if (!defaultKvStore.getBoolean("useAuthorName", false)) {
128128
Espresso.onData(PreferenceMatchers.withKey("useAuthorName"))
129129
.inAdapterView(withId(android.R.id.list))
130130
.perform(click())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package fr.free.nrw.commons
2+
3+
import androidx.test.espresso.Espresso
4+
import androidx.test.espresso.action.ViewActions.click
5+
import androidx.test.espresso.assertion.ViewAssertions
6+
import androidx.test.espresso.intent.Intents
7+
import androidx.test.espresso.intent.Intents.intended
8+
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent
9+
import androidx.test.espresso.matcher.ViewMatchers
10+
import androidx.test.espresso.matcher.ViewMatchers.withId
11+
import androidx.test.filters.MediumTest
12+
import androidx.test.rule.ActivityTestRule
13+
import androidx.test.runner.AndroidJUnit4
14+
import fr.free.nrw.commons.auth.LoginActivity
15+
import fr.free.nrw.commons.auth.SignupActivity
16+
import org.junit.Before
17+
import org.junit.Rule
18+
import org.junit.Test
19+
import org.junit.runner.RunWith
20+
21+
@MediumTest
22+
@RunWith(AndroidJUnit4::class)
23+
class SignupTest {
24+
@get:Rule
25+
var activityRule: ActivityTestRule<*> = ActivityTestRule(LoginActivity::class.java)
26+
27+
@Before
28+
fun setup() {
29+
UITestHelper.skipWelcome()
30+
}
31+
32+
@Test
33+
fun testSignupButton() {
34+
try {
35+
Intents.init()
36+
} catch (ex: IllegalStateException) {
37+
38+
}
39+
40+
Espresso.onView(withId(R.id.signupButton))
41+
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
42+
.perform(click())
43+
intended(hasComponent(SignupActivity::class.java.name))
44+
Intents.release()
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package fr.free.nrw.commons
2+
3+
import androidx.test.espresso.Espresso.closeSoftKeyboard
4+
import androidx.test.espresso.Espresso.onView
5+
import androidx.test.espresso.NoMatchingViewException
6+
import androidx.test.espresso.action.ViewActions
7+
import androidx.test.espresso.matcher.ViewMatchers
8+
import fr.free.nrw.commons.utils.StringUtils
9+
import timber.log.Timber
10+
11+
class UITestHelper {
12+
companion object {
13+
fun skipWelcome() {
14+
try {
15+
//Skip tutorial
16+
onView(ViewMatchers.withId(R.id.finishTutorialButton))
17+
.perform(ViewActions.click())
18+
} catch (ignored: NoMatchingViewException) {
19+
}
20+
}
21+
22+
fun loginUser() {
23+
try {
24+
//Perform Login
25+
onView(ViewMatchers.withId(R.id.loginUsername))
26+
.perform(ViewActions.clearText(), ViewActions.typeText(getTestUsername()))
27+
onView(ViewMatchers.withId(R.id.loginPassword))
28+
.perform(ViewActions.clearText(), ViewActions.typeText(getTestUserPassword()))
29+
closeSoftKeyboard()
30+
onView(ViewMatchers.withId(R.id.loginButton))
31+
.perform(ViewActions.click())
32+
sleep(5000)
33+
} catch (ignored: NoMatchingViewException) {
34+
}
35+
36+
}
37+
38+
fun sleep(timeInMillis: Long) {
39+
try {
40+
Timber.d("Sleeping for %d", timeInMillis)
41+
Thread.sleep(timeInMillis)
42+
} catch (e: InterruptedException) {
43+
e.printStackTrace()
44+
}
45+
}
46+
47+
private fun getTestUsername(): String {
48+
val username = BuildConfig.TEST_USERNAME
49+
if (StringUtils.isNullOrWhiteSpace(username) || username == "null") {
50+
throw NotImplementedError("Configure your beta account's username")
51+
} else return username
52+
}
53+
54+
private fun getTestUserPassword(): String {
55+
val password = BuildConfig.TEST_PASSWORD
56+
if (StringUtils.isNullOrWhiteSpace(password) || password == "null") {
57+
throw NotImplementedError("Configure your beta account's password")
58+
} else return password
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)