Skip to content

Commit 64b92e9

Browse files
committed
add ui tests for statistics and records ranges filter
1 parent 52d57ef commit 64b92e9

File tree

6 files changed

+274
-18
lines changed

6 files changed

+274
-18
lines changed

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

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.example.util.simpletimetracker
22

33
import androidx.test.core.app.ApplicationProvider
4-
import androidx.test.espresso.Espresso.onView
54
import androidx.test.espresso.Espresso.pressBack
6-
import androidx.test.espresso.action.ViewActions.click
7-
import androidx.test.espresso.action.ViewActions.longClick
5+
import androidx.test.espresso.matcher.ViewMatchers
6+
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
7+
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
88
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
99
import androidx.test.espresso.matcher.ViewMatchers.withId
1010
import androidx.test.espresso.matcher.ViewMatchers.withText
@@ -15,7 +15,10 @@ import com.example.util.simpletimetracker.di.AppModule
1515
import com.example.util.simpletimetracker.di.DaggerTestAppComponent
1616
import com.example.util.simpletimetracker.ui.MainActivity
1717
import com.example.util.simpletimetracker.utils.NavUtils
18+
import com.example.util.simpletimetracker.utils.checkViewDoesNotExist
19+
import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
1820
import com.example.util.simpletimetracker.utils.clickOnView
21+
import com.example.util.simpletimetracker.utils.clickOnViewWithId
1922
import com.example.util.simpletimetracker.utils.clickOnViewWithText
2023
import com.example.util.simpletimetracker.utils.typeTextIntoView
2124
import org.hamcrest.CoreMatchers.allOf
@@ -50,32 +53,78 @@ class MainScreenTest {
5053
fun test() {
5154
val name = "Test"
5255

56+
// Empty main
57+
checkViewDoesNotExist(withText(R.string.running_records_empty))
58+
59+
// Empty records
60+
NavUtils.openRecordsScreen()
61+
checkViewIsDisplayed(allOf(withText(R.string.records_empty), isCompletelyDisplayed()))
62+
clickOnViewWithId(R.id.btnRecordsContainerPrevious)
63+
checkViewIsDisplayed(allOf(withText(R.string.records_empty), isCompletelyDisplayed()))
64+
clickOnViewWithId(R.id.btnRecordsContainerNext)
65+
clickOnViewWithId(R.id.btnRecordsContainerNext)
66+
checkViewIsDisplayed(allOf(withText(R.string.records_empty), isCompletelyDisplayed()))
67+
68+
// Empty statistics
69+
NavUtils.openStatisticsScreen()
70+
checkViewIsDisplayed(
71+
allOf(
72+
withId(R.id.layoutStatisticsItem),
73+
hasDescendant(withText(R.string.untracked_time_name)),
74+
hasDescendant(ViewMatchers.withSubstring("100%")),
75+
isCompletelyDisplayed()
76+
)
77+
)
78+
clickOnView(allOf(withText(R.string.title_today), isCompletelyDisplayed()))
79+
clickOnViewWithText(R.string.title_this_week)
80+
checkViewIsDisplayed(
81+
allOf(
82+
withId(R.id.layoutStatisticsItem),
83+
hasDescendant(withText(R.string.untracked_time_name)),
84+
hasDescendant(ViewMatchers.withSubstring("100%")),
85+
isCompletelyDisplayed()
86+
)
87+
)
88+
clickOnView(allOf(withText(R.string.title_this_week), isCompletelyDisplayed()))
89+
clickOnViewWithText(R.string.title_overall)
90+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
91+
clickOnView(allOf(withText(R.string.title_overall), isCompletelyDisplayed()))
92+
clickOnViewWithText(R.string.title_today)
93+
clickOnViewWithId(R.id.btnStatisticsContainerPrevious)
94+
checkViewIsDisplayed(
95+
allOf(
96+
withId(R.id.layoutStatisticsItem),
97+
hasDescendant(withText(R.string.untracked_time_name)),
98+
hasDescendant(ViewMatchers.withSubstring("100%")),
99+
isCompletelyDisplayed()
100+
)
101+
)
102+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
103+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
104+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
105+
106+
// Add activity
107+
NavUtils.openRunningRecordsScreen()
53108
clickOnView(withText(R.string.running_records_add_type))
54109
typeTextIntoView(R.id.etChangeRecordTypeName, name)
55110
pressBack()
56111
clickOnView(withText(R.string.change_record_type_save))
112+
checkViewIsDisplayed(withText(R.string.running_records_empty))
113+
114+
// Start timer
57115
clickOnViewWithText(name)
116+
checkViewDoesNotExist(withText(R.string.running_records_empty))
58117
clickOnView(allOf(isDescendantOfA(withId(R.id.layoutRunningRecordItem)), withText(name)))
59118

119+
// Records
60120
NavUtils.openRecordsScreen()
61-
62-
onView(withId(R.id.btnRecordsContainerPrevious)).perform(click())
63-
onView(withId(R.id.btnRecordsContainerPrevious)).perform(click())
64-
onView(withId(R.id.btnRecordsContainerToday)).perform(longClick())
65-
onView(withId(R.id.btnRecordsContainerNext)).perform(click())
66-
onView(withId(R.id.btnRecordsContainerNext)).perform(click())
67-
68-
onView(withId(R.id.btnRecordAdd)).perform(click())
121+
clickOnViewWithId(R.id.btnRecordAdd)
69122
pressBack()
70123

124+
// Statistics
71125
NavUtils.openStatisticsScreen()
72126

73-
onView(withId(R.id.btnStatisticsContainerPrevious)).perform(click())
74-
onView(withId(R.id.btnStatisticsContainerPrevious)).perform(click())
75-
onView(withId(R.id.btnStatisticsContainerToday)).perform(longClick())
76-
onView(withId(R.id.btnStatisticsContainerNext)).perform(click())
77-
onView(withId(R.id.btnStatisticsContainerNext)).perform(click())
78-
127+
// Settings
79128
NavUtils.openSettingsScreen()
80129
}
81130
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.example.util.simpletimetracker
2+
3+
import androidx.test.core.app.ApplicationProvider
4+
import androidx.test.espresso.Espresso.pressBack
5+
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
6+
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
7+
import androidx.test.espresso.matcher.ViewMatchers.withId
8+
import androidx.test.espresso.matcher.ViewMatchers.withText
9+
import androidx.test.ext.junit.rules.ActivityScenarioRule
10+
import androidx.test.ext.junit.runners.AndroidJUnit4
11+
import com.example.util.simpletimetracker.core.mapper.IconMapper
12+
import com.example.util.simpletimetracker.core.utils.TestUtils
13+
import com.example.util.simpletimetracker.di.AppModule
14+
import com.example.util.simpletimetracker.di.DaggerTestAppComponent
15+
import com.example.util.simpletimetracker.ui.MainActivity
16+
import com.example.util.simpletimetracker.utils.NavUtils
17+
import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
18+
import com.example.util.simpletimetracker.utils.clickOnView
19+
import com.example.util.simpletimetracker.utils.clickOnViewWithId
20+
import com.example.util.simpletimetracker.utils.clickOnViewWithText
21+
import com.example.util.simpletimetracker.utils.longClickOnViewWithId
22+
import com.example.util.simpletimetracker.utils.typeTextIntoView
23+
import org.hamcrest.CoreMatchers.allOf
24+
import org.junit.Before
25+
import org.junit.Rule
26+
import org.junit.Test
27+
import org.junit.runner.RunWith
28+
import javax.inject.Inject
29+
30+
@RunWith(AndroidJUnit4::class)
31+
class RecordsRangesTest {
32+
33+
@Inject
34+
lateinit var testUtils: TestUtils
35+
36+
@Inject
37+
lateinit var iconMapper: IconMapper
38+
39+
@Rule
40+
@JvmField
41+
val activityScenarioRule = ActivityScenarioRule(MainActivity::class.java)
42+
43+
@Before
44+
fun setUp() {
45+
val app = ApplicationProvider.getApplicationContext() as TimeTrackerApp
46+
DaggerTestAppComponent.builder()
47+
.appModule(AppModule(app))
48+
.build()
49+
.inject(this)
50+
51+
testUtils.clearDatabase()
52+
testUtils.clearPrefs()
53+
}
54+
55+
@Test
56+
fun test() {
57+
val name = "Test"
58+
59+
// Add activity
60+
NavUtils.openRunningRecordsScreen()
61+
clickOnView(withText(R.string.running_records_add_type))
62+
typeTextIntoView(R.id.etChangeRecordTypeName, name)
63+
pressBack()
64+
clickOnView(withText(R.string.change_record_type_save))
65+
66+
// Start timer
67+
clickOnViewWithText(name)
68+
clickOnView(allOf(isDescendantOfA(withId(R.id.layoutRunningRecordItem)), withText(name)))
69+
70+
// Records
71+
NavUtils.openRecordsScreen()
72+
checkViewIsDisplayed(allOf(withText(name), isCompletelyDisplayed()))
73+
74+
clickOnViewWithId(R.id.btnRecordsContainerPrevious)
75+
checkViewIsDisplayed(allOf(withText(R.string.records_empty), isCompletelyDisplayed()))
76+
clickOnViewWithId(R.id.btnRecordsContainerPrevious)
77+
checkViewIsDisplayed(allOf(withText(R.string.records_empty), isCompletelyDisplayed()))
78+
79+
longClickOnViewWithId(R.id.btnRecordsContainerToday)
80+
checkViewIsDisplayed(allOf(withText(name), isCompletelyDisplayed()))
81+
82+
clickOnViewWithId(R.id.btnRecordsContainerNext)
83+
checkViewIsDisplayed(allOf(withText(R.string.records_empty), isCompletelyDisplayed()))
84+
clickOnViewWithId(R.id.btnRecordsContainerNext)
85+
checkViewIsDisplayed(allOf(withText(R.string.records_empty), isCompletelyDisplayed()))
86+
}
87+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.example.util.simpletimetracker
2+
3+
import androidx.test.core.app.ApplicationProvider
4+
import androidx.test.espresso.Espresso.pressBack
5+
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
6+
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
7+
import androidx.test.espresso.matcher.ViewMatchers.withId
8+
import androidx.test.espresso.matcher.ViewMatchers.withText
9+
import androidx.test.ext.junit.rules.ActivityScenarioRule
10+
import androidx.test.ext.junit.runners.AndroidJUnit4
11+
import com.example.util.simpletimetracker.core.mapper.IconMapper
12+
import com.example.util.simpletimetracker.core.utils.TestUtils
13+
import com.example.util.simpletimetracker.di.AppModule
14+
import com.example.util.simpletimetracker.di.DaggerTestAppComponent
15+
import com.example.util.simpletimetracker.ui.MainActivity
16+
import com.example.util.simpletimetracker.utils.NavUtils
17+
import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
18+
import com.example.util.simpletimetracker.utils.checkViewIsNotDisplayed
19+
import com.example.util.simpletimetracker.utils.clickOnView
20+
import com.example.util.simpletimetracker.utils.clickOnViewWithId
21+
import com.example.util.simpletimetracker.utils.clickOnViewWithText
22+
import com.example.util.simpletimetracker.utils.longClickOnViewWithId
23+
import com.example.util.simpletimetracker.utils.typeTextIntoView
24+
import org.hamcrest.CoreMatchers.allOf
25+
import org.junit.Before
26+
import org.junit.Rule
27+
import org.junit.Test
28+
import org.junit.runner.RunWith
29+
import javax.inject.Inject
30+
31+
@RunWith(AndroidJUnit4::class)
32+
class StatisticsRangesTest {
33+
34+
@Inject
35+
lateinit var testUtils: TestUtils
36+
37+
@Inject
38+
lateinit var iconMapper: IconMapper
39+
40+
@Rule
41+
@JvmField
42+
val activityScenarioRule = ActivityScenarioRule(MainActivity::class.java)
43+
44+
@Before
45+
fun setUp() {
46+
val app = ApplicationProvider.getApplicationContext() as TimeTrackerApp
47+
DaggerTestAppComponent.builder()
48+
.appModule(AppModule(app))
49+
.build()
50+
.inject(this)
51+
52+
testUtils.clearDatabase()
53+
testUtils.clearPrefs()
54+
}
55+
56+
@Test
57+
fun test() {
58+
val name = "Test"
59+
60+
// Add activity
61+
NavUtils.openRunningRecordsScreen()
62+
clickOnView(withText(R.string.running_records_add_type))
63+
typeTextIntoView(R.id.etChangeRecordTypeName, name)
64+
pressBack()
65+
clickOnView(withText(R.string.change_record_type_save))
66+
67+
// Start timer
68+
clickOnViewWithText(name)
69+
clickOnView(allOf(isDescendantOfA(withId(R.id.layoutRunningRecordItem)), withText(name)))
70+
71+
// Statistics
72+
NavUtils.openStatisticsScreen()
73+
checkViewIsDisplayed(allOf(withText(name), isCompletelyDisplayed()))
74+
clickOnViewWithId(R.id.btnStatisticsContainerPrevious)
75+
clickOnViewWithId(R.id.btnStatisticsContainerPrevious)
76+
longClickOnViewWithId(R.id.btnStatisticsContainerToday)
77+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
78+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
79+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
80+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
81+
82+
// Switch to week range
83+
clickOnViewWithId(R.id.btnStatisticsContainerToday)
84+
clickOnViewWithText(R.string.title_this_week)
85+
checkViewIsDisplayed(allOf(withText(name), isCompletelyDisplayed()))
86+
clickOnViewWithId(R.id.btnStatisticsContainerPrevious)
87+
clickOnViewWithId(R.id.btnStatisticsContainerPrevious)
88+
longClickOnViewWithId(R.id.btnStatisticsContainerToday)
89+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
90+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
91+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
92+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
93+
94+
// Switch to month range
95+
clickOnViewWithId(R.id.btnStatisticsContainerToday)
96+
clickOnViewWithText(R.string.title_this_month)
97+
checkViewIsDisplayed(allOf(withText(name), isCompletelyDisplayed()))
98+
clickOnViewWithId(R.id.btnStatisticsContainerPrevious)
99+
clickOnViewWithId(R.id.btnStatisticsContainerPrevious)
100+
longClickOnViewWithId(R.id.btnStatisticsContainerToday)
101+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
102+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
103+
clickOnViewWithId(R.id.btnStatisticsContainerNext)
104+
checkViewIsDisplayed(allOf(withText(R.string.statistics_empty), isCompletelyDisplayed()))
105+
106+
// Switch to overall range
107+
clickOnViewWithId(R.id.btnStatisticsContainerToday)
108+
clickOnViewWithText(R.string.title_overall)
109+
checkViewIsDisplayed(allOf(withText(name), isCompletelyDisplayed()))
110+
checkViewIsNotDisplayed(withId(R.id.btnStatisticsContainerPrevious))
111+
checkViewIsNotDisplayed(withId(R.id.btnStatisticsContainerNext))
112+
}
113+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import com.example.util.simpletimetracker.ChangeRecordTypeTest
77
import com.example.util.simpletimetracker.DeleteRecordTest
88
import com.example.util.simpletimetracker.DeleteRecordTypeTest
99
import com.example.util.simpletimetracker.MainScreenTest
10+
import com.example.util.simpletimetracker.RecordsRangesTest
1011
import com.example.util.simpletimetracker.StartRecordTest
1112
import com.example.util.simpletimetracker.StatisticsFilterTest
13+
import com.example.util.simpletimetracker.StatisticsRangesTest
1214
import com.example.util.simpletimetracker.StatisticsTest
1315
import com.example.util.simpletimetracker.data_local.di.DataLocalModule
1416
import com.example.util.simpletimetracker.feature_widget.di.WidgetModule
@@ -33,6 +35,8 @@ interface TestAppComponent: AppComponent {
3335
fun inject(into: ChangeRecordTest)
3436
fun inject(into: DeleteRecordTest)
3537
fun inject(into: StartRecordTest)
38+
fun inject(into: RecordsRangesTest)
3639
fun inject(into: StatisticsTest)
3740
fun inject(into: StatisticsFilterTest)
41+
fun inject(into: StatisticsRangesTest)
3842
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ fun clickOnView(matcher: Matcher<View>): ViewInteraction =
4747
fun longClickOnView(matcher: Matcher<View>): ViewInteraction =
4848
onView(matcher).perform(longClick())
4949

50+
fun longClickOnViewWithId(id: Int): ViewInteraction =
51+
onView(withId(id)).perform(longClick())
52+
5053
fun clickOnRecyclerItem(id: Int, matcher: Matcher<View>): ViewInteraction =
5154
onView(allOf(isDescendantOfA(withId(id)), matcher)).perform(click())
5255

feature_running_records/src/main/java/com/example/util/simpletimetracker/feature_running_records/viewModel/RunningRecordsViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class RunningRecordsViewModel @Inject constructor(
9696
val runningRecords = runningRecordInteractor.getAll()
9797

9898
val runningRecordsViewData = when {
99-
recordTypes.isEmpty() -> emptyList()
99+
recordTypes.filterNot { it.hidden }.isEmpty() -> emptyList()
100100
runningRecords.isEmpty() -> listOf(runningRecordViewDataMapper.mapToEmpty())
101101
else -> runningRecords
102102
.sortedByDescending {

0 commit comments

Comments
 (0)