11package com.example.util.simpletimetracker
22
3+ import androidx.test.espresso.Espresso.onView
34import androidx.test.espresso.Espresso.pressBack
5+ import androidx.test.espresso.contrib.PickerActions.setTime
46import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
57import androidx.test.espresso.matcher.ViewMatchers.hasSibling
68import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
79import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
10+ import androidx.test.espresso.matcher.ViewMatchers.withClassName
811import androidx.test.espresso.matcher.ViewMatchers.withId
912import androidx.test.espresso.matcher.ViewMatchers.withSubstring
1013import androidx.test.espresso.matcher.ViewMatchers.withText
1114import androidx.test.ext.junit.runners.AndroidJUnit4
15+ import com.example.util.simpletimetracker.feature_dialogs.R
16+ import com.example.util.simpletimetracker.feature_dialogs.dateTime.CustomTimePicker
1217import com.example.util.simpletimetracker.utils.BaseUiTest
1318import com.example.util.simpletimetracker.utils.NavUtils
1419import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
@@ -20,7 +25,10 @@ import com.example.util.simpletimetracker.utils.tryAction
2025import com.example.util.simpletimetracker.utils.typeTextIntoView
2126import com.example.util.simpletimetracker.utils.withPluralText
2227import dagger.hilt.android.testing.HiltAndroidTest
28+ import java.util.Calendar
29+ import java.util.concurrent.TimeUnit
2330import org.hamcrest.CoreMatchers.allOf
31+ import org.hamcrest.CoreMatchers.equalTo
2432import org.junit.Test
2533import org.junit.runner.RunWith
2634import com.example.util.simpletimetracker.core.R as coreR
@@ -433,6 +441,335 @@ class RecordsFilterTest : BaseUiTest() {
433441 clickOnView(withText(" $name1 - $tag1 " ))
434442 pressBack()
435443 checkRecordsCard(2 )
444+
445+ // Invert selection
446+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
447+ clickOnView(withSubstring(getString(coreR.string.records_filter_manually_filtered)))
448+ clickOnViewWithText(coreR.string.records_filter_invert_selection)
449+ pressBack()
450+ checkRecordsCard(1 )
451+ }
452+
453+ @Test
454+ fun dayOfWeek () {
455+ val name1 = " TypeName1"
456+ val calendar: Calendar = Calendar .getInstance()
457+ val timeStarted = calendar.apply {
458+ set(2023 , 4 , 8 , 15 , 0 )
459+ }.timeInMillis
460+ val timeEnded = timeStarted + TimeUnit .HOURS .toMillis(1 )
461+
462+ // Add data
463+ testUtils.addActivity(name1)
464+ // Monday
465+ repeat(1 ) {
466+ testUtils.addRecord(
467+ typeName = name1,
468+ timeStarted = timeStarted,
469+ timeEnded = timeEnded,
470+ )
471+ }
472+ // Tuesday
473+ repeat(2 ) {
474+ testUtils.addRecord(
475+ typeName = name1,
476+ timeStarted = timeStarted + TimeUnit .DAYS .toMillis(1 ),
477+ timeEnded = timeEnded + TimeUnit .DAYS .toMillis(1 ),
478+ )
479+ }
480+ // Wednesday
481+ repeat(3 ) {
482+ testUtils.addRecord(
483+ typeName = name1,
484+ timeStarted = timeStarted + TimeUnit .DAYS .toMillis(2 ),
485+ timeEnded = timeEnded + TimeUnit .DAYS .toMillis(2 ),
486+ )
487+ }
488+ // Thursday
489+ repeat(4 ) {
490+ testUtils.addRecord(
491+ typeName = name1,
492+ timeStarted = timeStarted + TimeUnit .DAYS .toMillis(3 ),
493+ timeEnded = timeEnded + TimeUnit .DAYS .toMillis(3 ),
494+ )
495+ }
496+ // Friday
497+ repeat(5 ) {
498+ testUtils.addRecord(
499+ typeName = name1,
500+ timeStarted = timeStarted + TimeUnit .DAYS .toMillis(4 ),
501+ timeEnded = timeEnded + TimeUnit .DAYS .toMillis(4 ),
502+ )
503+ }
504+ // Saturday
505+ repeat(6 ) {
506+ testUtils.addRecord(
507+ typeName = name1,
508+ timeStarted = timeStarted + TimeUnit .DAYS .toMillis(5 ),
509+ timeEnded = timeEnded + TimeUnit .DAYS .toMillis(5 ),
510+ )
511+ }
512+ // Saturday
513+ repeat(7 ) {
514+ testUtils.addRecord(
515+ typeName = name1,
516+ timeStarted = timeStarted + TimeUnit .DAYS .toMillis(6 ),
517+ timeEnded = timeEnded + TimeUnit .DAYS .toMillis(6 ),
518+ )
519+ }
520+
521+ // Check
522+ NavUtils .openStatisticsScreen()
523+ clickOnView(allOf(withText(coreR.string.title_today), isCompletelyDisplayed()))
524+ clickOnViewWithText(coreR.string.range_overall)
525+ tryAction { clickOnView(allOf(withText(name1), isCompletelyDisplayed())) }
526+ clickOnViewWithText(coreR.string.title_today)
527+ clickOnViewWithText(coreR.string.range_overall)
528+ checkRecordsCard(28 )
529+
530+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
531+ clickOnView(withSubstring(getString(coreR.string.range_day)))
532+ clickOnViewWithText(coreR.string.day_of_week_monday)
533+ pressBack()
534+ checkRecordsCard(1 )
535+
536+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
537+ clickOnView(withSubstring(getString(coreR.string.range_day)))
538+ clickOnViewWithText(coreR.string.day_of_week_monday)
539+ clickOnViewWithText(coreR.string.day_of_week_tuesday)
540+ pressBack()
541+ checkRecordsCard(2 )
542+
543+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
544+ clickOnView(withSubstring(getString(coreR.string.range_day)))
545+ clickOnViewWithText(coreR.string.day_of_week_tuesday)
546+ clickOnViewWithText(coreR.string.day_of_week_wednesday)
547+ pressBack()
548+ checkRecordsCard(3 )
549+
550+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
551+ clickOnView(withSubstring(getString(coreR.string.range_day)))
552+ clickOnViewWithText(coreR.string.day_of_week_wednesday)
553+ clickOnViewWithText(coreR.string.day_of_week_thursday)
554+ pressBack()
555+ checkRecordsCard(4 )
556+
557+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
558+ clickOnView(withSubstring(getString(coreR.string.range_day)))
559+ clickOnViewWithText(coreR.string.day_of_week_thursday)
560+ clickOnViewWithText(coreR.string.day_of_week_friday)
561+ pressBack()
562+ checkRecordsCard(5 )
563+
564+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
565+ clickOnView(withSubstring(getString(coreR.string.range_day)))
566+ clickOnViewWithText(coreR.string.day_of_week_friday)
567+ clickOnViewWithText(coreR.string.day_of_week_saturday)
568+ pressBack()
569+ checkRecordsCard(6 )
570+
571+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
572+ clickOnView(withSubstring(getString(coreR.string.range_day)))
573+ clickOnViewWithText(coreR.string.day_of_week_saturday)
574+ clickOnViewWithText(coreR.string.day_of_week_sunday)
575+ pressBack()
576+ checkRecordsCard(7 )
577+
578+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
579+ clickOnView(withSubstring(getString(coreR.string.range_day)))
580+ clickOnViewWithText(coreR.string.day_of_week_saturday)
581+ pressBack()
582+ checkRecordsCard(13 )
583+ }
584+
585+ @Test
586+ fun duration () {
587+ val name1 = " TypeName1"
588+ val calendar: Calendar = Calendar .getInstance()
589+
590+ // Add data
591+ testUtils.addActivity(name1)
592+ testUtils.addRecord(
593+ typeName = name1,
594+ timeStarted = calendar.timeInMillis,
595+ timeEnded = calendar.timeInMillis + TimeUnit .MINUTES .toMillis(30 ),
596+ )
597+ testUtils.addRecord(
598+ typeName = name1,
599+ timeStarted = calendar.timeInMillis,
600+ timeEnded = calendar.timeInMillis + TimeUnit .MINUTES .toMillis(80 ),
601+ )
602+ testUtils.addRecord(
603+ typeName = name1,
604+ timeStarted = calendar.timeInMillis,
605+ timeEnded = calendar.timeInMillis + TimeUnit .MINUTES .toMillis(100 ),
606+ )
607+
608+ // Check
609+ NavUtils .openStatisticsScreen()
610+ tryAction { clickOnView(allOf(withText(name1), isCompletelyDisplayed())) }
611+ checkRecordsCard(3 )
612+
613+ // 0s - 1h
614+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
615+ clickOnView(withSubstring(getString(coreR.string.records_all_sort_duration)))
616+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
617+ repeat(6 ) { clickOnViewWithId(R .id.ivDurationPickerDelete) }
618+ clickOnViewWithId(R .id.tvNumberKeyboard1)
619+ repeat(4 ) { clickOnViewWithId(R .id.tvNumberKeyboard0) }
620+ clickOnViewWithText(coreR.string.duration_dialog_save)
621+ pressBack()
622+ checkRecordsCard(1 )
623+
624+ // 1h - 2h
625+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
626+ clickOnView(withSubstring(getString(coreR.string.records_all_sort_duration)))
627+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeStarted)
628+ clickOnViewWithId(R .id.tvNumberKeyboard1)
629+ repeat(4 ) { clickOnViewWithId(R .id.tvNumberKeyboard0) }
630+ clickOnViewWithText(coreR.string.duration_dialog_save)
631+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
632+ repeat(5 ) { clickOnViewWithId(R .id.ivDurationPickerDelete) }
633+ clickOnViewWithId(R .id.tvNumberKeyboard2)
634+ repeat(4 ) { clickOnViewWithId(R .id.tvNumberKeyboard0) }
635+ clickOnViewWithText(coreR.string.duration_dialog_save)
636+ pressBack()
637+ checkRecordsCard(2 )
638+
639+ // 0s - 2h
640+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
641+ clickOnView(withSubstring(getString(coreR.string.records_all_sort_duration)))
642+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeStarted)
643+ repeat(5 ) { clickOnViewWithId(R .id.ivDurationPickerDelete) }
644+ clickOnViewWithText(coreR.string.duration_dialog_save)
645+ pressBack()
646+ checkRecordsCard(3 )
647+
648+ // 0s - 10m
649+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
650+ clickOnView(withSubstring(getString(coreR.string.records_all_sort_duration)))
651+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
652+ repeat(5 ) { clickOnViewWithId(R .id.ivDurationPickerDelete) }
653+ clickOnViewWithId(R .id.tvNumberKeyboard1)
654+ repeat(3 ) { clickOnViewWithId(R .id.tvNumberKeyboard0) }
655+ clickOnViewWithText(coreR.string.duration_dialog_save)
656+ pressBack()
657+ checkRecordsCard(0 )
658+ }
659+
660+ @Test
661+ fun timeOfDay () {
662+ val name1 = " TypeName1"
663+ val calendar: Calendar = Calendar .getInstance().apply {
664+ set(2023 , 4 , 21 , 0 , 0 , 0 )
665+ }
666+ val startOfDay = calendar.timeInMillis
667+
668+ // Add data
669+ testUtils.addActivity(name1)
670+ repeat(1 ) {
671+ testUtils.addRecord(
672+ typeName = name1,
673+ timeStarted = startOfDay + TimeUnit .HOURS .toMillis(2 ),
674+ timeEnded = startOfDay + TimeUnit .HOURS .toMillis(4 ),
675+ )
676+ }
677+ repeat(2 ) {
678+ testUtils.addRecord(
679+ typeName = name1,
680+ timeStarted = startOfDay + TimeUnit .HOURS .toMillis(8 ),
681+ timeEnded = startOfDay + TimeUnit .HOURS .toMillis(10 ),
682+ )
683+ }
684+ repeat(3 ) {
685+ testUtils.addRecord(
686+ typeName = name1,
687+ timeStarted = startOfDay + TimeUnit .HOURS .toMillis(14 ),
688+ timeEnded = startOfDay + TimeUnit .HOURS .toMillis(16 ),
689+ )
690+ }
691+ repeat(4 ) {
692+ testUtils.addRecord(
693+ typeName = name1,
694+ timeStarted = startOfDay + TimeUnit .HOURS .toMillis(20 ),
695+ timeEnded = startOfDay + TimeUnit .HOURS .toMillis(22 ),
696+ )
697+ }
698+
699+ // Check
700+ NavUtils .openStatisticsScreen()
701+ clickOnView(allOf(withText(coreR.string.title_today), isCompletelyDisplayed()))
702+ clickOnViewWithText(coreR.string.range_overall)
703+ tryAction { clickOnView(allOf(withText(name1), isCompletelyDisplayed())) }
704+ clickOnViewWithText(coreR.string.title_today)
705+ clickOnViewWithText(coreR.string.range_overall)
706+ checkRecordsCard(10 )
707+
708+ // 0h - 1h
709+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
710+ clickOnView(withSubstring(getString(coreR.string.date_time_dialog_time)))
711+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
712+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(1 , 0 ))
713+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
714+ pressBack()
715+ checkRecordsCard(0 )
716+
717+ // 0h - 6h
718+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
719+ clickOnView(withSubstring(getString(coreR.string.date_time_dialog_time)))
720+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
721+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(6 , 0 ))
722+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
723+ pressBack()
724+ checkRecordsCard(1 )
725+
726+ // 0h - 12h
727+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
728+ clickOnView(withSubstring(getString(coreR.string.date_time_dialog_time)))
729+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
730+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(12 , 0 ))
731+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
732+ pressBack()
733+ checkRecordsCard(3 )
734+
735+ // 0h - 18h
736+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
737+ clickOnView(withSubstring(getString(coreR.string.date_time_dialog_time)))
738+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
739+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(18 , 0 ))
740+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
741+ pressBack()
742+ checkRecordsCard(6 )
743+
744+ // 0h - 23h
745+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
746+ clickOnView(withSubstring(getString(coreR.string.date_time_dialog_time)))
747+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
748+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(23 , 0 ))
749+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
750+ pressBack()
751+ checkRecordsCard(10 )
752+
753+ // 12h - 23h
754+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
755+ clickOnView(withSubstring(getString(coreR.string.date_time_dialog_time)))
756+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeStarted)
757+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(12 , 0 ))
758+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
759+ pressBack()
760+ checkRecordsCard(7 )
761+
762+ // 18h - 6h
763+ clickOnViewWithId(statisticsDetailR.id.cardStatisticsDetailFilter)
764+ clickOnView(withSubstring(getString(coreR.string.date_time_dialog_time)))
765+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeStarted)
766+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(18 , 0 ))
767+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
768+ clickOnViewWithId(recordsFilterR.id.fieldRecordsFilterRangeTimeEnded)
769+ onView(withClassName(equalTo(CustomTimePicker ::class .java.name))).perform(setTime(6 , 0 ))
770+ clickOnViewWithId(R .id.btnDateTimeDialogPositive)
771+ pressBack()
772+ checkRecordsCard(5 )
436773 }
437774
438775 @Test
0 commit comments