Skip to content

Commit 8ce0405

Browse files
Merge pull request #113 from kirill-markin/codex/android-marketing-screenshot-package
[codex] Move Android marketing screenshot tests
2 parents 7466eec + 5ca0452 commit 8ce0405

12 files changed

Lines changed: 187 additions & 170 deletions

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/AppStateResetRule.kt

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package com.flashcardsopensourceapp.app
22

3-
import android.app.LocaleConfig
4-
import android.app.LocaleManager
53
import android.content.Context
6-
import android.os.LocaleList
74
import androidx.core.app.NotificationManagerCompat
85
import androidx.test.core.app.ApplicationProvider
96
import androidx.test.platform.app.InstrumentationRegistry
@@ -24,107 +21,12 @@ private val testOnlyPreferenceNames: List<String> = listOf(
2421
)
2522

2623
open class AppStateResetRule : ExternalResource() {
27-
companion object {
28-
private const val localeApplyTimeoutMillis: Long = 5_000L
29-
}
30-
3124
override fun before() {
32-
applyConfiguredMarketingScreenshotLocaleOverride()
3325
resetAndroidTestAppState()
3426
}
3527

3628
override fun after() {
3729
resetAndroidTestAppState()
38-
clearConfiguredMarketingScreenshotLocaleOverride()
39-
}
40-
41-
private fun applyConfiguredMarketingScreenshotLocaleOverride() {
42-
val localeConfig = configuredMarketingScreenshotLocaleConfigOrNull() ?: return
43-
val context = ApplicationProvider.getApplicationContext<Context>()
44-
val localeManager = context.getSystemService(LocaleManager::class.java)
45-
?: throw IllegalStateException("LocaleManager was unavailable while applying screenshot locale.")
46-
val localeList = LocaleList.forLanguageTags(localeConfig.appLocaleTag)
47-
48-
InstrumentationRegistry.getInstrumentation().runOnMainSync {
49-
localeManager.overrideLocaleConfig = LocaleConfig(localeList)
50-
localeManager.applicationLocales = localeList
51-
}
52-
waitForOverrideLocaleConfigState(
53-
localeManager = localeManager,
54-
expectedLanguageTags = localeConfig.appLocaleTag,
55-
phase = "applying marketing screenshot override locale config '${localeConfig.localePrefix}'"
56-
)
57-
waitForLocaleState(
58-
localeManager = localeManager,
59-
expectedLanguageTags = localeConfig.appLocaleTag,
60-
phase = "applying marketing screenshot locale '${localeConfig.localePrefix}'"
61-
)
62-
}
63-
64-
private fun clearConfiguredMarketingScreenshotLocaleOverride() {
65-
val localeConfig = configuredMarketingScreenshotLocaleConfigOrNull() ?: return
66-
val context = ApplicationProvider.getApplicationContext<Context>()
67-
val localeManager = context.getSystemService(LocaleManager::class.java)
68-
?: throw IllegalStateException("LocaleManager was unavailable while clearing screenshot locale.")
69-
70-
InstrumentationRegistry.getInstrumentation().runOnMainSync {
71-
localeManager.applicationLocales = LocaleList.getEmptyLocaleList()
72-
localeManager.overrideLocaleConfig = null
73-
}
74-
waitForLocaleState(
75-
localeManager = localeManager,
76-
expectedLanguageTags = "",
77-
phase = "clearing marketing screenshot locale '${localeConfig.localePrefix}'"
78-
)
79-
waitForOverrideLocaleConfigState(
80-
localeManager = localeManager,
81-
expectedLanguageTags = null,
82-
phase = "clearing marketing screenshot override locale config '${localeConfig.localePrefix}'"
83-
)
84-
}
85-
86-
private fun waitForLocaleState(
87-
localeManager: LocaleManager,
88-
expectedLanguageTags: String,
89-
phase: String
90-
) {
91-
val startTimeMillis = System.currentTimeMillis()
92-
do {
93-
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
94-
if (localeManager.applicationLocales.toLanguageTags() == expectedLanguageTags) {
95-
return
96-
}
97-
} while (System.currentTimeMillis() - startTimeMillis < localeApplyTimeoutMillis)
98-
99-
throw IllegalStateException(
100-
"Timed out after $localeApplyTimeoutMillis ms while $phase. " +
101-
"expectedLanguageTags='$expectedLanguageTags' actualLanguageTags='${localeManager.applicationLocales.toLanguageTags()}'."
102-
)
103-
}
104-
105-
private fun waitForOverrideLocaleConfigState(
106-
localeManager: LocaleManager,
107-
expectedLanguageTags: String?,
108-
phase: String
109-
) {
110-
val startTimeMillis = System.currentTimeMillis()
111-
do {
112-
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
113-
val actualLanguageTags = localeManager.overrideLocaleConfig
114-
?.supportedLocales
115-
?.toLanguageTags()
116-
if (actualLanguageTags == expectedLanguageTags) {
117-
return
118-
}
119-
} while (System.currentTimeMillis() - startTimeMillis < localeApplyTimeoutMillis)
120-
121-
val actualLanguageTags = localeManager.overrideLocaleConfig
122-
?.supportedLocales
123-
?.toLanguageTags()
124-
throw IllegalStateException(
125-
"Timed out after $localeApplyTimeoutMillis ms while $phase. " +
126-
"expectedLanguageTags='$expectedLanguageTags' actualLanguageTags='$actualLanguageTags'."
127-
)
12830
}
12931
}
13032

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/MarketingScreenshotAppStateResetRule.kt

