Skip to content

Commit 1824ca8

Browse files
committed
Smoke test is working!
Still needs to be fleshed out further
1 parent f71f382 commit 1824ca8

3 files changed

Lines changed: 126 additions & 19 deletions

File tree

app/src/androidTest/kotlin/com/darkrockstudios/app/securecamera/SmokeTestUiTest.kt

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ import androidx.compose.ui.test.SemanticsMatcher
99
import androidx.compose.ui.test.assertIsDisplayed
1010
import androidx.compose.ui.test.hasContentDescription
1111
import androidx.compose.ui.test.hasSetTextAction
12+
import androidx.compose.ui.test.hasTestTag
1213
import androidx.compose.ui.test.hasText
1314
import androidx.compose.ui.test.hasTextExactly
1415
import androidx.compose.ui.test.junit4.ComposeContentTestRule
1516
import androidx.compose.ui.test.junit4.createAndroidComposeRule
17+
import androidx.compose.ui.test.onNodeWithContentDescription
1618
import androidx.compose.ui.test.onNodeWithText
1719
import androidx.compose.ui.test.performClick
1820
import androidx.compose.ui.test.performTextClearance
1921
import androidx.compose.ui.test.performTextInput
2022
import androidx.test.core.app.ApplicationProvider
2123
import androidx.test.rule.GrantPermissionRule
22-
import org.junit.Ignore
2324
import org.junit.Rule
2425
import org.junit.Test
2526
import kotlin.time.Duration
@@ -38,7 +39,6 @@ class SmokeTestUiTest {
3839
@get:Rule
3940
val composeTestRule = createAndroidComposeRule<MainActivity>()
4041

41-
@Ignore("Working on a smoke test, doesn't pass yet")
4242
@Test
4343
fun smokeTest() {
4444
composeTestRule.apply {
@@ -65,19 +65,68 @@ class SmokeTestUiTest {
6565
setPinFields("313373", "313373")
6666
onNodeWithText(str(R.string.pin_creation_button)).performClick()
6767

68-
waitForText(R.string.pin_creating_vault)
68+
waitForTextSimple(str(R.string.pin_creating_vault))
6969

70-
composeTestRule.waitUntil(
71-
timeoutMillis = 30.seconds.inWholeMilliseconds
72-
) {
73-
composeTestRule
74-
.onAllNodes(hasRole(Role.Button) and hasContentDescription(str(R.string.camera_shutter_button_desc)))
75-
.fetchSemanticsNodes().isNotEmpty()
76-
}
70+
waitForButton(str(R.string.camera_shutter_button_desc))
7771

7872
onNode(
7973
hasRole(Role.Button) and hasContentDescription(str(R.string.camera_shutter_button_desc))
80-
).assertExists()
74+
).performClick()
75+
76+
waitForContentDescriptionSimple(str(R.string.camera_more_options_content_description))
77+
78+
onNode(
79+
hasRole(Role.Button) and hasContentDescription(str(R.string.camera_more_options_content_description))
80+
).performClick()
81+
82+
waitForTestTagSimple("flash-switch")
83+
onNode(
84+
hasRole(Role.Switch) and hasTestTag("flash-switch")
85+
).performClick()
86+
87+
onNode(
88+
hasRole(Role.Button) and hasContentDescription(str(R.string.camera_close_controls_content_description))
89+
).performClick()
90+
}
91+
}
92+
93+
private fun waitForButton(contentDescription: String) {
94+
composeTestRule.waitUntil(
95+
timeoutMillis = 5.seconds.inWholeMilliseconds
96+
) {
97+
composeTestRule
98+
.onAllNodes(hasRole(Role.Button) and hasContentDescription(contentDescription))
99+
.fetchSemanticsNodes().isNotEmpty()
100+
}
101+
}
102+
103+
private fun waitForTextSimple(text: String) {
104+
composeTestRule.waitUntil(
105+
timeoutMillis = 5.seconds.inWholeMilliseconds
106+
) {
107+
composeTestRule
108+
.onAllNodes(hasText(text))
109+
.fetchSemanticsNodes().isNotEmpty()
110+
}
111+
}
112+
113+
private fun waitForContentDescriptionSimple(contentDescription: String) {
114+
composeTestRule.waitUntil(
115+
timeoutMillis = 5.seconds.inWholeMilliseconds
116+
) {
117+
composeTestRule
118+
.onAllNodes(hasContentDescription(contentDescription))
119+
.fetchSemanticsNodes().isNotEmpty()
120+
}
121+
}
122+
123+
private fun waitForTestTagSimple(testTag: String) {
124+
composeTestRule.waitUntil(
125+
timeoutMillis = 5.seconds.inWholeMilliseconds
126+
) {
127+
composeTestRule
128+
.onAllNodes(hasTestTag(testTag))
129+
.fetchSemanticsNodes().isNotEmpty()
81130
}
82131
}
83132

@@ -103,8 +152,11 @@ class SmokeTestUiTest {
103152
return application.resources
104153
}
105154

106-
private fun ComposeContentTestRule.waitForText(@StringRes text: Int, timeout: Duration = 10.seconds) {
107-
waitForText(str(text), timeout)
155+
private fun ComposeContentTestRule.waitForText(
156+
@StringRes text: Int,
157+
timeout: Duration = 10.seconds
158+
) {
159+
this@waitForText.waitForText(str(text), timeout)
108160
}
109161

110162
fun ComposeContentTestRule.waitForText(
@@ -123,6 +175,22 @@ class SmokeTestUiTest {
123175
.assertIsDisplayed()
124176
}
125177

178+
fun ComposeContentTestRule.waitForContentDescription(
179+
text: String,
180+
timeout: Duration = 10.seconds,
181+
useUnmergedTree: Boolean = true,
182+
substring: Boolean = true
183+
) {
184+
waitUntil(timeout.inWholeMilliseconds) {
185+
onAllNodes(
186+
hasText(text, substring = substring),
187+
useUnmergedTree = useUnmergedTree
188+
).fetchSemanticsNodes().isNotEmpty()
189+
}
190+
onNodeWithContentDescription(text, substring = substring)
191+
.assertIsDisplayed()
192+
}
193+
126194
private fun ComposeContentTestRule.setTextField(value: String, placeholder: Int) {
127195
onNode(
128196
hasSetTextAction() and hasTextExactly(

app/src/main/kotlin/com/darkrockstudios/app/securecamera/camera/CameraControls.kt

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,33 @@ import androidx.compose.animation.AnimatedVisibility
77
import androidx.compose.animation.core.tween
88
import androidx.compose.animation.fadeIn
99
import androidx.compose.animation.fadeOut
10-
import androidx.compose.foundation.layout.*
10+
import androidx.compose.foundation.layout.Box
11+
import androidx.compose.foundation.layout.PaddingValues
12+
import androidx.compose.foundation.layout.fillMaxSize
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.layout.size
1115
import androidx.compose.material.icons.Icons
1216
import androidx.compose.material.icons.filled.MoreVert
13-
import androidx.compose.material3.*
14-
import androidx.compose.runtime.*
17+
import androidx.compose.material3.CircularProgressIndicator
18+
import androidx.compose.material3.ElevatedButton
19+
import androidx.compose.material3.Icon
20+
import androidx.compose.material3.MaterialTheme
21+
import androidx.compose.material3.Surface
22+
import androidx.compose.runtime.Composable
23+
import androidx.compose.runtime.LaunchedEffect
24+
import androidx.compose.runtime.MutableState
25+
import androidx.compose.runtime.derivedStateOf
26+
import androidx.compose.runtime.getValue
27+
import androidx.compose.runtime.mutableStateOf
28+
import androidx.compose.runtime.remember
29+
import androidx.compose.runtime.rememberCoroutineScope
1530
import androidx.compose.runtime.saveable.rememberSaveable
31+
import androidx.compose.runtime.setValue
1632
import androidx.compose.ui.Alignment
1733
import androidx.compose.ui.Modifier
1834
import androidx.compose.ui.graphics.Color
1935
import androidx.compose.ui.platform.LocalContext
36+
import androidx.compose.ui.platform.testTag
2037
import androidx.compose.ui.res.stringResource
2138
import androidx.compose.ui.unit.dp
2239
import com.ashampoo.kim.model.GpsCoordinates
@@ -124,6 +141,7 @@ fun CameraControls(
124141
ElevatedButton(
125142
onClick = { isTopControlsVisible = true },
126143
modifier = Modifier
144+
.testTag("more-button")
127145
.align(Alignment.TopEnd)
128146
.padding(
129147
top = paddingValues.calculateTopPadding().plus(16.dp),

app/src/main/kotlin/com/darkrockstudios/app/securecamera/camera/TopCameraControlsBar.kt

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,40 @@
11
package com.darkrockstudios.app.securecamera.camera
22

3-
import androidx.compose.animation.*
3+
import androidx.compose.animation.AnimatedVisibility
44
import androidx.compose.animation.core.tween
5+
import androidx.compose.animation.fadeIn
6+
import androidx.compose.animation.fadeOut
7+
import androidx.compose.animation.slideInHorizontally
8+
import androidx.compose.animation.slideOutHorizontally
59
import androidx.compose.foundation.background
6-
import androidx.compose.foundation.layout.*
10+
import androidx.compose.foundation.layout.Arrangement
11+
import androidx.compose.foundation.layout.Column
12+
import androidx.compose.foundation.layout.PaddingValues
13+
import androidx.compose.foundation.layout.Row
14+
import androidx.compose.foundation.layout.Spacer
15+
import androidx.compose.foundation.layout.fillMaxWidth
16+
import androidx.compose.foundation.layout.padding
17+
import androidx.compose.foundation.layout.size
18+
import androidx.compose.foundation.layout.width
719
import androidx.compose.foundation.shape.CircleShape
820
import androidx.compose.foundation.shape.RoundedCornerShape
921
import androidx.compose.material.icons.Icons
1022
import androidx.compose.material.icons.filled.Cameraswitch
1123
import androidx.compose.material.icons.filled.Close
12-
import androidx.compose.material3.*
24+
import androidx.compose.material3.ButtonDefaults
25+
import androidx.compose.material3.FilledTonalButton
26+
import androidx.compose.material3.Icon
27+
import androidx.compose.material3.MaterialTheme
28+
import androidx.compose.material3.Surface
29+
import androidx.compose.material3.Switch
30+
import androidx.compose.material3.SwitchDefaults
31+
import androidx.compose.material3.Text
1332
import androidx.compose.runtime.Composable
1433
import androidx.compose.ui.Alignment
1534
import androidx.compose.ui.Modifier
1635
import androidx.compose.ui.graphics.Color
1736
import androidx.compose.ui.graphics.vector.ImageVector
37+
import androidx.compose.ui.platform.testTag
1838
import androidx.compose.ui.res.stringResource
1939
import androidx.compose.ui.unit.dp
2040
import com.darkrockstudios.app.securecamera.Flashlight
@@ -133,6 +153,7 @@ private fun CameraControlSwitch(
133153
)
134154
Spacer(modifier = Modifier.width(8.dp))
135155
Switch(
156+
modifier = Modifier.testTag("flash-switch"),
136157
checked = checked,
137158
onCheckedChange = onCheckedChange,
138159
colors = SwitchDefaults.colors(

0 commit comments

Comments
 (0)