Skip to content

Commit 433942e

Browse files
committed
add new tests
1 parent 24b14c3 commit 433942e

File tree

9 files changed

+418
-12
lines changed

9 files changed

+418
-12
lines changed

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,13 @@ class RecordActionsSplitTest : BaseUiTest() {
8787
timePreview = timeEndedTimestamp.formatDateTime()
8888
checkViewIsDisplayed(allOf(withId(changeRecordR.id.tvChangeRecordTimePreviewItem), withText(timePreview)))
8989
onView(withId(changeRecordR.id.sliderChangeRecordItem)).perform(clickLocation(GeneralLocation.CENTER))
90-
timePreview = calendar.getMillis(16, 17).formatDateTime()
91-
checkViewIsDisplayed(allOf(withId(changeRecordR.id.tvChangeRecordTimePreviewItem), withText(timePreview)))
90+
try {
91+
timePreview = calendar.getMillis(16, 17).formatDateTime()
92+
checkViewIsDisplayed(allOf(withId(changeRecordR.id.tvChangeRecordTimePreviewItem), withText(timePreview)))
93+
} catch (e: Exception) {
94+
timePreview = calendar.getMillis(16, 16).formatDateTime()
95+
checkViewIsDisplayed(allOf(withId(changeRecordR.id.tvChangeRecordTimePreviewItem), withText(timePreview)))
96+
}
9297
}
9398

9499
@Test

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

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.util.simpletimetracker
22

