1+ package org.scottishtecharmy.soundscape
2+
3+ import androidx.compose.foundation.layout.WindowInsets
4+ import androidx.compose.foundation.layout.safeDrawing
5+ import androidx.compose.foundation.layout.windowInsetsPadding
6+ import androidx.compose.ui.Modifier
7+ import androidx.compose.ui.test.junit4.createComposeRule
8+ import androidx.navigation.NavController
9+ import androidx.preference.PreferenceManager
10+ import androidx.test.platform.app.InstrumentationRegistry
11+ import kotlinx.coroutines.flow.MutableStateFlow
12+ import org.scottishtecharmy.soundscape.ui.theme.SoundscapeTheme
13+ import org.junit.Rule
14+ import org.junit.Test
15+ import org.scottishtecharmy.soundscape.MainActivity.Companion.ACCESSIBLE_MAP_KEY
16+ import org.scottishtecharmy.soundscape.database.local.model.MarkerEntity
17+ import org.scottishtecharmy.soundscape.database.local.model.RouteEntity
18+ import org.scottishtecharmy.soundscape.database.local.model.RouteWithMarkers
19+ import org.scottishtecharmy.soundscape.geojsonparser.geojson.LngLatAlt
20+ import org.scottishtecharmy.soundscape.screens.home.BottomButtonFunctions
21+ import org.scottishtecharmy.soundscape.screens.home.RouteFunctions
22+ import org.scottishtecharmy.soundscape.screens.home.StreetPreviewFunctions
23+ import org.scottishtecharmy.soundscape.screens.home.data.LocationDescription
24+ import org.scottishtecharmy.soundscape.screens.home.home.Home
25+ import org.scottishtecharmy.soundscape.screens.home.placesnearby.PlacesNearbyUiState
26+ import org.scottishtecharmy.soundscape.screens.markers_routes.screens.addandeditroutescreen.AddAndEditRouteScreen
27+ import org.scottishtecharmy.soundscape.screens.markers_routes.screens.addandeditroutescreen.AddAndEditRouteUiState
28+ import org.scottishtecharmy.soundscape.screens.markers_routes.screens.routedetailsscreen.RouteDetailsScreen
29+ import org.scottishtecharmy.soundscape.screens.markers_routes.screens.routedetailsscreen.RouteDetailsUiState
30+ import org.scottishtecharmy.soundscape.services.RoutePlayerState
31+ import org.scottishtecharmy.soundscape.viewmodels.home.HomeState
32+
33+ // This is very helpful:
34+ // https://developer.android.com/develop/ui/compose/testing/testing-cheatsheet
35+ class DocumentationScreens {
36+ @get:Rule
37+ val composeTestRule = createComposeRule()
38+
39+ private val location = LngLatAlt (
40+ - 4.3178027 ,
41+ 55.9410791
42+ )
43+
44+ private val routeToShops = RouteWithMarkers (
45+ RouteEntity (
46+ name = " Route to shops" ,
47+ description = " " ,
48+ routeId = 1L
49+ ),
50+ listOf (
51+ MarkerEntity (
52+ name = " Craigton Road" ,
53+ longitude = - 4.3239319 ,
54+ latitude = 55.9446396 ,
55+ markerId = 1L
56+ ),
57+ MarkerEntity (
58+ name = " Clober Road" ,
59+ longitude = - 4.3210534 ,
60+ latitude = 55.9417227 ,
61+ markerId = 1L
62+ ),
63+ MarkerEntity (
64+ name = " Douglas Street" ,
65+ longitude = - 4.3194968 ,
66+ latitude = 55.9406974 ,
67+ markerId = 1L
68+ ),
69+ MarkerEntity (
70+ name = " Underpass entry" ,
71+ longitude = - 4.3175668 ,
72+ latitude = 55.9399973 ,
73+ markerId = 2L
74+ )
75+ )
76+ )
77+
78+ @Test
79+ fun homeScreen (){
80+ val targetContext = InstrumentationRegistry .getInstrumentation().targetContext
81+
82+ val sharedPreferences = PreferenceManager .getDefaultSharedPreferences(targetContext)
83+ // Use accessible map
84+ sharedPreferences.edit().putBoolean(ACCESSIBLE_MAP_KEY , true ).apply ()
85+
86+ val themeStateFlow = MutableStateFlow (ThemeState ())
87+ composeTestRule.setContent {
88+ SoundscapeTheme (themeStateFlow) {
89+ Home (
90+ state = HomeState (
91+ location = location,
92+ heading = 45.0F ,
93+
94+ ),
95+ onNavigate = {},
96+ preferences = sharedPreferences,
97+ onMapLongClick = { false },
98+ bottomButtonFunctions = BottomButtonFunctions (null ),
99+ getCurrentLocationDescription = {
100+ LocationDescription (
101+ name = " Milngavie" ,
102+ location = location
103+ )
104+ },
105+ searchText = " " ,
106+ onToggleSearch = { },
107+ onSearchTextChange = { },
108+ rateSoundscape = { },
109+ routeFunctions = RouteFunctions (viewModel = null ),
110+ streetPreviewFunctions = StreetPreviewFunctions (viewModel = null ),
111+ modifier = Modifier .windowInsetsPadding(WindowInsets .safeDrawing)
112+ )
113+ }
114+ }
115+
116+ // Delay to allow the maps to load
117+ Thread .sleep(5000 )
118+
119+ // Capture screenshot of the root composable
120+ ScreenshotUtils .captureAndSaveScreenshot(
121+ context = targetContext, // Use target context
122+ filename = " homeScreen"
123+ )
124+ }
125+
126+ @Test
127+ fun homeScreenWithRoute (){
128+ val targetContext = InstrumentationRegistry .getInstrumentation().targetContext
129+
130+ val sharedPreferences = PreferenceManager .getDefaultSharedPreferences(targetContext)
131+ // Use accessible map
132+ sharedPreferences.edit().putBoolean(ACCESSIBLE_MAP_KEY , true ).apply ()
133+
134+ val routePlayerState = RoutePlayerState (
135+ routeData = routeToShops,
136+ currentWaypoint = 0
137+ )
138+ val themeStateFlow = MutableStateFlow (ThemeState ())
139+ composeTestRule.setContent {
140+ SoundscapeTheme (themeStateFlow) {
141+ Home (
142+ state = HomeState (
143+ location = location,
144+ heading = 45.0F ,
145+ currentRouteData = routePlayerState
146+ ),
147+ onNavigate = {},
148+ preferences = sharedPreferences,
149+ onMapLongClick = { false },
150+ bottomButtonFunctions = BottomButtonFunctions (null ),
151+ getCurrentLocationDescription = {
152+ LocationDescription (
153+ name = " Milngavie" ,
154+ location = location
155+ )
156+ },
157+ searchText = " " ,
158+ onToggleSearch = { },
159+ onSearchTextChange = { },
160+ rateSoundscape = { },
161+ routeFunctions = RouteFunctions (viewModel = null ),
162+ streetPreviewFunctions = StreetPreviewFunctions (viewModel = null ),
163+ modifier = Modifier .windowInsetsPadding(WindowInsets .safeDrawing)
164+ )
165+ }
166+ }
167+
168+ // Delay to allow the maps to load
169+ Thread .sleep(5000 )
170+
171+ // Capture screenshot of the root composable
172+ ScreenshotUtils .captureAndSaveScreenshot(
173+ context = targetContext, // Use target context
174+ filename = " homeScreenWithRoute"
175+ )
176+ }
177+
178+ @Test
179+ fun routeDetailsScreen (){
180+ val targetContext = InstrumentationRegistry .getInstrumentation().targetContext
181+
182+ val sharedPreferences = PreferenceManager .getDefaultSharedPreferences(targetContext)
183+
184+ // Use accessible map
185+ sharedPreferences.edit().putBoolean(ACCESSIBLE_MAP_KEY , true ).apply ()
186+ val themeStateFlow = MutableStateFlow (ThemeState ())
187+ composeTestRule.setContent {
188+ SoundscapeTheme (themeStateFlow) {
189+ RouteDetailsScreen (
190+ navController = NavController (targetContext),
191+ routeId = 1 ,
192+ modifier = Modifier .windowInsetsPadding(WindowInsets .safeDrawing),
193+ uiState = RouteDetailsUiState (
194+ route = routeToShops
195+ ),
196+ routePlayerState = RoutePlayerState (
197+ null ,
198+ 0
199+ ),
200+ getRouteById = { },
201+ startRoute = { },
202+ stopRoute = { },
203+ shareRoute = { },
204+ clearErrorMessage = { },
205+ userLocation = location,
206+ heading = 45.0F
207+ )
208+ }
209+ }
210+
211+ // Delay to allow the maps to load
212+ Thread .sleep(5000 )
213+
214+ // Capture screenshot of the root composable
215+ ScreenshotUtils .captureAndSaveScreenshot(
216+ context = targetContext, // Use target context
217+ filename = " routeDetails"
218+ )
219+ }
220+ @Test
221+ fun editScreen (){
222+ val targetContext = InstrumentationRegistry .getInstrumentation().targetContext
223+
224+ val sharedPreferences = PreferenceManager .getDefaultSharedPreferences(targetContext)
225+ // Use accessible map
226+ sharedPreferences.edit().putBoolean(ACCESSIBLE_MAP_KEY , true ).apply ()
227+
228+ val route = routeToShops
229+ val members : MutableList <LocationDescription > = emptyList<LocationDescription >().toMutableList()
230+ for ((index, marker) in route.markers.withIndex()) {
231+ members.add(
232+ LocationDescription (
233+ name = marker.name,
234+ location = LngLatAlt (marker.longitude, marker.latitude),
235+ orderId = index.toLong(),
236+ )
237+ )
238+ }
239+
240+ val uiState = AddAndEditRouteUiState (
241+ name = " To shops" ,
242+ description = " Route to shops" ,
243+ routeMembers = members,
244+ )
245+
246+
247+ val themeStateFlow = MutableStateFlow (ThemeState ())
248+ composeTestRule.setContent {
249+ SoundscapeTheme (themeStateFlow) {
250+ AddAndEditRouteScreen (
251+ navController = NavController (targetContext),
252+ modifier = Modifier .windowInsetsPadding(WindowInsets .safeDrawing),
253+ uiState = uiState,
254+ userLocation = location,
255+ onClearErrorMessage = { },
256+ onResetDoneAction = { },
257+ onNameChange = { },
258+ onDescriptionChange = { },
259+ onDeleteRoute = { },
260+ onEditComplete = { },
261+ onClickFolder = { _, _ -> },
262+ onClickBack = { },
263+ onSelectLocation = { },
264+ createAndAddMarker = { _, _, _ -> },
265+ editRoute = true ,
266+ routeObjectId = 1 ,
267+ placesNearbyUiState = PlacesNearbyUiState ()
268+ )
269+ }
270+ }
271+
272+ // Delay to allow the maps to load
273+ Thread .sleep(5000 )
274+
275+ // Capture screenshot of the root composable
276+ ScreenshotUtils .captureAndSaveScreenshot(
277+ context = targetContext, // Use target context
278+ filename = " routeEdit"
279+ )
280+ }
281+ }
0 commit comments