Token Migration UI Tests#2844
Conversation
…oid into token-migration
…ctivity and MigrationCallbackRegistry.
…iometricAuthPolicy and handleDuplicateUserAccount. Split out TokenMigrationView and add tests.
…oid into token-migration
…iew page objects by removing unnecessary calls. Fix tests on small and low API devices. Switch to sed to make install and set version scripts portable.
…ge into login and migration and increased timeouts for consistency.
…oid into token-migration
Generated by 🚫 Danger |
| # sed -i.bak works identically on both BSD sed (macOS) and GNU sed (Linux) | ||
| sed -i.bak "s|__CONSUMER_KEY__|${MSDK_ANDROID_REMOTE_ACCESS_CONSUMER_KEY}|g" "$bootconfig" && rm -f "$bootconfig.bak" |
There was a problem hiding this comment.
@wmathurin gsed isn't installed on MacOS by default and doesn't exist on linux. This was the best I could come up with for a command that worked on both platforms but happy to hear suggestions.
| } | ||
|
|
||
| @Serializable | ||
| data class UITestConfig(val loginHosts: List<LoginHost>, val apps: List<AppConfig>) { |
There was a problem hiding this comment.
Again, Kotlin's Json and Serialization "plugins" are magic. Json.decodeFromString returns an instance of this data class.
| * Handles the OAuth authorization "Allow" button that may appear | ||
| * after login or token migration. | ||
| */ | ||
| class AuthorizationPageObject(composeTestRule: ComposeTestRule) : BasePageObject(composeTestRule) { |
There was a problem hiding this comment.
This class gave me the most trouble since I have to use UIAutomator2 to tap the "Allow" button (given it has no resource ID). I split it into separate login and migration functions so I could use Compose/Espresso to quickly check for signs of if we need to wait for and click the allow button or not. The slow waiting + quick short circuit in a loop seems to work well but I purposefully left log lines to make debugging easier if it ever fails/flaps.
| // Migrate within same CA (scope upgrade). | ||
| @Test | ||
| fun testMigrate_CA_AddMoreScopes() { |
There was a problem hiding this comment.
Test comments, names and structure copied directly from iOS with few modifications.
| # sed -i.bak works identically on both BSD sed (macOS) and GNU sed (Linux) | ||
| sed -i.bak "s/version = \"[0-9\.]*\"/version = \"${versionName}\"/g" "${file}" && rm -f "${file}.bak" |
There was a problem hiding this comment.
@wmathurin I could revert this if you are uncomfortable with it. This script doesn't need to run on CI (at this time).
There was a problem hiding this comment.
It's fine if it works the same.
And maybe one day, we will run the release from CI !
There was a problem hiding this comment.
(Although we could just install gsed as part of the CI job).
There was a problem hiding this comment.
gsed is being used across all the setversion.sh in all the repos - so maybe we keep it unchanged (for now).
There was a problem hiding this comment.
gsed does not exist for Linux, it's just sed. AFAIK GNU make gsed because BSD sed is a completely different implementation than UNIX. sed is not truly portable but it seems like the command I changed it to has the same result on both.
There was a problem hiding this comment.
We should move to sed then. Maybe have a dedicated story and move all the setversion.sh across all the repos as part of that work?
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #2844 +/- ##
=============================================
- Coverage 64.55% 54.27% -10.28%
+ Complexity 2925 2423 -502
=============================================
Files 222 222
Lines 17323 17335 +12
Branches 2471 2473 +2
=============================================
- Hits 11182 9409 -1773
- Misses 4934 6843 +1909
+ Partials 1207 1083 -124
🚀 New features to boost your workflow:
|
| - name: Install Dependencies | ||
| env: | ||
| TEST_CREDENTIALS: ${{ secrets.TEST_CREDENTIALS }} | ||
| MSDK_ANDROID_REMOTE_ACCESS_CALLBACK_URL: ${{ secrets.MSDK_ANDROID_REMOTE_ACCESS_CALLBACK_URL }} |
There was a problem hiding this comment.
On iOS, I don't use/need those because the consumer key are always set through login options in the tests (and they come from ui_test_config.json).
There was a problem hiding this comment.
Yeah. It isn't possible (or at least reasonably worth the effort) to truly set the contents of the bootconfig file on Android so I don't have an equivalent "staticAppConfig". I wanted to have at least one test that uses the bootconfig file alone so I added it to CI.
There was a problem hiding this comment.
Oh yeah, I remember that from the earlier PRs.
It's not ideal to have both platforms diverge on that (but I guess they were already quite different in their handling of bootconfig). It would be better if we could move away from any pre-build setup step. But like you said, it's probably too much work / we don't have enough time.
| } | ||
|
|
||
| fun getTokens(): Tokens { | ||
| expandUserCredentialsSection() |
There was a problem hiding this comment.
On iOS, I ended up having export button that gives me back a JSON with all the values in the section - things were too slow when expanding and reading individual values one by one. But it looks like things are faster on Android?
There was a problem hiding this comment.
Compose UI Test skips animations, syncs/synchronizes with Compose so you never have to sleep/wait and automatically scrolls (which was honestly a huge pain with UIAutomator2). I don't think it would really speed it up much but I will take a look.
There was a problem hiding this comment.
Shockingly they are about the same:
Edit: The above didn't account for some UI navigation overhead. The more accurate numbers are still close though, with the Json method being ~100ms faster on an API 36 device:

Unless the difference is larger on API 28 I'd rather just test using the UI since that also ensures its correctness.
Second Edit: ^ It's not. Between 100-200 ms difference.
There was a problem hiding this comment.
I'm jealous, on iOS, things are really slow.
There was a problem hiding this comment.
That gave me an idea - I'm now disabling animations on iOS (see wmathurin/SalesforceMobileSDK-iOS@7677881?w=1) - it's a bit faster but not as impressive as Android.
|
|
||
| // endregion | ||
|
|
||
| private fun loginAndValidate( |
There was a problem hiding this comment.
This method will probably be useful in other login tests (not migration related) - so maybe it should move to a super class or helper class. On iOS, all the test suites derive from BaseAuthflowTester (and the test suites don't interact with the PageObject directly).
| # sed -i.bak works identically on both BSD sed (macOS) and GNU sed (Linux) | ||
| sed -i.bak "s/version = \"[0-9\.]*\"/version = \"${versionName}\"/g" "${file}" && rm -f "${file}.bak" |
There was a problem hiding this comment.
It's fine if it works the same.
And maybe one day, we will run the release from CI !
| # sed -i.bak works identically on both BSD sed (macOS) and GNU sed (Linux) | ||
| sed -i.bak "s/version = \"[0-9\.]*\"/version = \"${versionName}\"/g" "${file}" && rm -f "${file}.bak" |
There was a problem hiding this comment.
(Although we could just install gsed as part of the CI job).
| # sed -i.bak works identically on both BSD sed (macOS) and GNU sed (Linux) | ||
| sed -i.bak "s/version = \"[0-9\.]*\"/version = \"${versionName}\"/g" "${file}" && rm -f "${file}.bak" |
There was a problem hiding this comment.
gsed is being used across all the setversion.sh in all the repos - so maybe we keep it unchanged (for now).
This PR fundamentally changes the direction of our UI Test strategy for this repo:
SalesforceSDK-UITestshas been removed.Compose UI TestAPIs which are extremely fast and appear to be very stable.Espresso Webis used for most WebView interactions.UIAutomator2APIs are only used in the couple places that they are unfortunately necessary (explained in code comments).Test Orchestratoralso noticeably to helps stability with Firebase Test Lab at the cost of only ~10 seconds per test (now ~30s each).ui_test_config.json.This PR is quite large, but contains no behavior changes to production code and only adds IDs to the existing UI.
Note: The UI Tests CI will fail on this PR because the code and yaml config (that does not change on PR) are out of sync. You can see my locally triggered Firebase Runs here, the first two failures were before
Test Orchestrator.