tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 1b184d2bbd82756b01075b63c54fcf48a5188142
parent c46cca14e8062874f1f1c76ef9e6e479c9fbbbed
Author: AndiAJ <andiaj@users.noreply.github.com>
Date:   Mon, 29 Dec 2025 17:52:09 +0000

Bug 1981686 - Fix launchLinksInAPrivateTabTest UI test r=mcarare

Updated **openAppFromExternalLink** to launch external intents in a Compose-safe way by using composeTestRule.activity when a host activity exists, and falling back to the instrumentation context when the activity has been finished.

This ensures the Compose hierarchy is ready before UI assertions (waitForIdle()), preventing “No compose hierarchies found” errors and activity idle timeouts.

Differential Revision: https://phabricator.services.mozilla.com/D277592

Diffstat:
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt | 48+++++++++++++++++++++++++++++++++++-------------
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt | 6+++---
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt | 2+-
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt | 4++--
4 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt @@ -665,24 +665,46 @@ object AppAndSystemHelper { Log.i(TAG, "verifyKeyboardVisibility: Verified the keyboard is visible.") } - fun openAppFromExternalLink(url: String) { - val context = InstrumentationRegistry.getInstrumentation().getTargetContext() - val intent = Intent().apply { - action = Intent.ACTION_VIEW - data = url.toUri() + fun openAppFromExternalLink( + composeTestRule: AndroidComposeTestRule<HomeActivityIntentTestRule, HomeActivity>, + url: String, + ) { + val intent = Intent(Intent.ACTION_VIEW, url.toUri()).apply { `package` = TestHelper.packageName flags = Intent.FLAG_ACTIVITY_NEW_TASK } + try { - Log.i(TAG, "openAppFromExternalLink: Trying to start the activity from an external intent.") - context.startActivity(intent) - Log.i(TAG, "openAppFromExternalLink: Activity started from an external intent.") - } catch (ex: ActivityNotFoundException) { - Log.i(TAG, "openAppFromExternalLink: Exception caught. Trying to start the activity from a null intent.") - intent.setPackage(null) - context.startActivity(intent) - Log.i(TAG, "openAppFromExternalLink: Started the activity from a null intent.") + // Case 1: The app is already running and Compose has a host activity. + // Launch the external intent from the existing activity so the + // ComposeTestRule can properly track the Compose hierarchy. + Log.i(TAG, "openAppFromExternalLink: Host activity exists, launching external intent from activity.") + composeTestRule.activity.startActivity(intent) + } catch (e: IllegalStateException) { + // Case 2: The host activity was finished (cold start scenario). + // ComposeTestRule no longer has an activity, so we fall back to + // launching the intent from the instrumentation context. + Log.i(TAG, "openAppFromExternalLink: No host activity found. Launching external intent from instrumentation context.") + + val context = InstrumentationRegistry + .getInstrumentation() + .targetContext + + try { + context.startActivity(intent) + Log.i(TAG, "openAppFromExternalLink: Activity started from instrumentation context.") + } catch (ex: ActivityNotFoundException) { + // Fallback in case the explicit package cannot handle the intent. + Log.i(TAG, "openAppFromExternalLink: ActivityNotFoundException caught. Retrying with null package.") + intent.`package` = null + context.startActivity(intent) + Log.i(TAG, "openAppFromExternalLink: Activity started with null package.") + } } + + // Ensure Compose has fully settled before any UI assertions or robot actions. + composeTestRule.waitForIdle() + Log.i(TAG, "openAppFromExternalLink: Compose is idle and ready for assertions.") } /** diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt @@ -80,7 +80,7 @@ class CustomTabsTest : TestSetup() { clickPageObject(composeTestRule, itemWithText("Save")) } - openAppFromExternalLink(loginPage) + openAppFromExternalLink(composeTestRule, loginPage) browserScreen(composeTestRule) { }.openThreeDotMenu { @@ -110,7 +110,7 @@ class CustomTabsTest : TestSetup() { longClickAndCopyToolbarUrl() } - openAppFromExternalLink(customTabPage.url.toString()) + openAppFromExternalLink(composeTestRule, customTabPage.url.toString()) browserScreen(composeTestRule) { }.openSearch { @@ -272,7 +272,7 @@ class CustomTabsTest : TestSetup() { }.closeSiteSecuritySheet(composeTestRule) { } - openAppFromExternalLink(customTabPage.url.toString()) + openAppFromExternalLink(composeTestRule, customTabPage.url.toString()) browserScreen(composeTestRule) { }.openThreeDotMenu { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt @@ -204,7 +204,7 @@ class SettingsHomepageTest : TestSetup() { with(composeTestRule.activityRule) { finishActivity() mDevice.waitForIdle() - openAppFromExternalLink(genericPage.url.toString()) + openAppFromExternalLink(composeTestRule, genericPage.url.toString()) } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt @@ -70,7 +70,7 @@ class SettingsPrivateBrowsingTest : TestSetup() { verifyHomeComponent() } - AppAndSystemHelper.openAppFromExternalLink(firstWebPage.url.toString()) + AppAndSystemHelper.openAppFromExternalLink(composeTestRule, firstWebPage.url.toString()) browserScreen(composeTestRule) { verifyUrl(firstWebPage.url.toString()) @@ -89,7 +89,7 @@ class SettingsPrivateBrowsingTest : TestSetup() { } // We need to open a different link, otherwise it will open the same session - AppAndSystemHelper.openAppFromExternalLink(secondWebPage.url.toString()) + AppAndSystemHelper.openAppFromExternalLink(composeTestRule, secondWebPage.url.toString()) browserScreen(composeTestRule) { verifyUrl(secondWebPage.url.toString())