Skip to content

Commit 36d504b

Browse files
committed
add new backup tests
1 parent e647ef6 commit 36d504b

File tree

10 files changed

+496
-123
lines changed

10 files changed

+496
-123
lines changed

app/src/androidTest/java/com/example/util/simpletimetracker/SettingsBackupTest.kt

Lines changed: 282 additions & 27 deletions
Large diffs are not rendered by default.

app/src/androidTest/java/com/example/util/simpletimetracker/SuggestionsTest.kt

Lines changed: 45 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
99
import androidx.test.espresso.matcher.ViewMatchers.withId
1010
import androidx.test.espresso.matcher.ViewMatchers.withText
1111
import androidx.test.ext.junit.runners.AndroidJUnit4
12+
import com.example.util.simpletimetracker.SuggestionsTestUtils.checkSuggestion
13+
import com.example.util.simpletimetracker.SuggestionsTestUtils.checkType
1214
import com.example.util.simpletimetracker.feature_base_adapter.recordTypeSuggestion.RecordTypeSuggestionViewData
1315
import com.example.util.simpletimetracker.utils.BaseUiTest
1416
import com.example.util.simpletimetracker.utils.Direction
@@ -17,7 +19,6 @@ import com.example.util.simpletimetracker.utils.checkViewDoesNotExist
1719
import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
1820
import com.example.util.simpletimetracker.utils.clickOnViewWithText
1921
import com.example.util.simpletimetracker.utils.drag
20-
import com.example.util.simpletimetracker.utils.scrollRecyclerToView
2122
import com.example.util.simpletimetracker.utils.tryAction
2223
import com.example.util.simpletimetracker.utils.withTag
2324
import dagger.hilt.android.testing.HiltAndroidTest
@@ -106,30 +107,30 @@ class SuggestionsTest : BaseUiTest() {
106107
checkType(type4, false)
107108

108109
// Add suggestions
109-
checkSuggestion(withText(R.string.running_records_add_type), typesMap[type1], true)
110+
checkSuggestion(type1, withText(R.string.running_records_add_type), typesMap[type1], true)
110111
.performClick()
111112
clickOnViewWithText(type2)
112113
clickOnViewWithText(R.string.change_record_save)
113-
checkSuggestion(withText(type2), typesMap[type1], true)
114+
checkSuggestion(type1, withText(type2), typesMap[type1], true)
114115

115-
checkSuggestion(withText(R.string.running_records_add_type), typesMap[type2], true)
116+
checkSuggestion(type2, withText(R.string.running_records_add_type), typesMap[type2], true)
116117
.performClick()
117118
clickOnViewWithText(type1)
118119
clickOnViewWithText(type3)
119120
clickOnViewWithText(R.string.change_record_save)
120-
checkSuggestion(withText(type1), typesMap[type2], true)
121-
checkSuggestion(withText(type3), typesMap[type2], true)
121+
checkSuggestion(type2, withText(type1), typesMap[type2], true)
122+
checkSuggestion(type2, withText(type3), typesMap[type2], true)
122123

123-
checkSuggestion(withText(type1), typesMap[type3], false)
124-
checkSuggestion(withText(type2), typesMap[type3], false)
125-
checkSuggestion(withText(type3), typesMap[type3], false)
124+
checkSuggestion(type3, withText(type1), typesMap[type3], false)
125+
checkSuggestion(type3, withText(type2), typesMap[type3], false)
126+
checkSuggestion(type3, withText(type3), typesMap[type3], false)
126127

127128
// Check that is saved
128129
clickOnViewWithText(R.string.change_record_save)
129130
NavUtils.openSuggestions()
130-
checkSuggestion(withText(type2), typesMap[type1], true)
131-
checkSuggestion(withText(type1), typesMap[type2], true)
132-
checkSuggestion(withText(type3), typesMap[type2], true)
131+
checkSuggestion(type1, withText(type2), typesMap[type1], true)
132+
checkSuggestion(type2, withText(type1), typesMap[type2], true)
133+
checkSuggestion(type2, withText(type3), typesMap[type2], true)
133134
}
134135