Lines changed: 0 additions & 59 deletions
This file was deleted.

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/MarketingAllScreenshotsScript.kt renamed to apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/marketing/screenshots/MarketingAllScreenshotsScript.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
package com.flashcardsopensourceapp.app
1+
package com.flashcardsopensourceapp.app.marketing.screenshots
22

33
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
import com.flashcardsopensourceapp.app.ManualOnlyAndroidTest
5+
import com.flashcardsopensourceapp.app.createRepositorySeedExecutor
46
import kotlinx.coroutines.runBlocking
57
import org.junit.Assert.assertTrue
68
import org.junit.Rule

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/MarketingRepositorySeedScenarios.kt renamed to apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/marketing/screenshots/MarketingRepositorySeedScenarios.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
package com.flashcardsopensourceapp.app
1+
package com.flashcardsopensourceapp.app.marketing.screenshots
22

3+
import com.flashcardsopensourceapp.app.RepositorySeedCard
4+
import com.flashcardsopensourceapp.app.RepositorySeedReview
5+
import com.flashcardsopensourceapp.app.RepositorySeedScenario
36
import com.flashcardsopensourceapp.data.local.model.EffortLevel
47
import com.flashcardsopensourceapp.data.local.model.ReviewRating
58
import java.time.Instant
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package com.flashcardsopensourceapp.app.marketing.screenshots
2+
3+
import android.app.LocaleConfig
4+
import android.app.LocaleManager
5+
import android.content.Context
6+
import android.os.LocaleList
7+
import androidx.test.core.app.ApplicationProvider
8+
import androidx.test.platform.app.InstrumentationRegistry
9+
import com.flashcardsopensourceapp.app.AppStateResetRule
10+
import com.flashcardsopensourceapp.app.FlashcardsApplication
11+
import kotlinx.coroutines.runBlocking
12+
import kotlinx.coroutines.withTimeout
13+
14+
private const val localeApplyTimeoutMillis: Long = 5_000L
15+
private const val marketingScreenshotGuestCleanupTimeoutMillis: Long = 20_000L
16+
17+
class MarketingScreenshotAppStateResetRule : AppStateResetRule() {
18+
override fun before() {
19+
runRemoteCleanupThenReset(
20+
resetAction = {
21+
applyConfiguredMarketingScreenshotLocaleOverride()
22+
super.before()
23+
}
24+
)
25+
}
26+
27+
override fun after() {
28+
runRemoteCleanupThenReset(
29+
resetAction = {
30+
super.after()
31+
clearConfiguredMarketingScreenshotLocaleOverride()
32+
}
33+
)
34+
}
35+
36+
private fun runRemoteCleanupThenReset(resetAction: () -> Unit) {
37+
var primaryFailure: Throwable? = null
38+
39+
try {
40+
deleteStoredGuestCloudSessionIfPresent()
41+
} catch (error: Throwable) {
42+
primaryFailure = error
43+
}
44+
45+
try {
46+
resetAction()
47+
} catch (error: Throwable) {
48+
if (primaryFailure != null) {
49+
primaryFailure.addSuppressed(error)
50+
} else {
51+
primaryFailure = error
52+
}
53+
}
54+
55+
if (primaryFailure != null) {
56+
throw primaryFailure
57+
}
58+
}
59+
60+
private fun deleteStoredGuestCloudSessionIfPresent() {
61+
val context: Context = ApplicationProvider.getApplicationContext<Context>()
62+
val application = context as FlashcardsApplication
63+
64+
runBlocking {
65+
withTimeout(marketingScreenshotGuestCleanupTimeoutMillis) {
66+
// Marketing screenshot seeding creates a real guest cloud workspace,
67+
// so the remote session must be deleted before the local reset
68+
// drops the only stored guest token.
69+
val appGraph = requireNotNull(application.appGraphOrNull) {
70+
"App graph is unavailable for marketing screenshot guest cleanup."
71+
}
72+
appGraph.deleteStoredGuestCloudSessionIfPresent()
73+
}
74+
}
75+
}
76+
77+
private fun applyConfiguredMarketingScreenshotLocaleOverride() {
78+
val localeConfig = configuredMarketingScreenshotLocaleConfigOrNull() ?: return
79+
val context = ApplicationProvider.getApplicationContext<Context>()
80+
val localeManager = context.getSystemService(LocaleManager::class.java)
81+
?: throw IllegalStateException("LocaleManager was unavailable while applying screenshot locale.")
82+
val localeList = LocaleList.forLanguageTags(localeConfig.appLocaleTag)
83+
84+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
85+
localeManager.overrideLocaleConfig = LocaleConfig(localeList)
86+
localeManager.applicationLocales = localeList
87+
}
88+
waitForOverrideLocaleConfigState(
89+
localeManager = localeManager,
90+
expectedLanguageTags = localeConfig.appLocaleTag,
91+
phase = "applying marketing screenshot override locale config '${localeConfig.localePrefix}'"
92+
)
93+
waitForLocaleState(
94+
localeManager = localeManager,
95+
expectedLanguageTags = localeConfig.appLocaleTag,
96+
phase = "applying marketing screenshot locale '${localeConfig.localePrefix}'"
97+
)
98+
}
99+
100+
private fun clearConfiguredMarketingScreenshotLocaleOverride() {
101+
val localeConfig = configuredMarketingScreenshotLocaleConfigOrNull() ?: return
102+
val context = ApplicationProvider.getApplicationContext<Context>()
103+
val localeManager = context.getSystemService(LocaleManager::class.java)
104+
?: throw IllegalStateException("LocaleManager was unavailable while clearing screenshot locale.")
105+
106+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
107+
localeManager.applicationLocales = LocaleList.getEmptyLocaleList()
108+
localeManager.overrideLocaleConfig = null
109+
}
110+
waitForLocaleState(
111+
localeManager = localeManager,
112+
expectedLanguageTags = "",
113+
phase = "clearing marketing screenshot locale '${localeConfig.localePrefix}'"
114+
)
115+
waitForOverrideLocaleConfigState(
116+
localeManager = localeManager,
117+
expectedLanguageTags = null,
118+
phase = "clearing marketing screenshot override locale config '${localeConfig.localePrefix}'"
119+
)
120+
}
121+
122+
private fun waitForLocaleState(
123+
localeManager: LocaleManager,
124+
expectedLanguageTags: String,
125+
phase: String
126+
) {
127+
val startTimeMillis = System.currentTimeMillis()
128+
do {
129+
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
130+
if (localeManager.applicationLocales.toLanguageTags() == expectedLanguageTags) {
131+
return
132+
}
133+
} while (System.currentTimeMillis() - startTimeMillis < localeApplyTimeoutMillis)
134+
135+
throw IllegalStateException(
136+
"Timed out after $localeApplyTimeoutMillis ms while $phase. " +
137+
"expectedLanguageTags='$expectedLanguageTags' actualLanguageTags='${localeManager.applicationLocales.toLanguageTags()}'."
138+
)
139+
}
140+
141+
private fun waitForOverrideLocaleConfigState(
142+
localeManager: LocaleManager,
143+
expectedLanguageTags: String?,
144+
phase: String
145+
) {
146+
val startTimeMillis = System.currentTimeMillis()
147+
do {
148+
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
149+
val actualLanguageTags = localeManager.overrideLocaleConfig
150+
?.supportedLocales
151+
?.toLanguageTags()
152+
if (actualLanguageTags == expectedLanguageTags) {
153+
return
154+
}
155+
} while (System.currentTimeMillis() - startTimeMillis < localeApplyTimeoutMillis)
156+
157+
val actualLanguageTags = localeManager.overrideLocaleConfig
158+
?.supportedLocales
159+
?.toLanguageTags()
160+
throw IllegalStateException(
161+
"Timed out after $localeApplyTimeoutMillis ms while $phase. " +
162+
"expectedLanguageTags='$expectedLanguageTags' actualLanguageTags='$actualLanguageTags'."
163+
)
164+
}
165+
}

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/MarketingScreenshotCatalog.kt renamed to apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/marketing/screenshots/MarketingScreenshotCatalog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.flashcardsopensourceapp.app
1+
package com.flashcardsopensourceapp.app.marketing.screenshots
22