3+
import androidx.test.espresso.Espresso.closeSoftKeyboard
34
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
45
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
56
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
@@ -154,6 +155,7 @@ class StartRecordTest : BaseUiTest() {
154155
clickOnViewWithText(coreR.string.change_record_comment_field)
155156
typeTextIntoView(changeRecordR.id.etChangeRecordCommentField, comment)
156157
clickOnViewWithText(coreR.string.change_record_comment_field)
158+
closeSoftKeyboard()
157159
clickOnViewWithText(coreR.string.change_record_save)
158160

159161
// Stop timer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
package com.example.util.simpletimetracker
2+
3+
import android.view.View
4+
import androidx.test.espresso.Espresso.onView
5+
import androidx.test.espresso.Espresso.pressBack
6+
import androidx.test.espresso.action.ViewActions.click
7+
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyLeftOf
8+
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
9+
import androidx.test.espresso.matcher.ViewMatchers.withId
10+
import androidx.test.espresso.matcher.ViewMatchers.withText
11+
import androidx.test.ext.junit.runners.AndroidJUnit4
12+
import com.example.util.simpletimetracker.feature_base_adapter.recordTypeSuggestion.RecordTypeSuggestionViewData
13+
import com.example.util.simpletimetracker.utils.BaseUiTest
14+
import com.example.util.simpletimetracker.utils.Direction
15+
import com.example.util.simpletimetracker.utils.NavUtils
16+
import com.example.util.simpletimetracker.utils.checkViewDoesNotExist
17+
import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
18+
import com.example.util.simpletimetracker.utils.clickOnViewWithText
19+
import com.example.util.simpletimetracker.utils.drag
20+
import com.example.util.simpletimetracker.utils.scrollRecyclerToView
21+
import com.example.util.simpletimetracker.utils.tryAction
22+
import com.example.util.simpletimetracker.utils.withTag
23+
import dagger.hilt.android.testing.HiltAndroidTest
24+
import kotlinx.coroutines.runBlocking
25+
import org.hamcrest.CoreMatchers.allOf
26+
import org.hamcrest.Matcher
27+
import org.junit.Test
28+
import org.junit.runner.RunWith
29+
30+
@HiltAndroidTest
31+
@RunWith(AndroidJUnit4::class)
32+
class SuggestionsTest : BaseUiTest() {
33+
34+
@Test
35+
fun selectActivities() {
36+
val type1 = "type1"
37+
val type2 = "type2"
38+
val type3 = "type3"
39+
40+
// Add data
41+
testUtils.addActivity(type1)
42+
testUtils.addActivity(type2)
43+
testUtils.addActivity(type3)
44+
45+
// Navigate
46+
NavUtils.openSettingsScreen()
47+
NavUtils.openSettingsAdditional()
48+
NavUtils.openSuggestions()
49+
50+
// Select one
51+
clickOnViewWithText(R.string.change_record_message_choose_type)
52+
checkViewIsDisplayed(withText(type1))
53+
checkViewIsDisplayed(withText(type2))
54+
checkViewIsDisplayed(withText(type3))
55+
clickOnViewWithText(type1)
56+
clickOnViewWithText(R.string.change_record_save)
57+
58+
checkType(type1, true)
59+
checkType(type2, false)
60+
checkType(type3, false)
61+
62+
// Select other
63+
clickOnViewWithText(R.string.change_record_message_choose_type)
64+
clickOnViewWithText(type1)
65+
clickOnViewWithText(type2)
66+
clickOnViewWithText(type3)
67+
clickOnViewWithText(R.string.change_record_save)
68+
69+
checkType(type1, false)
70+
checkType(type2, true)
71+
checkType(type3, true)
72+
73+
// Check that is saved
74+
clickOnViewWithText(R.string.change_category_save)
75+
NavUtils.openSuggestions()
76+
checkType(type1, false)
77+
checkType(type2, true)
78+
checkType(type3, true)
79+
}
80+
81+
@Test
82+
fun addSuggestions() {
83+
val type1 = "type1"
84+
val type2 = "type2"
85+
val type3 = "type3"
86+
val type4 = "type4"
87+
88+
// Add data
89+
testUtils.addActivity(type1)
90+
testUtils.addActivity(type2)
91+
testUtils.addActivity(type3)
92+
testUtils.addActivity(type4)
93+
testUtils.addSuggestion(type1)
94+
testUtils.addSuggestion(type2)
95+
testUtils.addSuggestion(type3)
96+
val typesMap = runBlocking { recordTypeRepo.getAll().associate { it.name to it.id } }
97+
98+
// Navigate
99+
NavUtils.openSettingsScreen()
100+
NavUtils.openSettingsAdditional()
101+
NavUtils.openSuggestions()
102+
103+
checkType(type1, true)
104+
checkType(type2, true)
105+
checkType(type3, true)
106+
checkType(type4, false)
107+
108+
// Add suggestions
109+
checkSuggestion(withText(R.string.running_records_add_type), typesMap[type1], true)
110+
.performClick()
111+
clickOnViewWithText(type2)
112+
clickOnViewWithText(R.string.change_record_save)
113+
checkSuggestion(withText(type2), typesMap[type1], true)
114+
115+
checkSuggestion(withText(R.string.running_records_add_type), typesMap[type2], true)
116+
.performClick()
117+
clickOnViewWithText(type1)
118+
clickOnViewWithText(type3)
119+
clickOnViewWithText(R.string.change_record_save)
120+
checkSuggestion(withText(type1), typesMap[type2], true)
121+
checkSuggestion(withText(type3), typesMap[type2], true)
122+
123+
checkSuggestion(withText(type1), typesMap[type3], false)
124+
checkSuggestion(withText(type2), typesMap[type3], false)
125+
checkSuggestion(withText(type3), typesMap[type3], false)
126+
127+
// Check that is saved
128+
clickOnViewWithText(R.string.change_record_save)
129+
NavUtils.openSuggestions()
130+
checkSuggestion(withText(type2), typesMap[type1], true)
131+
checkSuggestion(withText(type1), typesMap[type2], true)
132+
checkSuggestion(withText(type3), typesMap[type2], true)
133+
}
134+
135+
@Test
136+
fun fromStatistics() {
137+
val type1 = "type1"
138+
val type2 = "type2"
139+
val type3 = "type3"
140+
141+
// Add data
142+
testUtils.addActivity(type1)
143+
testUtils.addActivity(type2)
144+
testUtils.addActivity(type3)
145+
146+
val currentTime = System.currentTimeMillis()
147+
testUtils.addRecord(type1, currentTime - 10, currentTime - 10)
148+
testUtils.addRecord(type2, currentTime - 9, currentTime - 9)
149+
testUtils.addRecord(type1, currentTime - 8, currentTime - 8)
150+
testUtils.addRecord(type3, currentTime - 7, currentTime - 7)
151+
testUtils.addRecord(type1, currentTime - 6, currentTime - 6)
152+
testUtils.addRecord(type3, currentTime - 5, currentTime - 5)
153+
testUtils.addSuggestion(type1)
154+
testUtils.addSuggestion(type2)
155+
testUtils.addSuggestion(type3)
156+
val typesMap = runBlocking { recordTypeRepo.getAll().associate { it.name to it.id } }
157+
158+
// Navigate
159+
NavUtils.openSettingsScreen()
160+
NavUtils.openSettingsAdditional()
161+
NavUtils.openSuggestions()
162+
163+
// Check
164+
clickOnViewWithText(R.string.activity_suggestions_calculate)
165+
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)
169+
onView(type3Matcher).check(isCompletelyLeftOf(type2Matcher))
170+
171+
checkSuggestion(withText(type1), typesMap[type2], true)
172+
checkSuggestion(withText(type2), typesMap[type2], false)
173+
checkSuggestion(withText(type3), typesMap[type2], false)
174+
175+
checkSuggestion(withText(type1), typesMap[type3], true)
176+
checkSuggestion(withText(type2), typesMap[type3], false)
177+
checkSuggestion(withText(type3), typesMap[type3], false)
178+
179+
// Check buttons
180+
pressBack()
181+
NavUtils.openSuggestions()
182+
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)
187+
.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)
191+
onView(type3Matcher).check(isCompletelyLeftOf(type2Matcher))
192+
193+
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)
198+
.performClick()
199+
tryAction { checkSuggestion(withText(type1), typesMap[type2], true) }
200+
checkSuggestion(withText(type2), typesMap[type2], false)
201+
checkSuggestion(withText(type3), typesMap[type2], false)
202+
203+
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)
208+
.performClick()
209+
tryAction { checkSuggestion(withText(type1), typesMap[type3], true) }
210+
checkSuggestion(withText(type2), typesMap[type3], false)
211+
checkSuggestion(withText(type3), typesMap[type3], false)
212+
}
213+
214+
@Test
215+
fun reorder() {
216+
val type1 = "type1"
217+
val type2 = "type2"
218+
val type3 = "type3"
219+
220+
// Add data
221+
testUtils.addActivity(type1)
222+
testUtils.addActivity(type2)
223+
testUtils.addActivity(type3)
224+
testUtils.addSuggestion(type1, listOf(type2, type3))
225+
val typesMap = runBlocking { recordTypeRepo.getAll().associate { it.name to it.id } }
226+
227+
// Navigate
228+
NavUtils.openSettingsScreen()
229+
NavUtils.openSettingsAdditional()
230+
NavUtils.openSuggestions()
231+
232+
// Check
233+
var type2Matcher = checkSuggestion(withText(type2), typesMap[type1], true)
234+
var type3Matcher = checkSuggestion(withText(type3), typesMap[type1], true)
235+
onView(type2Matcher).check(isCompletelyLeftOf(type3Matcher))
236+
237+
// Reorder
238+
onView(type3Matcher).perform(drag(Direction.LEFT, 300))
239+
Thread.sleep(500)
240+
onView(type3Matcher).check(isCompletelyLeftOf(type2Matcher))
241+
clickOnViewWithText(R.string.change_record_save)
242+
243+
// Check that is saved
244+
NavUtils.openSuggestions()
245+
onView(type3Matcher).check(isCompletelyLeftOf(type2Matcher))
246+
247+
// Check on main
248+
pressBack()
249+
NavUtils.openRunningRecordsScreen()
250+
checkViewDoesNotExist(typeMatcher(type1))
251+
checkViewDoesNotExist(typeMatcher(type2))
252+
checkViewDoesNotExist(typeMatcher(type3))
253+
clickOnViewWithText(type1)
254+
type2Matcher = typeMatcher(type2)
255+
type3Matcher = typeMatcher(type3)
256+
tryAction { checkViewIsDisplayed(type2Matcher) }
257+
checkViewIsDisplayed(type3Matcher)
258+
onView(type3Matcher).check(isCompletelyLeftOf(type2Matcher))
259+
}
260+
261+
@Test
262+
fun mainTab() {
263+
val type1 = "type1"
264+
val type2 = "type2"
265+
val type3 = "type3"
266+
267+
// Add data
268+
runBlocking { prefsInteractor.setAllowMultitasking(false) }
269+
testUtils.addActivity(type1)
270+
testUtils.addActivity(type2)
271+
testUtils.addActivity(type3)
272+
testUtils.addSuggestion(type1, listOf(type2, type3))
273+
testUtils.addSuggestion(type2, listOf(type3))
274+
testUtils.addSuggestion(type3, listOf(type1, type2))
275+
Thread.sleep(1000)
276+
277+
// Check
278+
checkViewDoesNotExist(typeMatcher(type1))
279+
checkViewDoesNotExist(typeMatcher(type2))
280+
checkViewDoesNotExist(typeMatcher(type3))
281+
282+
clickOnViewWithText(type1)
283+
checkRunningRecord(type1)
284+
checkViewDoesNotExist(typeMatcher(type1))
285+
checkViewIsDisplayed(typeMatcher(type2))
286+
checkViewIsDisplayed(typeMatcher(type3))
287+
288+
typeMatcher(type2).performClick()
289+
checkRunningRecord(type2)
290+
checkViewDoesNotExist(typeMatcher(type1))
291+
checkViewDoesNotExist(typeMatcher(type2))
292+
checkViewIsDisplayed(typeMatcher(type3))
293+
294+
typeMatcher(type3).performClick()
295+
checkRunningRecord(type3)
296+
checkViewIsDisplayed(typeMatcher(type1))
297+
checkViewIsDisplayed(typeMatcher(type2))
298+
checkViewDoesNotExist(typeMatcher(type3))
299+
}
300+
301+
private fun Matcher<View>.performClick() {
302+
onView(this).perform(click())
303+
}
304+
305+
private fun checkType(
306+
name: String,
307+
visible: Boolean,
308+
) {
309+
val matcher = suggestionTypeMatcher(name)
310+
if (visible) {
311+
scrollRecyclerToView(R.id.rvActivitySuggestionsList, matcher)
312+
checkViewIsDisplayed(matcher)
313+
} else {
314+
checkViewDoesNotExist(matcher)
315+
}
316+
}
317+
318+
private fun checkSuggestion(
319+
textMatcher: Matcher<View>,
320+
tag: Any?,
321+
visible: Boolean,
322+
): Matcher<View> {
323+
val matcher = suggestionMatcher(textMatcher, tag)
324+
if (visible) {
325+
scrollRecyclerToView(R.id.rvActivitySuggestionsList, matcher)
326+
checkViewIsDisplayed(matcher)
327+
} else {
328+
checkViewDoesNotExist(matcher)
329+
}
330+
return matcher
331+
}
332+
333+
private fun suggestionTypeMatcher(name: String): Matcher<View> {
334+
return allOf(
335+
withId(R.id.viewRecordTypeItem),
336+
hasDescendant(withText(name)),
337+
)
338+
}
339+
340+
private fun typeMatcher(name: String): Matcher<View> {
341+
return allOf(
342+
withId(R.id.viewRecordTypeItem),
343+
withTag(RecordTypeSuggestionViewData.TEST_TAG),
344+
hasDescendant(withText(name)),
345+
)
346+
}
347+
348+
private fun suggestionMatcher(
349+
textMatcher: Matcher<View>,
350+
tag: Any?,
351+
): Matcher<View> {
352+
return allOf(
353+
withId(R.id.cvActivitySuggestionListItemContent),
354+
withTag(tag ?: Any()),
355+
hasDescendant(textMatcher),
356+
)
357+
}
358+
359+
private fun checkRunningRecord(name: String) {
360+
checkViewIsDisplayed(allOf(withId(R.id.viewRunningRecordItem), hasDescendant(withText(name))))
361+
}
362+
}

0 commit comments

Comments
 (0)