test(android): grant media permissions before UI E2E and dismiss all-files prompt

E2EFlowTest failed because the system media-permission dialog stole focus and
left no compose hierarchy (orchestrator clears package data between tests).
Grant media access in an outer rule before the activity launches, and dismiss the
all-files access prompt so it does not block taps.
This commit is contained in:
iu
2026-10-13 22:13:39 +03:00
parent fa210e6c7f
commit cbff7a340c
@@ -3,6 +3,7 @@ package com.galo.android
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.net.Uri import android.net.Uri
import android.os.Build
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onAllNodesWithTag import androidx.compose.ui.test.onAllNodesWithTag
@@ -13,10 +14,13 @@ import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextInput import androidx.compose.ui.test.performTextInput
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.galo.android.data.network.GaloJson import com.galo.android.data.network.GaloJson
import com.galo.android.data.network.dto.AlbumEnvelopeDto import com.galo.android.data.network.dto.AlbumEnvelopeDto
import com.galo.android.domain.media.MediaPermissions
import com.galo.android.domain.model.UploadStatus import com.galo.android.domain.model.UploadStatus
import com.galo.android.ui.MainActivity import com.galo.android.ui.MainActivity
import com.galo.android.ui.TAG_ALL_FILES_PROMPT_DIALOG
import com.galo.android.ui.album.TAG_ALBUM_GRID import com.galo.android.ui.album.TAG_ALBUM_GRID
import com.galo.android.ui.album.TAG_PHOTO_PREFIX import com.galo.android.ui.album.TAG_PHOTO_PREFIX
import com.galo.android.ui.albums.TAG_ALBUM_CARD_PREFIX import com.galo.android.ui.albums.TAG_ALBUM_CARD_PREFIX
@@ -38,7 +42,11 @@ import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.model.Statement
import java.io.File import java.io.File
/** /**
@@ -51,8 +59,26 @@ import java.io.File
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class E2EFlowTest { class E2EFlowTest {
private val mediaPermissionRule: TestRule = object : TestRule {
override fun apply(base: Statement, description: Description): Statement = object : Statement() {
override fun evaluate() {
// Grant media access before the activity launches, otherwise the
// system permission dialog steals focus and no compose hierarchy
// is found (orchestrator clears package data between tests).
val instrumentation = InstrumentationRegistry.getInstrumentation()
val pkg = instrumentation.targetContext.packageName
MediaPermissions.required(Build.VERSION.SDK_INT).forEach { permission ->
runCatching { instrumentation.uiAutomation.grantRuntimePermission(pkg, permission) }
}
base.evaluate()
}
}
}
private val compose = createAndroidComposeRule<MainActivity>()
@get:Rule @get:Rule
val compose = createAndroidComposeRule<MainActivity>() val rules: TestRule = RuleChain.outerRule(mediaPermissionRule).around(compose)
private val baseUrl = "http://10.0.2.2:8088" private val baseUrl = "http://10.0.2.2:8088"
private val client = OkHttpClient() private val client = OkHttpClient()
@@ -88,6 +114,11 @@ class E2EFlowTest {
compose.onAllNodesWithText("Пока нет альбомов").fetchSemanticsNodes().isNotEmpty() compose.onAllNodesWithText("Пока нет альбомов").fetchSemanticsNodes().isNotEmpty()
} }
// Dismiss the "all files" access prompt if shown, so it does not block taps.
if (compose.onAllNodesWithTag(TAG_ALL_FILES_PROMPT_DIALOG).fetchSemanticsNodes().isNotEmpty()) {
compose.onNodeWithText("Позже").performClick()
}
// Seed an album (the client has no album-creation UI in v1). // Seed an album (the client has no album-creation UI in v1).
val token = app().container.tokenStore.accessToken() val token = app().container.tokenStore.accessToken()
?: error("expected a stored access token after registration") ?: error("expected a stored access token after registration")