33
import androidx.test.platform.app.InstrumentationRegistry
44

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/MarketingScreenshotGuestCleanupScript.kt renamed to apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/marketing/screenshots/MarketingScreenshotGuestCleanupScript.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
package com.flashcardsopensourceapp.app
1+
package com.flashcardsopensourceapp.app.marketing.screenshots
22

33
import android.content.Context
44
import androidx.test.core.app.ApplicationProvider
55
import androidx.test.ext.junit.runners.AndroidJUnit4
6+
import com.flashcardsopensourceapp.app.FlashcardsApplication
7+
import com.flashcardsopensourceapp.app.ManualOnlyAndroidTest
8+
import com.flashcardsopensourceapp.app.resetAndroidTestAppState
69
import kotlinx.coroutines.runBlocking
710
import kotlinx.coroutines.withTimeout
811
import org.junit.Test

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/MarketingScreenshotTestSupport.kt renamed to apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/marketing/screenshots/MarketingScreenshotTestSupport.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.flashcardsopensourceapp.app
1+
package com.flashcardsopensourceapp.app.marketing.screenshots
22

33
import android.app.LocaleManager
44
import android.os.LocaleList
@@ -26,6 +26,7 @@ import androidx.compose.ui.semantics.getOrNull
2626
import androidx.test.core.app.ActivityScenario
2727
import androidx.test.platform.app.InstrumentationRegistry
2828
import androidx.test.uiautomator.UiDevice
29+
import com.flashcardsopensourceapp.app.MainActivity
2930
import com.flashcardsopensourceapp.app.livesmoke.dismissBlockingSystemDialogIfPresent
3031
import com.flashcardsopensourceapp.app.navigation.AiDestination
3132
import com.flashcardsopensourceapp.app.navigation.CardsDestination

0 commit comments

Comments
 (0)