Skip to content

Commit 17f5aa7

Browse files
committed
Add Compose UI tests covering ErrorPanel and comment section flows
1 parent d9ddc07 commit 17f5aa7

6 files changed

Lines changed: 492 additions & 59 deletions

File tree

app/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,17 @@ dependencies {
337337
/** Testing **/
338338
testImplementation libs.junit
339339
testImplementation libs.mockito.core
340+
androidTestImplementation libs.mockito.android
341+
androidTestImplementation libs.mockito.kotlin
340342

341343
androidTestImplementation libs.androidx.junit
342344
androidTestImplementation libs.androidx.runner
343345
androidTestImplementation libs.androidx.room.testing
344346
androidTestImplementation libs.assertj.core
347+
348+
androidTestImplementation platform(libs.androidx.compose.bom)
349+
androidTestImplementation libs.androidx.compose.ui.test.junit4
350+
debugImplementation libs.androidx.compose.ui.test.manifest
345351
}
346352

347353
static String getGitWorkingBranch() {

app/src/androidTest/java/org/schabi/newpipe/error/ErrorInfoCommentsTest.kt

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package org.schabi.newpipe.error
2+
3+
class ErrorInfoTest {
4+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package org.schabi.newpipe.ui.components.common
2+
3+
import androidx.activity.ComponentActivity
4+
import androidx.annotation.StringRes
5+
import androidx.compose.ui.test.assertIsDisplayed
6+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
7+
import androidx.compose.ui.test.onNodeWithText
8+
import androidx.compose.ui.test.performClick
9+
import androidx.test.ext.junit.runners.AndroidJUnit4
10+
import org.junit.Rule
11+
import org.junit.Test
12+
import org.junit.runner.RunWith
13+
import org.schabi.newpipe.R
14+
import org.schabi.newpipe.error.ErrorInfo
15+
import org.schabi.newpipe.error.UserAction
16+
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException
17+
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException
18+
import org.schabi.newpipe.ui.theme.AppTheme
19+
import java.net.UnknownHostException
20+
21+
@RunWith(AndroidJUnit4::class)
22+
class ErrorPanelTest {
23+
@get:Rule
24+
val composeRule = createAndroidComposeRule<ComponentActivity>()
25+
26+
private fun setErrorPanel(errorInfo: ErrorInfo, onRetry: (() -> Unit)? = null) {
27+
composeRule.setContent {
28+
AppTheme {
29+
ErrorPanel(errorInfo = errorInfo, onRetry = onRetry)
30+
}
31+
}
32+
}
33+
private fun text(@StringRes id: Int) = composeRule.activity.getString(id)
34+
35+
/**
36+
* Test Network Error
37+
*/
38+
@Test
39+
fun testNetworkErrorShowsRetryWithoutReportButton() {
40+
val networkErrorInfo = ErrorInfo(
41+
throwable = UnknownHostException("offline"),
42+
userAction = UserAction.REQUESTED_STREAM,
43+
request = "https://example.com/watch?v=foo"
44+
)
45+
46+
setErrorPanel(networkErrorInfo, onRetry = {})
47+
composeRule.onNodeWithText(text(R.string.network_error)).assertIsDisplayed()
48+
composeRule.onNodeWithText(text(R.string.retry), ignoreCase = true).assertIsDisplayed()
49+
composeRule.onNodeWithText(text(R.string.error_snackbar_action), ignoreCase = true)
50+
.assertDoesNotExist()
51+
composeRule.onNodeWithText(text(R.string.recaptcha_solve), ignoreCase = true)
52+
.assertDoesNotExist()
53+
}
54+
55+
/**
56+
* Test Unexpected Error, Shows Report and Retry buttons
57+
*/
58+
@Test
59+
fun unexpectedErrorShowsReportAndRetryButtons() {
60+
val unexpectedErrorInfo = ErrorInfo(
61+
throwable = RuntimeException("Unexpected error"),
62+
userAction = UserAction.REQUESTED_STREAM,
63+
request = "https://example.com/watch?v=bar"
64+
)
65+
66+
setErrorPanel(unexpectedErrorInfo, onRetry = {})
67+
composeRule.onNodeWithText(text(R.string.error_snackbar_message)).assertIsDisplayed()
68+
composeRule.onNodeWithText(text(R.string.retry), ignoreCase = true).assertIsDisplayed()
69+
composeRule.onNodeWithText(text(R.string.error_snackbar_action), ignoreCase = true)
70+
.assertIsDisplayed()
71+
}
72+
73+
/**
74+
* Test Recaptcha Error shows solve, retry and open in browser buttons
75+
*/
76+
@Test
77+
fun recaptchaErrorShowsSolveAndRetryOpenInBrowserButtons() {
78+
var retryClicked = false
79+
val recaptchaErrorInfo = ErrorInfo(
80+
throwable = ReCaptchaException(
81+
"Recaptcha required",
82+
"https://example.com/captcha"
83+
),
84+
userAction = UserAction.REQUESTED_STREAM,
85+
request = "https://example.com/watch?v=baz",
86+
openInBrowserUrl = "https://example.com/watch?v=baz"
87+
)
88+
89+
setErrorPanel(
90+
errorInfo = recaptchaErrorInfo,
91+
onRetry = { retryClicked = true }
92+
93+
)
94+
composeRule.onNodeWithText(text(R.string.recaptcha_solve), ignoreCase = true)
95+
.assertIsDisplayed()
96+
composeRule.onNodeWithText(text(R.string.retry), ignoreCase = true)
97+
.assertIsDisplayed()
98+
.performClick()
99+
composeRule.onNodeWithText(text(R.string.open_in_browser), ignoreCase = true)
100+
.assertIsDisplayed()
101+
composeRule.onNodeWithText(text(R.string.error_snackbar_action), ignoreCase = true)
102+
.assertDoesNotExist()
103+
assert(retryClicked) { "onRetry callback should have been invoked" }
104+
}
105+
106+
/**
107+
* Test Content Not Available Error hides retry button
108+
*/
109+
@Test
110+
fun testNonRetryableErrorHidesRetryAndReportButtons() {
111+
val contentNotAvailable = ErrorInfo(
112+
throwable = ContentNotAvailableException("Video has been removed"),
113+
userAction = UserAction.REQUESTED_STREAM,
114+
request = "https://example.com/watch?v=qux"
115+
)
116+
117+
setErrorPanel(contentNotAvailable)
118+
119+
composeRule.onNodeWithText(text(R.string.content_not_available))
120+
.assertIsDisplayed()
121+
composeRule.onNodeWithText(text(R.string.retry), ignoreCase = true)
122+
.assertDoesNotExist()
123+
composeRule.onNodeWithText(text(R.string.error_snackbar_action), ignoreCase = true)
124+
.assertDoesNotExist()
125+
}
126+
}

0 commit comments

Comments
 (0)