e2e example - Add runtime SDK configuration injection for e2e tests - #2838
e2e example - Add runtime SDK configuration injection for e2e tests#2838Robert-SD wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces an ExternalConfigurationReader to parse and apply external SDK configurations (such as showCardholderName) from a Base64-encoded JSON string passed via intent extras, storing them in KeyValueStorage for use by the CheckoutConfigurationProvider. Feedback focuses on replacing java.util.Base64 with android.util.Base64 to prevent crashes on devices below API level 26, resetting the persisted configuration when empty to avoid test pollution, and using Moshi's compile-time code generation instead of reflection to improve main-thread startup performance.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
ae3a012 to
249262b
Compare
Add ExternalConfigurationReader to read Base64-encoded JSON config from intent extras (passed by Appium e2e tests via `--es config '<base64>'`). The config is parsed and written to SharedPreferences so both old and new Drop In card configurations pick up the values. Supported fields: - CARD_CONFIGURATION.showCardholderName (boolean) Wiring: - SharedPreferencesEntry: SHOW_CARDHOLDER_NAME entry - KeyValueStorage: isShowCardholderName() / setShowCardholderName() - CheckoutConfigurationProvider: setHolderNameRequired() in old card config + showCardholderName in new card config - MainActivity: applies external config in onCreate()
…ce Moshi with org.json - Replace java.util.Base64 with android.util.Base64 to support minSdk 23 - Reset showCardholderName to default when no config extra is passed (prevents test pollution) - Replace Moshi reflection with built-in org.json.JSONObject (no extra dependencies)
…s pollution Apply ExternalConfigurationReader in onNewIntent so that config resets to defaults when the activity receives a new intent without restarting, preventing test pollution from previous e2e runs.
a3237e9 to
b79770c
Compare
✅ No public API changes |
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
| import kotlin.io.encoding.Base64 | ||
| import kotlin.io.encoding.ExperimentalEncodingApi |
There was a problem hiding this comment.
I considered a few options for decoding the Base64 configuration string.
android.util.Base64— works on all Android API levels, but it is Android-framework code that cannot be called from plain JVM unit tests. Using it would force this logic into instrumented or Robolectric tests, which is heavier and slower for a simple decoder.java.util.Base64— works on the JVM, but is only available from Android API 26 / Java 8. The projectminSdkis 23 and core library desugaring is not enabled, so using it would crash on older devices.- Third-party Base64 library — possible, but adding a new dependency just to decode a Base64 string is overkill.
kotlin.io.encoding.Base64 is part of the Kotlin stdlib, works on all Android API levels, works in JVM unit tests, and requires no extra dependency. The @OptIn(ExperimentalEncodingApi::class) annotation is only an opt-in for a still-experimental API surface; the decode behavior itself is stable and fully functional.
There was a problem hiding this comment.
It's fine to use indeed. We use it internally as well
|
| fun isShowCardholderName(): Boolean | ||
| fun setShowCardholderName(showCardholderName: Boolean) |
There was a problem hiding this comment.
Nits: What do you think if we rename this to isCardHolderNameShown, setCardholderNameShown to read more naturally. isShowCardholderName reads a bit off.
| internal const val RETURN_URL_EXTRA = "RETURN_URL_EXTRA" | ||
| internal const val CONFIG_EXTRA = "config" |
There was a problem hiding this comment.
Nits: Could you keep these two values consistent, uppercase or lowercase?


Summary
ExternalConfigurationReader.ktto read a Base64-encoded JSON config from theconfigintent extra at app launchKeyValueStoragewithshowCardholderNamesupport (persisted via SharedPreferences)MainActivityto read the intent extra and apply the external config before UI creationCheckoutConfigurationProviderto apply the externalshowCardholderNamevalueThis enables the e2e test framework to inject SDK configuration (e.g.,
showCardholderName: true) at launch time viaadb shell am start --es config '<base64>', without rebuilding the app.JSON Schema
{ "CARD_CONFIGURATION": { "showCardholderName": true } }