135136
@Test
@@ -163,52 +164,52 @@ class SuggestionsTest : BaseUiTest() {
163164
// Check
164165
clickOnViewWithText(R.string.activity_suggestions_calculate)
165166

166-
checkSuggestion(withText(type1), typesMap[type1], false)
167-
var type2Matcher = checkSuggestion(withText(type2), typesMap[type1], true)
168-
var type3Matcher = checkSuggestion(withText(type3), typesMap[type1], true)
167+
checkSuggestion(type1, withText(type1), typesMap[type1], false)
168+
var type2Matcher = checkSuggestion(type1, withText(type2), typesMap[type1], true)
169+
var type3Matcher = checkSuggestion(type1, withText(type3), typesMap[type1], true)
169170
onView(type3Matcher).check(isCompletelyLeftOf(type2Matcher))
170171

171-
checkSuggestion(withText(type1), typesMap[type2], true)
172-
checkSuggestion(withText(type2), typesMap[type2], false)
173-
checkSuggestion(withText(type3), typesMap[type2], false)
172+
checkSuggestion(type2, withText(type1), typesMap[type2], true)
173+
checkSuggestion(type2, withText(type2), typesMap[type2], false)
174+
checkSuggestion(type2, withText(type3), typesMap[type2], false)
174175

175-
checkSuggestion(withText(type1), typesMap[type3], true)
176-
checkSuggestion(withText(type2), typesMap[type3], false)
177-
checkSuggestion(withText(type3), typesMap[type3], false)
176+
checkSuggestion(type3, withText(type1), typesMap[type3], true)
177+
checkSuggestion(type3, withText(type2), typesMap[type3], false)
178+
checkSuggestion(type3, withText(type3), typesMap[type3], false)
178179

179180
// Check buttons
180181
pressBack()
181182
NavUtils.openSuggestions()
182183

183-
checkSuggestion(withText(type1), typesMap[type1], false)
184-
checkSuggestion(withText(type2), typesMap[type1], false)
185-
checkSuggestion(withText(type3), typesMap[type1], false)
186-
checkSuggestion(withText(R.string.shortcut_navigation_statistics), typesMap[type1], true)
184+
checkSuggestion(type1, withText(type1), typesMap[type1], false)
185+
checkSuggestion(type1, withText(type2), typesMap[type1], false)
186+
checkSuggestion(type1, withText(type3), typesMap[type1], false)
187+
checkSuggestion(type1, withText(R.string.shortcut_navigation_statistics), typesMap[type1], true)
187188
.performClick()
188-
tryAction { checkSuggestion(withText(type1), typesMap[type1], false) }
189-
type2Matcher = checkSuggestion(withText(type2), typesMap[type1], true)
190-
type3Matcher = checkSuggestion(withText(type3), typesMap[type1], true)
189+
tryAction { checkSuggestion(type1, withText(type1), typesMap[type1], false) }
190+
type2Matcher = checkSuggestion(type1, withText(type2), typesMap[type1], true)
191+
type3Matcher = checkSuggestion(type1, withText(type3), typesMap[type1], true)
191192
onView(type3Matcher).check(isCompletelyLeftOf(type2Matcher))
192193

193194
Thread.sleep(500)
194-
checkSuggestion(withText(type1), typesMap[type2], false)
195-
checkSuggestion(withText(type2), typesMap[type2], false)
196-
checkSuggestion(withText(type3), typesMap[type2], false)
197-
checkSuggestion(withText(R.string.shortcut_navigation_statistics), typesMap[type2], true)
195+
checkSuggestion(type2, withText(type1), typesMap[type2], false)
196+
checkSuggestion(type2, withText(type2), typesMap[type2], false)
197+
checkSuggestion(type2, withText(type3), typesMap[type2], false)
198+
checkSuggestion(type2, withText(R.string.shortcut_navigation_statistics), typesMap[type2], true)
198199
.performClick()
199-
tryAction { checkSuggestion(withText(type1), typesMap[type2], true) }
200-
checkSuggestion(withText(type2), typesMap[type2], false)
201-
checkSuggestion(withText(type3), typesMap[type2], false)
200+
tryAction { checkSuggestion(type2, withText(type1), typesMap[type2], true) }
201+
checkSuggestion(type2, withText(type2), typesMap[type2], false)
202+
checkSuggestion(type2, withText(type3), typesMap[type2], false)
202203

203204
Thread.sleep(500)
204-
checkSuggestion(withText(type1), typesMap[type3], false)
205-
checkSuggestion(withText(type2), typesMap[type3], false)
206-
checkSuggestion(withText(type3), typesMap[type3], false)
207-
checkSuggestion(withText(R.string.shortcut_navigation_statistics), typesMap[type3], true)
205+
checkSuggestion(type3, withText(type1), typesMap[type3], false)
206+
checkSuggestion(type3, withText(type2), typesMap[type3], false)
207+
checkSuggestion(type3, withText(type3), typesMap[type3], false)
208+
checkSuggestion(type3, withText(R.string.shortcut_navigation_statistics), typesMap[type3], true)
208209
.performClick()
209-
tryAction { checkSuggestion(withText(type1), typesMap[type3], true) }
210-
checkSuggestion(withText(type2), typesMap[type3], false)
211-
checkSuggestion(withText(type3), typesMap[type3], false)
210+
tryAction { checkSuggestion(type3, withText(type1), typesMap[type3], true) }
211+
checkSuggestion(type3, withText(type2), typesMap[type3], false)
212+
checkSuggestion(type3, withText(type3), typesMap[type3], false)
212213
}
213214

214215
@Test
@@ -230,8 +231,8 @@ class SuggestionsTest : BaseUiTest() {
230231
NavUtils.openSuggestions()
231232

232233
// Check
233-
var type2Matcher = checkSuggestion(withText(type2), typesMap[type1], true)
234-
var type3Matcher = checkSuggestion(withText(type3), typesMap[type1], true)
234+
var type2Matcher = checkSuggestion(type1, withText(type2), typesMap[type1], true)
235+
var type3Matcher = checkSuggestion(type1, withText(type3), typesMap[type1], true)
235236
onView(type2Matcher).check(isCompletelyLeftOf(type3Matcher))
236237

237238
// Reorder
@@ -341,41 +342,6 @@ class SuggestionsTest : BaseUiTest() {
341342
onView(this).perform(click())
342343
}
343344

344-
private fun checkType(
345-
name: String,
346-
visible: Boolean,
347-
) {
348-
val matcher = suggestionTypeMatcher(name)
349-
if (visible) {
350-
scrollRecyclerToView(R.id.rvActivitySuggestionsList, matcher)
351-
checkViewIsDisplayed(matcher)
352-
} else {
353-
checkViewDoesNotExist(matcher)
354-
}
355-
}
356-
357-
private fun checkSuggestion(
358-
textMatcher: Matcher<View>,
359-
tag: Any?,
360-
visible: Boolean,
361-
): Matcher<View> {
362-
val matcher = suggestionMatcher(textMatcher, tag)
363-
if (visible) {
364-
scrollRecyclerToView(R.id.rvActivitySuggestionsList, matcher)
365-
checkViewIsDisplayed(matcher)
366-
} else {
367-
checkViewDoesNotExist(matcher)
368-
}
369-
return matcher
370-
}
371-
372-
private fun suggestionTypeMatcher(name: String): Matcher<View> {
373-
return allOf(
374-
withId(R.id.viewRecordTypeItem),
375-
hasDescendant(withText(name)),
376-
)
377-
}
378-
379345
private fun typeMatcher(name: String): Matcher<View> {
380346
return allOf(
381347
withId(R.id.viewRecordTypeItem),
@@ -384,17 +350,6 @@ class SuggestionsTest : BaseUiTest() {
384350
)
385351
}
386352

387-
private fun suggestionMatcher(
388-
textMatcher: Matcher<View>,
389-
tag: Any?,
390-
): Matcher<View> {
391-
return allOf(
392-
withId(R.id.cvActivitySuggestionListItemContent),
393-
withTag(tag ?: Any()),
394-
hasDescendant(textMatcher),
395-
)
396-
}
397-
398353
private fun checkRunningRecord(name: String) {
399354
checkViewIsDisplayed(allOf(withId(R.id.viewRunningRecordItem), hasDescendant(withText(name))))
400355
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.example.util.simpletimetracker
2+
3+
import android.view.View
4+
import androidx.test.espresso.Espresso.onView
5+
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyBelow
6+
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
7+
import androidx.test.espresso.matcher.ViewMatchers.withId
8+
import androidx.test.espresso.matcher.ViewMatchers.withText
9+
import com.example.util.simpletimetracker.utils.checkViewDoesNotExist
10+
import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
11+
import com.example.util.simpletimetracker.utils.scrollRecyclerToView
12+
import com.example.util.simpletimetracker.utils.withTag
13+
import org.hamcrest.CoreMatchers.allOf
14+
import org.hamcrest.Matcher
15+
16+
object SuggestionsTestUtils {
17+
18+
fun checkType(
19+
name: String,
20+
visible: Boolean,
21+
) {
22+
val matcher = suggestionTypeMatcher(name)
23+
if (visible) {
24+
scrollRecyclerToView(R.id.rvActivitySuggestionsList, matcher)
25+
checkViewIsDisplayed(matcher)
26+
} else {
27+
checkViewDoesNotExist(matcher)
28+
}
29+
}
30+
31+
fun checkSuggestion(
32+
forType: String,
33+
textMatcher: Matcher<View>,
34+
tag: Any?,
35+
visible: Boolean,
36+
): Matcher<View> {
37+
val typeMatcher = suggestionTypeMatcher(forType)
38+
val matcher = suggestionMatcher(textMatcher, tag)
39+
if (visible) {
40+
scrollRecyclerToView(R.id.rvActivitySuggestionsList, matcher)
41+
checkViewIsDisplayed(matcher)
42+
onView(matcher).check(isCompletelyBelow(typeMatcher))
43+
} else {
44+
checkViewDoesNotExist(matcher)
45+
}
46+
return matcher
47+
}
48+
49+
private fun suggestionTypeMatcher(name: String): Matcher<View> {
50+
return allOf(
51+
withId(R.id.viewRecordTypeItem),
52+
hasDescendant(withText(name)),
53+
)
54+
}
55+
56+
private fun suggestionMatcher(
57+
textMatcher: Matcher<View>,
58+
tag: Any?,
59+
): Matcher<View> {
60+
return allOf(
61+
withId(R.id.cvActivitySuggestionListItemContent),
62+
withTag(tag ?: Any()),
63+
hasDescendant(textMatcher),
64+
)
65+
}
66+
}

app/src/androidTest/java/com/example/util/simpletimetracker/di/TestActionResolverImpl.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import com.example.util.simpletimetracker.navigation.ResultContainer
1111
import com.example.util.simpletimetracker.navigation.params.action.ActionParams
1212
import com.example.util.simpletimetracker.navigation.params.action.OpenFileParams
1313
import javax.inject.Inject
14-
import com.example.util.simpletimetracker.test.R as testR
1514

1615
class TestActionResolverImpl @Inject constructor(
1716
private val resultContainer: ResultContainer,
@@ -30,7 +29,7 @@ class TestActionResolverImpl @Inject constructor(
3029
private fun openFile() {
3130
resultContainer.sendResult(
3231
RequestCode.REQUEST_CODE_OPEN_FILE,
33-
resourceToUri(testR.raw.db_version_23).toString(),
32+
resourceToUri(testDatabaseNameResId).toString(),
3433
)
3534
}
3635

@@ -44,4 +43,9 @@ class TestActionResolverImpl @Inject constructor(
4443
context.resources.getResourceEntryName(resID),
4544
)
4645
}
46+
47+
companion object {
48+
// Set in test.
49+
var testDatabaseNameResId: Int = 0
50+
}
4751
}

app/src/androidTest/java/com/example/util/simpletimetracker/utils/Matchers.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ import androidx.core.content.ContextCompat
1111
import androidx.test.espresso.Root
1212
import androidx.test.espresso.matcher.BoundedMatcher
1313
import androidx.test.espresso.matcher.ViewMatchers.withTagValue
14+
import com.google.android.material.button.MaterialButton
1415
import com.google.android.material.slider.Slider
15-
import kotlin.math.roundToInt
1616
import org.hamcrest.CoreMatchers.equalTo
1717
import org.hamcrest.Description
1818
import org.hamcrest.Matcher
1919
import org.hamcrest.TypeSafeMatcher
20+
import kotlin.math.roundToInt
2021

2122
fun withCardColor(expectedId: Int): Matcher<View> =
2223
object : BoundedMatcher<View, CardView>(CardView::class.java) {
@@ -43,9 +44,35 @@ fun withCardColorInt(@ColorInt colorInt: Int): Matcher<View> =
4344
}
4445
}
4546

47+
// TODO doesn't work.
48+
fun withButtonColor(expectedId: Int): Matcher<View> =
49+
object : BoundedMatcher<View, MaterialButton>(MaterialButton::class.java) {
50+
override fun matchesSafely(view: MaterialButton): Boolean {
51+
val colorInt: Int = ContextCompat.getColor(view.context, expectedId)
52+
return view.backgroundTintList?.defaultColor == colorInt
53+
}
54+
55+
override fun describeTo(description: Description) {
56+
description.appendText("with button color: ")
57+
description.appendValue(expectedId)
58+
}
59+
}
60+
4661
fun withTag(tagValueMatcher: Any): Matcher<View> =
4762
withTagValue(equalTo(tagValueMatcher))
4863

64+
fun withNullTag(): Matcher<View> {
65+
return object : TypeSafeMatcher<View>() {
66+
override fun matchesSafely(view: View?): Boolean {
67+
return view?.tag == null
68+
}
69+
70+
override fun describeTo(description: Description) {
71+
description.appendText("view with null tag")
72+
}
73+
}
74+
}
75+
4976
fun isToast(): Matcher<Root> {
5077
return object : TypeSafeMatcher<Root>() {
5178
override fun matchesSafely(item: Root): Boolean {

app/src/androidTest/java/com/example/util/simpletimetracker/utils/ViewActions.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,16 @@ fun tryAction(action: () -> Unit) {
253253
}
254254
action()
255255
}
256+
257+
fun tryActionWithFallback(
258+
onError: () -> Unit,
259+
action: () -> Unit,
260+
) {
261+
try {
262+
action()
263+
return
264+
} catch (e: Throwable) {
265+
onError.invoke()
266+
}
267+
action()
268+
}

0 commit comments

Comments
 (0)