tor-browser

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

commit e7316136b5c279c1a13ea28cdd206b68a193e2f1
parent 310a64d8d88232c185f2ba07b89450fbbd230769
Author: Jackie Johnson <107960801+jjSDET@users.noreply.github.com>
Date:   Wed, 12 Nov 2025 18:51:07 +0000

Bug 1998492 - Add Test Factory Base and Private Browsing Test Factory r=isabel_rios,aaronmt

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

Diffstat:
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/ArchitectureOverview.md | 47+++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/DebugUtilities.md | 22++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/Factories.md | 21+++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/FeatureLayer.md | 20++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/FeatureSpecDataModel.md | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/LoggingLayer.md | 23+++++++++++++++++++++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/README.md | 150++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/StepsLayer.md | 13+++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/TestFactoryDesignGoals.md | 43+++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/examples/FactoryDryRunTestExample.kt | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/examples/PrivateBrowsingFactoryTestExample.kt | 48++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/debug/DebugControls.kt | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/debug/ShellExporter.kt | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/BehaviorFactory.kt | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/InteractionFactory.kt | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/PresenceFactory.kt | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/Checks.kt | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/FeatureKey.kt | 19+++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/FeatureSpec.kt | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/ArtifactManager.kt | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/JsonSink.kt | 46++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/LoggerFactory.kt | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/ScreenshotTaker.kt | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/StepLogger.kt | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/SummarySink.kt | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/ActionSteps.kt | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/NavigateSteps.kt | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/NoOpsSteps.kt | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/StepContext.kt | 27+++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/StepResult.kt | 26++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/TestStep.kt | 32++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/VerifySteps.kt | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/features/privatebrowsing/PrivateBrowsingSpec.kt | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/SwipeDirection.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/BookmarksPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/CollectionsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/CustomTabsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/DownloadsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/FindInPagePage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HistoryPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HomePage.kt | 19+++++++++++++++++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuComposePage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MicrosurveysPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/NotificationPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/PWAPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ReaderViewPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/RecentlyClosedTabsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAboutPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAccessibilityPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAddonsManagerPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAutofillPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsCustomizePage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDataCollectionPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDeleteBrowsingDataOnQuitPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDeleteBrowsingDataPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsEnhancedTrackingProtectionExceptionsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsEnhancedTrackingProtectionPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsExperimentsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsHTTPSOnlyModePage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsHomepagePage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsLanguagePage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsOpenLinksInAppsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPasswordsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPrivateBrowsingPage.kt | 19+++++++++++++++++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSavePasswordsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSavedPasswordsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSearchPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsExceptionsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsPermissionsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTabsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTranslationsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTurnOnSyncPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ShareOverlayPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ShortcutsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SitePermissionsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SiteSecurityPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SystemSettingsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/TabDrawerPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/TranslationsPage.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/BookmarksSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/CollectionsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/CustomTabsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/DownloadsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/FindInPageSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HistorySelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HomeSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuComposeSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MicrosurveysSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/NotificationSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/PWASelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ReaderViewSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/RecentlyClosedTabsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAboutSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAccessibilitySelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAddonsManagerSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAutofillSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsCustomizeSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDataCollectionSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDeleteBrowsingDataOnQuitSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDeleteBrowsingDataSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsEnhancedTrackingProtectionExceptionsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsEnhancedTrackingProtectionSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsExperimentsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsHTTPSOnlyModeSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsHomepageSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsLanguageSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsOpenLinksInAppsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsPasswordsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsPrivateBrowsingSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSavePasswordsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSavedPasswordsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSearchSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsExceptionsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsPermissionsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTabsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTranslationSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTurnOnSyncSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ShareOverlaySelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ShortcutsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SitePermissionsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SiteSecuritySelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SystemSettingsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/TabDrawerSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/TranslationsSelectors.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/BookmarksTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/HistoryTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/HomeTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuComposeTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/RecentlyClosedTabsTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAboutTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAccessibilityTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAutofillTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsCustomizeTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDataCollectionTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDeleteBrowsingDataOnQuitTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDeleteBrowsingDataTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsEnhancedTrackingProtectionExceptionsTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsEnhancedTrackingProtectionTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsHTTPSOnlyModeTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsHomepageTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsLanguageTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsOpenLinksInAppsTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsPasswordsTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsPrivateBrowsingTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsSearchTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsSiteSettingsTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTabsTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTest.kt | 4++++
Mmobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTurnOnSyncTest.kt | 4++++
156 files changed, 2605 insertions(+), 63 deletions(-)

diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/ArchitectureOverview.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/ArchitectureOverview.md @@ -0,0 +1,47 @@ +# Architecture Overview + +This document provides a high-level map of modules and how they interact. + +## Diagram — Architecture Overview + +```mermaid +flowchart LR + A["Selectors(UI element metadata)"] --> B["Page Objects(BasePage, PageContext)"] + B --> C["Steps(Navigate, Toggle, Verify...)"] + C --> D["Feature Specs(Presence, Interaction, Behavior)"] + D --> E["Factories(Presence, Interaction, Behavior)"] + E --> F["Logging LayerSummarySink, JsonSink, ScreenshotTaker"] + E --> G["Debug UtilitiesDebugControls, ShellExporter"] + F --> H["CI / Firebase Test Lab"] + G --> H +``` + +## Diagram — Factory Execution Flow + +```mermaid +flowchart TB + start(("Test Start")) --> pre["Run Preconditions"] + pre --> p["PresenceFactory.run()"] + p --> i["InteractionFactory.run()"] + i --> b["BehaviorFactory.run()"] + b --> logger[("StepLogger\nSummary + JSONL")] & shots[["ScreenshotTaker"]] & dbg["DebugControls.onSuiteEnd()"] + logger --> finish(("Test End / Artifacts Exported")) + shots --> finish + dbg --> finish +``` + +## Diagram — FeatureSpec Composition + +```mermaid +flowchart LR + FS[FeatureSpec] --> PRE["Preconditions List"<TestStep>] + FS --> SUR["Surfaces List"<SurfaceCheck>] + FS --> INT["Interactions List"<InteractionCheck>] + FS --> BEH["Behavior List"<BehaviorCheck>] + FS --> CLN["Cleanup List"<TestStep>] + PRE --> STEP[TestStep] + SUR --> STEP + INT --> STEP + BEH --> STEP + CLN --> STEP +``` diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/DebugUtilities.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/DebugUtilities.md @@ -0,0 +1,22 @@ +# Debug Utilities + +The debug layer provides **developer‑friendly** tools for exporting artifacts and pausing after runs—without Gradle/manifest changes. + +## Modules + +- `DebugControls` — reads instrumentation flags and performs suite‑end actions +- `ShellExporter` — mirrors `artifacts/<run-id>` to a public path (e.g., `/sdcard/TestFactoryArtifacts/<run-id>`) + +## Flags + +``` +-e factoryExportPublic true +-e factoryPauseAfterRunSec 20 +``` + +## Typical Flow + +1. Factories run a tier and write artifacts under the app’s private external storage. +2. `DebugControls.onSuiteEnd(...)` runs: + - **export** artifacts publicly (optional) + - **pause** N seconds for manual inspection (optional) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/Factories.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/Factories.md @@ -0,0 +1,21 @@ +# Factories Guide + +Factories execute `FeatureSpec` tiers with consistent logging and screenshots. + +## Tiers + +- **PresenceFactory** — navigate + verify +- **InteractionFactory** — navigate + action + verify +- **BehaviorFactory** — setup + trigger + cross‑page verify + +## Failure Semantics + +- **Fail fast** on the first failed step within a tier +- Capture a screenshot on failure +- Always call `testEnd(PASS|FAIL)` and suite‑end debug hooks + +## Logging + +- Human: `summary.log` +- Machine: `details.jsonl` (one JSON per line) +- Screenshots: under per‑test/per‑step dirs diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/FeatureLayer.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/FeatureLayer.md @@ -0,0 +1,20 @@ +# Feature Layer + +The feature layer defines the **what** of a feature’s tests. + +## Key Types + +```kotlin +enum class FeatureKey { PRIVATE_BROWSING /* ... */ } + +data class FeatureSpec( + val key: FeatureKey, + val preconditions: List<TestStep> = emptyList(), + val surfaces: List<SurfaceCheck> = emptyList(), + val interactions: List<InteractionCheck> = emptyList(), + val sanity: List<BehaviorCheck> = emptyList(), + val cleanup: List<TestStep> = emptyList(), +) +``` + +Use the DSL or data to build `FeatureSpec`; factories do the rest. diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/FeatureSpecDataModel.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/FeatureSpecDataModel.md @@ -0,0 +1,79 @@ +# FeatureSpec Data Model + +This document explains the `FeatureSpec` concept and how **feature specs** (eventually authored as data) will drive the factories to generate dynamic test suites per piece of functionality. + +## Why Feature Specs? + +- Make **intent explicit**: what surfaces, interactions, and behaviors matter +- Allow **tests as data**: factories assemble suites mechanically +- Enable **ad‑hoc, on‑demand suites** in CI by passing arguments to choose features/tier + +## Kotlin Type Model (today) + +```kotlin +data class FeatureSpec( + val key: FeatureKey, + val preconditions: List<TestStep> = emptyList(), + val surfaces: List<SurfaceCheck> = emptyList(), + val interactions: List<InteractionCheck> = emptyList(), + val sanity: List<BehaviorCheck> = emptyList(), + val cleanup: List<TestStep> = emptyList(), +) +``` + +```kotlin +data class SurfaceCheck(val navigateStep: TestStep, val verifyStep: TestStep) +data class InteractionCheck(val navigateStep: TestStep, val actionStep: TestStep, val verifyStep: TestStep) +data class BehaviorCheck(val setupSteps: List<TestStep>, val triggerSteps: List<TestStep>, val crossPageVerifySteps: List<TestStep>) +``` + +## Future: Spec as Data (JSON/YAML) + +```yaml +feature: PRIVATE_BROWSING +preconditions: + - navigate: home +surfaces: + - navigate: home + verify: { page: home, group: privateHomeHeader } + - navigate: history + verify: { page: history, group: emptyHistoryList } +interactions: + - navigate: home + actions: [toggle: { privateBrowsing: true }] + verify: { page: home, group: privateHomeHeader } +behavior: + - setup: [toggle: { privateBrowsing: true }] + trigger: [visit: "https://example.com"] + verify: + - navigate: history + - verify: { page: history, group: emptyHistoryList } +cleanup: + - toggle: { privateBrowsing: false } +``` + +The factory runtime maps these to concrete `TestStep`s (navigate/toggle/verify). + +## Relationship Diagram + +```mermaid +flowchart LR + FS[FeatureSpec] --> PRE[Preconditions] + FS --> SUR[Surfaces] + FS --> INT[Interactions] + FS --> BEH[Behavior] + FS --> CLN[Cleanup] + PRE --> STEP[TestStep] + SUR --> STEP + INT --> STEP + BEH --> STEP + CLN --> STEP +``` + +## CI Usage + +- Choose features & tiers via arguments (e.g., `--features=PRIVATE_BROWSING --tiers=PRESENCE,INTERACTION`) +- Factories generate suites on demand using the provided `FeatureSpec` data +- Teams manage **test data** (selectors + groups) as the “requirements” that drive base coverage + +**Goal:** everything that can be procedurally generated is covered by factories; only **user‑journey tests** remain bespoke. diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/LoggingLayer.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/LoggingLayer.md @@ -0,0 +1,23 @@ +# Logging Layer + +Provides both **human‑friendly** and **machine‑readable** outputs. + +## Components + +- `SummarySink` — concise, timestamped lines; also emits to Logcat +- `JsonSink` — newline‑delimited JSON (JSONL) +- `CombinedLogger` — fans out to both sinks +- `ArtifactManager` — centralized artifacts root +- `ScreenshotTaker` — captures full‑device PNGs + +## Example JSONL event + +```json +{ + "type": "stepEnd", + "stepId": "presence-0", + "name": "Presence.SurfaceCheck", + "result": "PASS", + "ts": 1731000000000 +} +``` diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/README.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/README.md @@ -1,95 +1,119 @@ -# Android Test Automation Framework (POM-Based) +# Android Test Automation Framework (POM + Factories) -## 🚀 Introduction +## Introduction -This framework introduces a modern, scalable approach to Android UI testing using the Page Object Model (POM). It combines Espresso, UIAutomator2, and Jetpack Compose testing under a single unified abstraction, making test code clean, reusable, and easy to maintain. +This framework brings a modern, scalable approach to Android UI testing using the **Page Object Model (POM)** and a new **Test Factory** layer. It unifies Espresso, UIAutomator2, and Jetpack Compose testing under one abstraction so tests read like user journeys and can be **composed** from reusable steps. -Tests written with this system read like user journeys, not code. Teams can define pages once and reuse them throughout tests—encouraging ownership, modularity, and clarity across features. +Factories sit on top of POM and execute **Presence**, **Interaction**, and **Behavior** suites from a declarative **FeatureSpec**. This makes it easy to scale coverage with minimal boilerplate while keeping logs and artifacts developer-friendly. -## 🛠️ Getting Started +> The concrete `features/*` specs and factory test classes included here are **demo & educational scaffolding**. They illustrate what the system will produce “over‑the‑wire.” As the team adopts data‑driven specs and the DSL, these demos will be replaced or removed. -### Prerequisites - -- Android Studio Arctic Fox or newer -- Kotlin 1.9+ -- Compose UI Test library -- Enabled Test Orchestrator (optional for retries) - -### Writing Your First Test +--- -```kotlin -@Test -fun verifyHomeLoads() { - on.homePage.navigateToPage() - .mozVerifyElementsByGroup("requiredForPage") -} +## Architecture Layers + +| Layer | Responsibility | Example | +| --------------- | ---------------------------------- | ---------------------------------------------------- | +| Selectors | Describe how to find UI elements | `Selector(byText = "Settings")` | +| Pages | Group selectors and expose actions | `SettingsPage.navigateToPage()` | +| Steps | Reusable actions/assertions | `Navigate.To.Home()`, `Toggle.PrivateBrowsing(true)` | +| Feature Specs | Compose steps into suites | `FeatureSpec(surfaces, interactions, behavior)` | +| Factories | Execute suites + logging/artifacts | `PresenceFactory.run(spec, ctx)` | +| Debug Utilities | Export artifacts & pause | `DebugControls.onSuiteEnd()` | +| Logging | Human + machine logs, screenshots | `SummarySink`, `JsonSink`, `ScreenshotTaker` | + +### Diagram — Architecture Overview + +```mermaid +flowchart LR + A["Selectors<br/>(UI element metadata)"] --> B["Page Objects<br/>(BasePage, PageContext)"] + B --> C["Steps<br/>(Navigate, Toggle, Verify...)"] + C --> D["Feature Specs<br/>(Presence, Interaction, Behavior)"] + D --> E["Factories<br/>(Presence, Interaction, Behavior)"] + E --> F["Logging Layer<br/>SummarySink, JsonSink, ScreenshotTaker"] + E --> G["Debug Utilities<br/>DebugControls, ShellExporter"] + F --> H["CI / Firebase Test Lab"] + G --> H ``` -### Structure Overview +--- -- `BasePage.kt`: Common actions (clicks, verification, navigation) -- `Selector.kt`: Describes UI elements in a flexible, tool-agnostic way -- `PageContext.kt`: Entry point for test pages via `on.<Page>` -- `NavigationRegistry.kt`: Stores how to move between pages +## Dynamic Test Factories (Phase 1.5 Prototype) -## 🧪 Test Development Workflow +Factories consume a declarative `FeatureSpec` and run three tiers: -1. **Define Selectors** +- **Presence** – do expected elements render? +- **Interaction** – are controls responsive? +- **Behavior** – do minimal logical outcomes hold across pages? ```kotlin -val TITLE = Selector( - strategy = SelectorStrategy.ESPRESSO_BY_TEXT, - value = "Welcome", - description = "Welcome title on Home Page", - groups = listOf("requiredForPage") +val PrivateBrowsingSpec = FeatureSpec( + key = FeatureKey.PRIVATE_BROWSING, + surfaces = list_of( + SurfaceCheck( + navigateStep = Navigate.To.Home(), + verifyStep = mozVerifyElementsByGroup("privateHomeHeader") { it.home } + ) + ) ) ``` -2. **Create a Page Object** - -```kotlin -object HomePage : BasePage() { - override val pageName = "HomePage" - - override fun mozGetSelectorsByGroup(group: String) = HomePageSelectors.all.filter { - it.groups.contains(group) - } -} +**Execution flow:** + +```mermaid +flowchart TB + start((Test Start)) --> pre[Run Preconditions] + pre --> p["PresenceFactory.run()"] + p --> i["InteractionFactory.run()"] + i --> b["BehaviorFactory.run()"] + b --> logger[(StepLogger\nSummary + JSONL)] + b --> shots[[ScreenshotTaker]] + b --> dbg["DebugControls.onSuiteEnd()"] + logger --> finish((Test End / Artifacts Exported)) + shots --> finish + dbg --> finish ``` -3. **Add to Context** - -```kotlin -val homePage = HomePage -``` +--- -4. **Write a Test** +## First Test ```kotlin -on.homePage.navigateToPage() +@Test +fun verifyHomeLoads() { + on.homePage.navigateToPage() .mozVerifyElementsByGroup("requiredForPage") +} ``` -## 📚 Additional Resources - -- 📖 [Test Automation Strategy](./docs/TestAutomationStrategy.md): Roadmap for phases and long-term goals -- 💡 Example tests: See `ui/efficiency/tests/` -- 📎 Diagrams: (Coming soon) +--- -## 👥 Contributing +## Developer Workflow -When adding new pages or selectors: +1. **Define selectors** → small, reusable UI descriptors +2. **Create a page** → group selectors & expose actions +3. **Register navigation** → declare how to reach pages +4. **Compose specs or write tests** → use `FeatureSpec` or the DSL -- Follow the fluent interface pattern -- Group selectors meaningfully (e.g., `"requiredForPage"`, `"toolbar"`) -- Register navigation paths explicitly in each `Page`'s `init` block +--- -## ✅ Best Practices +## Documents -- Use clear, readable selector descriptions -- Avoid direct interaction with Espresso/UIAutomator in tests -- Build tests in Given/When/Then structure +- [Test Automation Strategy](./TestAutomationStrategy.md) +- [Test Factory Design Goals](./TestFactoryDesignGoals.md) +- [FeatureSpec Data Model](./FeatureSpecDataModel.md) +- [Architecture Overview](./ArchitectureOverview.md) +- [Debug Utilities](./DebugUtilities.md) +- [Factories Guide](./Factories.md) +- [Feature Layer](./FeatureLayer.md) +- [Logging Layer](./LoggingLayer.md) +- [Steps Layer](./StepsLayer.md) --- -This framework enables powerful, flexible testing—but starts simple. With it, we empower teams to own their features _and_ their tests. +## Best Practices + +- Prefer descriptive selector names & groups +- Keep page objects small and focused +- Use Given / When / Then phrasing +- Don’t call Espresso/UIAutomator directly in tests—wrap in steps/pages diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/StepsLayer.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/StepsLayer.md @@ -0,0 +1,13 @@ +# Steps Layer + +Reusable actions & assertions that never throw—return `StepResult` instead. + +## Common Steps + +- `Navigate.To.Home()`, `Navigate.To.Settings()`, `Navigate.To.History()`, `Navigate.To.Url(url)` +- `Toggle.PrivateBrowsing(true|false)` +- `Verify.ElementsByGroup("groupId")` + +## Utilities + +- `NoOpStep`, `SleepStep`, `FailStep` for dry runs and demos diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/TestFactoryDesignGoals.md b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/docs/TestFactoryDesignGoals.md @@ -0,0 +1,43 @@ +# Test Factory Design Goals + +> _“Write intent once; let the system handle the mechanics.”_ + +## Purpose + +The **Test Factory** prototype demonstrates how test cases can be built dynamically from declarative feature specifications, not imperative scripts. It is a **teaching & transition tool** that makes the composition mechanics visible before we automate them. + +## Goals + +1. **Demonstrate abstraction** — tests = navigation + action + verification +2. **Enable composability** — small steps → reusable specs → generated suites +3. **Provide transparency** — Summary + JSONL logs, screenshots on failure +4. **Reduce onboarding friction** — DSL/specs instead of raw code +5. **Prepare data‑driven future** — same factories will execute runtime specs + +## Factory Tiers + +| Factory | Purpose | Example | +| ----------- | ------------------------- | ----------------------- | +| Presence | Ensure UI surfaces render | “Do elements appear?” | +| Interaction | Validate responsiveness | “Can I toggle/tap?” | +| Behavior | Confirm logical outcomes | “After X, does Y hold?” | + +## Execution Flow + +```mermaid +flowchart TB + start((Start)) --> pre[Preconditions] + pre --> pres[PresenceFactory] + pres --> inter[InteractionFactory] + inter --> beh[BehaviorFactory] + beh --> log[(Logging)] + beh --> shot[[Screenshots]] + beh --> dbg[DebugControls] + log --> finish((End)) + shot --> finish + dbg --> finish +``` + +## Educational Scaffolding + +The `features/*` specs and `*FactoryTest` classes are **demo/educational** modules. They show what real, data-driven suites will look like “over‑the‑wire.” Once teams are comfortable, they will be replaced or removed. diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/examples/FactoryDryRunTestExample.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/examples/FactoryDryRunTestExample.kt @@ -0,0 +1,104 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.examples + +import org.junit.Test +import org.mozilla.fenix.ui.efficiency.factory.factories.BehaviorFactory +import org.mozilla.fenix.ui.efficiency.factory.factories.InteractionFactory +import org.mozilla.fenix.ui.efficiency.factory.factories.PresenceFactory +import org.mozilla.fenix.ui.efficiency.factory.feature.BehaviorCheck +import org.mozilla.fenix.ui.efficiency.factory.feature.FeatureKey +import org.mozilla.fenix.ui.efficiency.factory.feature.FeatureSpec +import org.mozilla.fenix.ui.efficiency.factory.feature.InteractionCheck +import org.mozilla.fenix.ui.efficiency.factory.feature.SurfaceCheck +import org.mozilla.fenix.ui.efficiency.factory.logging.LoggerFactory +import org.mozilla.fenix.ui.efficiency.factory.steps.FailStep +import org.mozilla.fenix.ui.efficiency.factory.steps.NoOpStep +import org.mozilla.fenix.ui.efficiency.factory.steps.SleepStep +import org.mozilla.fenix.ui.efficiency.factory.steps.StepContext +import org.mozilla.fenix.ui.efficiency.helpers.BaseTest + +/** + * Demonstration test class that runs the factory tiers using **synthetic steps only**. + * + * This serves as an *educational* example of what the generated tests will + * look and behave like over the wire, without touching any real UI. + * + * - Uses [NoOpStep], [SleepStep], and [FailStep] to simulate flow. + * - Allows developers to inspect logging format, test order, and artifact output. + * - Safe to run on any emulator; no dependencies on app state. + * + * **Important:** This test is for demonstration and learning purposes only. + * It will be removed or heavily refactored once the team is comfortable + * authoring and running factory-based specs for real features. + */ +class FactoryDryRunTestExample : BaseTest() { + + /** Builds a synthetic [FeatureSpec] purely for logging/demo purposes. */ + private fun drySpec(): FeatureSpec = FeatureSpec( + key = FeatureKey.PRIVATE_BROWSING, // any key, we just want logging shape + preconditions = listOf( + NoOpStep("precondition-start"), + SleepStep(150, "precondition-wait"), + ), + surfaces = listOf( + SurfaceCheck( + navigateStep = NoOpStep("navigate-surface-1"), + verifyStep = NoOpStep("verify-surface-1"), + ), + SurfaceCheck( + navigateStep = SleepStep(100, "navigate-surface-2"), + verifyStep = NoOpStep("verify-surface-2"), + ), + ), + interactions = listOf( + InteractionCheck( + navigateStep = NoOpStep("navigate-interaction-1"), + actionStep = NoOpStep("action-interaction-1"), + verifyStep = NoOpStep("verify-interaction-1"), + ), + ), + sanity = listOf( + BehaviorCheck( + setupSteps = listOf(NoOpStep("setup-1"), SleepStep(120, "setup-wait")), + triggerSteps = listOf(NoOpStep("trigger-1")), + crossPageVerifySteps = listOf(NoOpStep("verify-1")), + ), + // include a failing behavior to see FAIL logging + BehaviorCheck( + setupSteps = listOf(NoOpStep("setup-2")), + triggerSteps = listOf(FailStep("synthetic failure in trigger")), + crossPageVerifySteps = listOf(NoOpStep("verify-never-reached")), + ), + ), + cleanup = listOf( + NoOpStep("cleanup-1"), + ), + ) + + /** Executes Presence tier demo with synthetic steps. */ + @Test + fun dryrun_presence_logs() { + val logger = LoggerFactory.create() + val ctx = StepContext(composeRule, on, logger) + PresenceFactory.run(drySpec(), ctx) + } + + /** Executes Interaction tier demo with synthetic steps. */ + @Test + fun dryrun_interaction_logs() { + val logger = LoggerFactory.create() + val ctx = StepContext(composeRule, on, logger) + InteractionFactory.run(drySpec(), ctx) + } + + /** Executes Behavior tier demo with synthetic steps. */ + @Test + fun dryrun_behavior_logs() { + val logger = LoggerFactory.create() + val ctx = StepContext(composeRule, on, logger) + BehaviorFactory.run(drySpec(), ctx) + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/examples/PrivateBrowsingFactoryTestExample.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/examples/PrivateBrowsingFactoryTestExample.kt @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.examples + +import org.junit.Test +import org.mozilla.fenix.ui.efficiency.factory.factories.BehaviorFactory +import org.mozilla.fenix.ui.efficiency.factory.factories.InteractionFactory +import org.mozilla.fenix.ui.efficiency.factory.factories.PresenceFactory +import org.mozilla.fenix.ui.efficiency.factory.logging.LoggerFactory +import org.mozilla.fenix.ui.efficiency.factory.steps.StepContext +import org.mozilla.fenix.ui.efficiency.features.privatebrowsing.PrivateBrowsingSpec +import org.mozilla.fenix.ui.efficiency.helpers.BaseTest + +/** + * Demonstration test class that runs the real [PrivateBrowsingSpec] through + * all three factory tiers: Presence, Interaction, and Behavior. + * + * This is primarily a **reference and educational example** to illustrate how + * a concrete [FeatureSpec] is executed by the factories. + * + * - Executes the same feature data across different logical tiers. + * - Useful for verifying that logging, artifact creation, and screenshot + * capture work end-to-end. + * - Does not represent final production tests; will evolve or be removed + * once the team adopts DSL-driven or data-driven feature specs. + */ +class PrivateBrowsingFactoryTestExample : BaseTest() { + + @Test fun presence() { + val logger = LoggerFactory.create() + val ctx = StepContext(composeRule, on, logger) + PresenceFactory.run(PrivateBrowsingSpec, ctx) + } + + @Test fun interaction() { + val logger = LoggerFactory.create() + val ctx = StepContext(composeRule, on, logger) + InteractionFactory.run(PrivateBrowsingSpec, ctx) + } + + @Test fun behavior() { + val logger = LoggerFactory.create() + val ctx = StepContext(composeRule, on, logger) + BehaviorFactory.run(PrivateBrowsingSpec, ctx) + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/debug/DebugControls.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/debug/DebugControls.kt @@ -0,0 +1,100 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.debug + +import androidx.test.platform.app.InstrumentationRegistry +import org.mozilla.fenix.ui.efficiency.factory.logging.ArtifactManager +import org.mozilla.fenix.ui.efficiency.factory.logging.StepLogger +import java.io.File + +/** + * Provides developer-facing debug utilities for factory test runs. + * + * `DebugControls` lets engineers modify runtime behavior of test factories via + * instrumentation arguments, without touching source code or build scripts. + * This makes it easier to debug locally on emulators and physical devices, + * where Firebase-style artifact export may not yet be available. + * + * Supported runtime arguments: + * ``` + * -e factoryExportPublic true # Export artifacts to /sdcard/TestFactoryArtifacts/<runId> + * -e factoryPauseAfterRunSec 15 # Pause (in seconds) after suite finishes for inspection + * ``` + * + * Example Gradle invocation: + * ``` + * ./gradlew :app:connectedDebugAndroidTest \ + * -Pandroid.testInstrumentationRunnerArguments.factoryExportPublic=true \ + * -Pandroid.testInstrumentationRunnerArguments.factoryPauseAfterRunSec=15 + * ``` + * + * During a test run, the factories call [onSuiteEnd] after each Presence, + * Interaction, or Behavior suite completes. This hook optionally mirrors + * artifacts to public storage and delays teardown to allow adb inspection. + */ +object DebugControls { + + /** + * Parsed runtime flags from the instrumentation arguments. + * + * @property exportPublic Whether to copy artifacts from the app sandbox to a + * public location under `/sdcard/TestFactoryArtifacts`. + * @property pauseSeconds How long (in seconds) to sleep after the suite ends + * to give developers time to inspect files. + */ + data class Flags( + val exportPublic: Boolean = false, + val pauseSeconds: Long = 0L, + ) + + /** + * Reads instrumentation arguments and builds a [Flags] instance. + * + * @return Parsed [Flags] with defaults if arguments are missing or invalid. + */ + fun flags(): Flags { + val args = InstrumentationRegistry.getArguments() + val export = args.getString("factoryExportPublic")?.equals("true", ignoreCase = true) == true + val pause = args.getString("factoryPauseAfterRunSec")?.toLongOrNull() ?: 0L + return Flags(exportPublic = export, pauseSeconds = pause) + } + + /** + * Executes developer-mode actions after a suite (Presence, Interaction, or Behavior) + * has completed. + * + * 1. **Export:** If [Flags.exportPublic] is `true`, copies all artifacts from the + * sandbox directory (under the app’s private external storage) to a stable, + * public path: `/sdcard/TestFactoryArtifacts/<runId>/`. This copy survives + * app uninstall and can be viewed through the Android file system or pulled + * via `adb pull`. + * 2. **Pause:** If [Flags.pauseSeconds] > 0, blocks the test thread for that + * duration to allow manual inspection or debugging. + * + * @param logger The active [StepLogger], used to record export or pause activity. + * @param flags Runtime configuration read from [flags]. + */ + fun onSuiteEnd(logger: StepLogger, flags: Flags) { + if (flags.exportPublic) { + val runDir = ArtifactManager.base() // .../artifacts/<run-id> + val runId = runDir.name + val exported = ShellExporter.exportRunDir(runId, runDir) + if (exported != null) { + logger.info("Exported artifacts to $exported") + } else { + logger.warn("Public export failed", mapOf("src" to runDir.absolutePath)) + } + } + if (flags.pauseSeconds > 0) { + logger.info("Pausing after run", mapOf("seconds" to flags.pauseSeconds)) + try { + Thread.sleep(flags.pauseSeconds * 1000) + } catch (_: InterruptedException) { + // Ignored; used only for debug inspection + null + } + } + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/debug/ShellExporter.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/debug/ShellExporter.kt @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.debug + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import java.io.File + +/** + * Provides a minimal shell-based file export mechanism for test artifacts. + * + * `ShellExporter` mirrors the current test run’s artifacts directory to + * a public folder (`/sdcard/TestFactoryArtifacts/<runId>`) using shell commands + * executed by [UiDevice]. This approach avoids requiring any Gradle or manifest + * changes and works on both emulators and physical devices. + * + * Artifacts exported here persist after the test APK is uninstalled, making + * them useful for local debugging and developer inspection. + * + * **Implementation notes:** + * - Uses `mkdir -p` to ensure target directories exist. + * - Uses `cp -r` to recursively copy the run directory contents. + * - Relies on `toybox`/`busybox` tools included on most Android 8+ images. + * - Returns `null` if the command fails silently or device shell is unavailable. + */ +object ShellExporter { + + /** Root directory under public external storage for exported test artifacts. */ + private const val PUBLIC_ROOT = "/sdcard/TestFactoryArtifacts" + + /** + * Copies the entire artifacts run directory from the app’s sandbox into a + * public location. + * + * Typical source: + * ``` + * /storage/emulated/0/Android/data/<package>/files/artifacts/<runId>/ + * ``` + * Copied to: + * ``` + * /sdcard/TestFactoryArtifacts/<runId>/ + * ``` + * + * This method is intentionally simple and platform-agnostic; it executes + * standard shell commands using [UiDevice.executeShellCommand] to perform + * the copy. If the operation succeeds, the full destination path is returned. + * + * @param runId Identifier for the current test run, used to name the export folder. + * @param srcRunDir Source directory produced by [ArtifactManager] containing logs + * and screenshots for the current run. + * @return Absolute path to the exported folder if successful, or `null` on failure. + */ + fun exportRunDir(runId: String, srcRunDir: File): String? { + return try { + val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + val dst = "$PUBLIC_ROOT/$runId" + + // Ensure destination exists before copying. + device.executeShellCommand("mkdir -p \"$dst\"") + + // Copy directory recursively. The trailing '/.' ensures only the contents + // of the folder are copied, not the parent directory itself. + val cmd = "cp -r \"${srcRunDir.absolutePath}/.\" \"$dst/\"" + device.executeShellCommand(cmd) + + dst + } catch (_: Throwable) { + null + } + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/BehaviorFactory.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/BehaviorFactory.kt @@ -0,0 +1,114 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.factories + +import org.mozilla.fenix.ui.efficiency.factory.debug.DebugControls +import org.mozilla.fenix.ui.efficiency.factory.feature.FeatureSpec +import org.mozilla.fenix.ui.efficiency.factory.logging.ScreenshotTaker +import org.mozilla.fenix.ui.efficiency.factory.logging.StepDescriptor +import org.mozilla.fenix.ui.efficiency.factory.logging.TestStatus +import org.mozilla.fenix.ui.efficiency.factory.steps.StepContext +import org.mozilla.fenix.ui.efficiency.factory.steps.StepResult + +/** + * Executes **Behavior** tier checks for a [FeatureSpec]. + * + * The Behavior tier verifies minimal “business logic” outcomes across page boundaries. + * Typical pattern: + * 1) **setup** steps (e.g., toggle a setting), + * 2) **trigger** steps (e.g., visit a URL), + * 3) **cross-page verify** steps (e.g., assert a History page group is empty). + * + * Logging & artifacts: + * - Starts/ends a test scope with ID: `<FEATURE>.Behavior` + * - Emits step start/end records to the logger. + * - On any failure, captures a screenshot into the artifacts directory and attaches its path. + * - Defers to [DebugControls] at suite end to optionally export/publicly mirror artifacts and pause. + */ +object BehaviorFactory { + + /** + * Runs all Behavior checks for the provided [spec] in the given [ctx]. + * + * Flow: + * - Run [FeatureSpec.preconditions] + * - For each behavior check: + * - run `setupSteps`, then `triggerSteps` + * - run each `crossPageVerifySteps`; **first failure aborts** the suite with FAIL + * - Run [FeatureSpec.cleanup] regardless of pass or fail path + * + * @param spec The feature description to execute. + * @param ctx The active test context (rule, PageContext, logger). + * @return [TestStatus.PASS] if all checks succeed, otherwise [TestStatus.FAIL]. + */ + fun run(spec: FeatureSpec, ctx: StepContext): TestStatus { + val testId = "${spec.key}.Behavior" + ctx.logger.testStart(testId) + val flags = DebugControls.flags() // read once per suite + + try { + for (p in spec.preconditions) if (p.perform(ctx) is StepResult.Fail) return endFail(ctx, testId) + + spec.sanity.forEachIndexed { i, b -> + val leaf = "behavior-$i" + val sd = StepDescriptor(leaf, "Behavior.Check") + ctx.logger.stepStart(sd) + + for (s in b.setupSteps) { + if (s.perform(ctx) is StepResult.Fail) { + shot(ctx, testId, leaf, "setup-fail"); return endFail(ctx, testId) + } + } + + for (t in b.triggerSteps) { + if (t.perform(ctx) is StepResult.Fail) { + shot(ctx, testId, leaf, "trigger-fail"); return endFail(ctx, testId) + } + } + + for (v in b.crossPageVerifySteps) { + val vr = v.perform(ctx) + if (vr is StepResult.Fail) { + ctx.logger.stepEnd(sd, vr) + shot(ctx, testId, leaf, "verify-fail") + return endFail(ctx, testId) + } + } + ctx.logger.stepEnd(sd, StepResult.Ok) + } + + for (c in spec.cleanup) c.perform(ctx) + ctx.logger.testEnd(testId, TestStatus.PASS) + DebugControls.onSuiteEnd(ctx.logger, flags) + return TestStatus.PASS + } catch (_: Throwable) { + shot(ctx, testId, "exception", "uncaught") + DebugControls.onSuiteEnd(ctx.logger, flags) + return TestStatus.FAIL + } + } + + /** + * Helper that captures a screenshot (if possible) and attaches it to the logger. + * + * @param ctx Active test context. + * @param testId Current suite test ID, e.g. `"FEATURE.Behavior"`. + * @param leaf Leaf step/scope identifier (e.g., `"behavior-0"`). + * @param name Screenshot filename stem (e.g., `"verify-fail"`). + */ + private fun shot(ctx: StepContext, testId: String, leaf: String, name: String) { + ScreenshotTaker.capture(testId, leaf, name)?.let { path -> + ctx.logger.attachScreenshot(StepDescriptor(leaf, "Behavior.Check"), path) + } + } + + /** + * Ends the current suite with FAIL and returns the status. + * Always emits a `testEnd(..., FAIL)` record. + */ + private fun endFail(ctx: StepContext, testId: String): TestStatus { + ctx.logger.testEnd(testId, TestStatus.FAIL); return TestStatus.FAIL + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/InteractionFactory.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/InteractionFactory.kt @@ -0,0 +1,94 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.factories + +import org.mozilla.fenix.ui.efficiency.factory.debug.DebugControls +import org.mozilla.fenix.ui.efficiency.factory.feature.FeatureSpec +import org.mozilla.fenix.ui.efficiency.factory.logging.ScreenshotTaker +import org.mozilla.fenix.ui.efficiency.factory.logging.StepDescriptor +import org.mozilla.fenix.ui.efficiency.factory.logging.TestStatus +import org.mozilla.fenix.ui.efficiency.factory.steps.StepContext +import org.mozilla.fenix.ui.efficiency.factory.steps.StepResult + +/** + * Executes **Interaction** tier checks for a [FeatureSpec]. + * + * The Interaction tier validates that UI elements are **responsive** and that + * a simple action + verification sequence works as expected (without deep business logic). + * + * Example flow per check: + * - Navigate to a page + * - Perform an action (toggle, tap, menu selection) + * - Verify a single expected UI artifact + * + * On failure of any step (navigate/action/verify), the suite fails fast and + * captures a screenshot for triage. At suite end, [DebugControls] may export + * artifacts or pause based on instrumentation args. + */ +object InteractionFactory { + + /** + * Runs all Interaction checks for the provided [spec] in the given [ctx]. + * + * @param spec The feature description to execute. + * @param ctx The active test context (rule, PageContext, logger). + * @return [TestStatus.PASS] if all checks succeed, otherwise [TestStatus.FAIL]. + */ + fun run(spec: FeatureSpec, ctx: StepContext): TestStatus { + val testId = "${spec.key}.Interaction" + ctx.logger.testStart(testId) + val flags = DebugControls.flags() // read once per suite + + try { + for (p in spec.preconditions) if (p.perform(ctx) is StepResult.Fail) return endFail(ctx, testId) + + spec.interactions.forEachIndexed { i, c -> + val leaf = "interaction-$i" + val sd = StepDescriptor(leaf, "Interaction.Check") + ctx.logger.stepStart(sd) + if (c.navigateStep.perform(ctx) is StepResult.Fail) { + shot(ctx, testId, leaf, "nav-fail") + return endFail(ctx, testId) + } + if (c.actionStep.perform(ctx) is StepResult.Fail) { + shot(ctx, testId, leaf, "action-fail") + return endFail(ctx, testId) + } + val vr = c.verifyStep.perform(ctx) + ctx.logger.stepEnd(sd, vr) + if (vr is StepResult.Fail) { + shot(ctx, testId, leaf, "verify-fail") + return endFail(ctx, testId) + } + } + + for (c in spec.cleanup) c.perform(ctx) + ctx.logger.testEnd(testId, TestStatus.PASS) + DebugControls.onSuiteEnd(ctx.logger, flags) + return TestStatus.PASS + } catch (_: Throwable) { + shot(ctx, testId, "exception", "uncaught") + DebugControls.onSuiteEnd(ctx.logger, flags) + return TestStatus.FAIL + } + } + + /** + * Helper that captures a screenshot (if possible) and attaches it to the logger. + */ + private fun shot(ctx: StepContext, testId: String, leaf: String, name: String) { + ScreenshotTaker.capture(testId, leaf, name)?.let { path -> + ctx.logger.attachScreenshot(StepDescriptor(leaf, "Interaction.Check"), path) + } + } + + /** + * Ends the current suite with FAIL and returns the status. + * Always emits a `testEnd(..., FAIL)` record. + */ + private fun endFail(ctx: StepContext, testId: String): TestStatus { + ctx.logger.testEnd(testId, TestStatus.FAIL); return TestStatus.FAIL + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/PresenceFactory.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/factories/PresenceFactory.kt @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.factories + +import org.mozilla.fenix.ui.efficiency.factory.debug.DebugControls +import org.mozilla.fenix.ui.efficiency.factory.feature.FeatureSpec +import org.mozilla.fenix.ui.efficiency.factory.logging.ScreenshotTaker +import org.mozilla.fenix.ui.efficiency.factory.logging.StepDescriptor +import org.mozilla.fenix.ui.efficiency.factory.logging.TestStatus +import org.mozilla.fenix.ui.efficiency.factory.steps.StepContext +import org.mozilla.fenix.ui.efficiency.factory.steps.StepResult + +/** + * Executes **Presence** tier checks for a [FeatureSpec]. + * + * The Presence tier answers: *do the expected UI elements render in the right places?* + * It does not interact with elements beyond navigation + verification. This gives a fast, + * high-signal read on “does the UI show up?” for a feature. + * + * Logging & artifacts: + * - Starts/ends a test scope with ID: `<FEATURE>.Presence` + * - Emits step start/end records + * - Captures screenshots on failures + * - Invokes [DebugControls] at end for optional public export and pause + */ +object PresenceFactory { + + /** + * Runs all Presence checks for the provided [spec] in the given [ctx]. + * + * @param spec The feature description to execute. + * @param ctx The active test context (rule, PageContext, logger). + * @return [TestStatus.PASS] if all checks succeed, otherwise [TestStatus.FAIL]. + */ + fun run(spec: FeatureSpec, ctx: StepContext): TestStatus { + val testId = "${spec.key}.Presence" + ctx.logger.testStart(testId) + val flags = DebugControls.flags() // read once per suite + + try { + for (p in spec.preconditions) if (p.perform(ctx) is StepResult.Fail) return endFail(ctx, testId) + + spec.surfaces.forEachIndexed { i, s -> + val leaf = "presence-$i" + val sd = StepDescriptor(leaf, "Presence.SurfaceCheck") + ctx.logger.stepStart(sd) + if (s.navigateStep.perform(ctx) is StepResult.Fail) { + shot(ctx, testId, leaf, "nav-fail") + return endFail(ctx, testId) + } + val vr = s.verifyStep.perform(ctx) + ctx.logger.stepEnd(sd, vr) + if (vr is StepResult.Fail) { + shot(ctx, testId, leaf, "verify-fail") + return endFail(ctx, testId) + } + } + + for (c in spec.cleanup) c.perform(ctx) + ctx.logger.testEnd(testId, TestStatus.PASS) + DebugControls.onSuiteEnd(ctx.logger, flags) + return TestStatus.PASS + } catch (_: Throwable) { + shot(ctx, testId, "exception", "uncaught") + ctx.logger.testEnd(testId, TestStatus.FAIL) + DebugControls.onSuiteEnd(ctx.logger, flags) + return TestStatus.FAIL + } + } + + /** + * Helper that captures a screenshot (if possible) and attaches it to the logger. + */ + private fun shot(ctx: StepContext, testId: String, leaf: String, name: String) { + ScreenshotTaker.capture(testId, leaf, name)?.let { path -> + ctx.logger.attachScreenshot(StepDescriptor(leaf, "Presence.SurfaceCheck"), path) + } + } + + /** + * Ends the current suite with FAIL and returns the status. + * Always emits a `testEnd(..., FAIL)` record. + */ + private fun endFail(ctx: StepContext, testId: String): TestStatus { + ctx.logger.testEnd(testId, TestStatus.FAIL); return TestStatus.FAIL + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/Checks.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/Checks.kt @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.feature + +import org.mozilla.fenix.ui.efficiency.factory.steps.TestStep + +/** + * Represents a minimal "presence" validation in a feature spec. + * + * Each [SurfaceCheck] describes a single surface to visit and verify: + * - Navigate to the surface (page, panel, menu) + * - Verify that a group of expected UI elements is present + * + * These checks form the **Presence** tier in the factory test suite. + * + * @property navigateStep A [TestStep] responsible for reaching the page or surface. + * @property verifyStep A [TestStep] that verifies expected UI elements are visible. + */ +data class SurfaceCheck( + val navigateStep: TestStep, + val verifyStep: TestStep, +) + +/** + * Represents a simple "action and verify" flow in a feature spec. + * + * Each [InteractionCheck] performs: + * - A navigation step + * - One action step (tap/toggle/menu item) + * - One verification step + * + * These checks make up the **Interaction** tier in the factory test suite. + * + * @property navigateStep Step that navigates to the correct page before interaction. + * @property actionStep Step that performs the user interaction to test responsiveness. + * @property verifyStep Step that validates the expected UI artifact after interaction. + */ +data class InteractionCheck( + val navigateStep: TestStep, + val actionStep: TestStep, + val verifyStep: TestStep, +) + +/** + * Represents a multi-step scenario that validates feature behavior across pages. + * + * A [BehaviorCheck] follows a 3-phase structure: + * 1. **Setup:** Prepare the feature state (e.g., enable a toggle) + * 2. **Trigger:** Perform the action under test (e.g., visit a website) + * 3. **Cross-page verification:** Confirm expected outcomes (e.g., history remains empty) + * + * These checks define the **Behavior** tier in the factory test suite. + * + * @property setupSteps Steps that configure or prepare state for the scenario. + * @property triggerSteps Steps that trigger the feature logic being tested. + * @property crossPageVerifySteps Steps that assert expected UI or data on other surfaces. + */ +data class BehaviorCheck( + val setupSteps: List<TestStep>, + val triggerSteps: List<TestStep>, + val crossPageVerifySteps: List<TestStep>, +) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/FeatureKey.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/FeatureKey.kt @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.feature + +/** + * Identifies distinct features that can be described and executed by the + * test factory framework. + * + * Each [FeatureKey] acts as a stable identifier for a feature specification. + * It maps directly to the test suite name (e.g. `<FEATURE>.Presence`). + * + * Add new entries here when onboarding new feature specs (e.g., `GPC`, `HISTORY`). + */ +enum class FeatureKey { + /** Private Browsing mode: UI state, toggles, and behavior isolation. */ + PRIVATE_BROWSING, +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/FeatureSpec.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/feature/FeatureSpec.kt @@ -0,0 +1,52 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.feature + +import org.mozilla.fenix.ui.efficiency.factory.steps.TestStep + +/** + * Describes the complete test specification for a feature under test. + * + * A [FeatureSpec] defines the ordered sets of checks and steps that the + * test factories (Presence, Interaction, and Behavior) will execute. + * + * Structure: + * - **preconditions** — steps to prepare the app before any suite runs + * - **surfaces** — [SurfaceCheck]s for the Presence tier + * - **interactions** — [InteractionCheck]s for the Interaction tier + * - **sanity** — [BehaviorCheck]s for the Behavior tier + * - **cleanup** — steps to restore app state after all checks complete + * + * The same [FeatureSpec] object can be reused across tiers. Factories will + * automatically select the relevant portion (e.g., PresenceFactory uses only + * [surfaces]). + * + * Example (conceptual): + * ``` + * FeatureSpec( + * key = FeatureKey.PRIVATE_BROWSING, + * preconditions = listOf(Navigate.To.Home()), + * surfaces = [ ... ], + * interactions = [ ... ], + * sanity = [ ... ], + * cleanup = listOf(Toggle.PrivateBrowsing(false)) + * ) + * ``` + * + * @property key Unique [FeatureKey] for grouping generated tests. + * @property preconditions Steps to ensure the app is in a valid starting state. + * @property surfaces Presence checks: navigation + verification pairs. + * @property interactions Interaction checks: navigation + action + verification. + * @property sanity Behavior checks: setup + trigger + cross-page verify. + * @property cleanup Steps to run after all tiers complete, even on failure. + */ +data class FeatureSpec( + val key: FeatureKey, + val preconditions: List<TestStep> = emptyList(), + val surfaces: List<SurfaceCheck> = emptyList(), + val interactions: List<InteractionCheck> = emptyList(), + val sanity: List<BehaviorCheck> = emptyList(), + val cleanup: List<TestStep> = emptyList(), +) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/ArtifactManager.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/ArtifactManager.kt @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.logging + +import java.io.File + +/** + * Centralized accessor for the **current run's artifact root**. + * + * Factories and utilities (e.g., [ScreenshotTaker]) rely on this to know + * *where* to write files. The directory is initialized by [LoggerFactory.create] + * and remains valid for the lifetime of the test process. + * + * Directory layout: + * ``` + * artifacts/<run-id>/summary.log + * artifacts/<run-id>/details.jsonl + * artifacts/<run-id>/<testId>/<leaf>/<files...> + * ``` + * + * Usage: + * - [base] gives you `artifacts/<run-id>` + * - [dirForTest(testId)] → `artifacts/<run-id>/<testId>/` + * - [dirForTest(testId, leaf)] → `artifacts/<run-id>/<testId>/<leaf>/` + * + * All path segments are sanitized for filesystem safety. + */ +object ArtifactManager { + @Volatile private var baseDir: File? = null + + /** + * Sets the artifacts base directory (called exactly once in [LoggerFactory.create]). + */ + fun init(root: File) { + check(baseDir == null) { "ArtifactManager already initialized." } + if (!root.exists()) root.mkdirs() + baseDir = root + } + + /** + * Returns the initialized base directory for the current run. + * + * @throws IllegalStateException if [init] has not been called yet. + */ + fun base(): File = requireNotNull(baseDir) { + "ArtifactManager not initialized. Call LoggerFactory.create() first." + } + + /** Ensures and returns `artifacts/<run-id>/<testId>/`. */ + fun dirForTest(testId: String): File = File(base(), sanitize(testId)).apply { mkdirs() } + + /** Ensures and returns `artifacts/<run-id>/<testId>/<leaf>/`. */ + fun dirForTest(testId: String, leaf: String): File = + File(dirForTest(testId), sanitize(leaf)).apply { mkdirs() } + + /** Replaces characters that are unsafe for file/dir names with underscores. */ + private fun sanitize(s: String) = s.replace("""[^\w.\-]+""".toRegex(), "_") +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/JsonSink.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/JsonSink.kt @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.logging + +import org.json.JSONObject +import java.io.File +import java.util.Date + +/** + * Appends structured **newline-delimited JSON** (JSONL) events to a file. + * + * Each call to [event] writes exactly one JSON object per line, + * injecting a millisecond-resolution `"ts"` timestamp. + * This format is easy to stream, parse, or index with log tools. + * + * Example line: + * ``` + * {"type":"stepEnd","stepId":"presence-0","result":"PASS","ts":1731000000000} + * ``` + * + * This sink is **best-effort**: any I/O or serialization failure is caught and + * logged to Logcat, never propagated to the caller, ensuring tests continue. + */ +class JsonSink(private val file: File) { + + /** + * Serializes [map] to JSON, injects `"ts"` (epoch millis), and appends a line. + * + * Thread-safe: synchronized to avoid interleaved writes from parallel tests + * within the same process (AndroidX can run multiple tests in one instrumentation). + * + * Exceptions are caught and logged at WARN level to prevent test interruption. + */ + @Synchronized + fun event(map: Map<String, Any?>) { + try { + val obj = JSONObject(map + mapOf("ts" to Date().time)) + file.appendText(obj.toString() + "\n") + } catch (t: Throwable) { + // Never let logging crash the test + android.util.Log.w("JsonSink", "Failed to write JSON event: ${t.message}") + } + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/LoggerFactory.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/LoggerFactory.kt @@ -0,0 +1,209 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.logging + +import android.content.Context +import androidx.test.platform.app.InstrumentationRegistry +import org.mozilla.fenix.ui.efficiency.factory.steps.StepResult +import java.io.File + +/** + * Multiplexing logger that fans out high-level messages to: + * + * - [SummarySink]: human-readable, line-oriented log (`summary.log`) + * - [JsonSink]: machine-readable, newline-delimited JSON (`details.jsonl`) + * + * This logger is **best-effort**: any sink failure is swallowed and logged to Logcat + * so logging can never crash a test or mask the root failure. + * + * This class implements the [StepLogger] interface used by factories so + * calling code does not care about concrete sinks or file layout. + */ +class CombinedLogger( + private val summary: SummarySink, + private val json: JsonSink, +) : StepLogger { + + /** + * Executes [fn] and swallows any Throwable raised by sinks, logging a WARN. + * This ensures logging never interferes with test execution. + */ + private fun swallow(phase: String, fn: () -> Unit) { + try { + fn() + } catch (t: Throwable) { + android.util.Log.w("CombinedLogger", "Sink failure during $phase: ${t.message}", t) + } + } + + /** Marks the beginning of a factory suite (e.g., `FEATURE.Presence`). */ + override fun testStart(testId: String, meta: Map<String, Any?>) { + swallow("testStart:summary") { summary.line("[TEST] $testId — START") } + swallow("testStart:json") { json.event(mapOf("type" to "testStart", "testId" to testId, "meta" to meta)) } + } + + /** Marks the end of a suite with a terminal [TestStatus]. */ + override fun testEnd(testId: String, status: TestStatus) { + swallow("testEnd:summary") { summary.line("[TEST] $testId — $status") } + swallow("testEnd:json") { json.event(mapOf("type" to "testEnd", "testId" to testId, "status" to status.name)) } + } + + /** Emits a step-begin record (navigation, action, verify, etc.). */ + override fun stepStart(step: StepDescriptor) { + swallow("stepStart:summary") { summary.line("[STEP] ${step.name} ${step.args} — START") } + swallow("stepStart:json") { + json.event(mapOf("type" to "stepStart", "stepId" to step.id, "name" to step.name, "args" to step.args)) + } + } + + /** Emits a step-end record with PASS/FAIL (and reason if failed). */ + override fun stepEnd(step: StepDescriptor, result: StepResult) { + val status = if (result is StepResult.Ok) "PASS" else "FAIL" + swallow("stepEnd:summary") { summary.line("[STEP] ${step.name} — $status") } + swallow("stepEnd:json") { + json.event( + mapOf( + "type" to "stepEnd", + "stepId" to step.id, + "name" to step.name, + "result" to status, + "reason" to (result as? StepResult.Fail)?.reason, + ), + ) + } + } + + /** Free-form informational note. */ + override fun info(msg: String, kv: Map<String, Any?>) { + swallow("info:summary") { summary.line("[INFO] $msg $kv") } + swallow("info:json") { json.event(mapOf("type" to "info", "msg" to msg, "kv" to kv)) } + } + + /** Warning (non-fatal). */ + override fun warn(msg: String, kv: Map<String, Any?>) { + swallow("warn:summary") { summary.line("[WARN] $msg $kv") } + swallow("warn:json") { json.event(mapOf("type" to "warn", "msg" to msg, "kv" to kv)) } + } + + /** Error (non-fatal); include throwable stack trace if provided. */ + override fun error(msg: String, kv: Map<String, Any?>, throwable: Throwable?) { + swallow("error:summary") { summary.line("[ERROR] $msg $kv ${throwable?.message ?: ""}") } + swallow("error:json") { + json.event(mapOf("type" to "error", "msg" to msg, "kv" to kv, "error" to (throwable?.stackTraceToString()))) + } + } + + /** + * Attaches a screenshot path to both sinks so consumers + * (humans + machines) can correlate imagery with a step. + */ + override fun attachScreenshot(step: StepDescriptor, path: String) { + swallow("screenshot:summary") { summary.line("[SHOT] ${step.name} → $path") } + swallow("screenshot:json") { json.event(mapOf("type" to "screenshot", "stepId" to step.id, "path" to path)) } + } +} + +/** + * Factory for a ready-to-use [StepLogger] and run-scoped artifact directory. + * + * Responsibilities: + * - Creates `artifacts/<run-id>/` under app storage (external if available, else internal) + * - Initializes [ArtifactManager] with that directory + * - Wires a [CombinedLogger] with [SummarySink] and [JsonSink] file targets + * + * Fault tolerance: + * - If external storage is unavailable or directory creation fails, falls back to internal storage. + * - If sink setup or ArtifactManager init fails, returns a **no-op** logger so tests keep running. + */ +object LoggerFactory { + + /** + * Create a [StepLogger] and initialize the artifacts root for this run. + * + * The method prefers external app storage, then falls back to internal storage, + * and finally to an internal fallback directory if needed. If sink setup fails, + * a **no-op** logger is returned so tests continue to run. + * + * @param runId Optional run identifier used as the artifacts directory name (sanitized). + * Defaults to current epoch millis for uniqueness. + * @param ctx Optional Android context; defaults to instrumentation target context + * via [InstrumentationRegistry]. + */ + fun create( + runId: String = System.currentTimeMillis().toString(), + ctx: Context? = null, + ): StepLogger { + val appCtx = ctx ?: InstrumentationRegistry.getInstrumentation().targetContext + val safeRunId = runId.replace("""[^\w.\-]+""".toRegex(), "_") + + // Choose a base storage root (prefer external, fall back to internal) + val externalBase: File? = try { + appCtx.getExternalFilesDir(null) + } catch (_: Throwable) { + null + } + val internalBase: File = appCtx.filesDir + + // Try external/artifacts/<runId>, else internal/artifacts/<runId>, else internal fallback. + val candidateRoots = sequenceOf( + (externalBase ?: internalBase) to "preferred", + internalBase to "internal", + ).map { (base, label) -> + val dir = File(base, "artifacts/$safeRunId") + label to dir + }.toList() + + val root: File = run { + var chosen: File? = null + for ((label, dir) in candidateRoots) { + try { + if (dir.exists() || dir.mkdirs()) { + android.util.Log.i("LoggerFactory", "Artifacts root: [$label] ${dir.absolutePath}") + chosen = dir + break + } else { + android.util.Log.w("LoggerFactory", "mkdirs failed: ${dir.absolutePath}") + } + } catch (t: Throwable) { + android.util.Log.w("LoggerFactory", "Failed creating ${dir.absolutePath}: ${t.message}", t) + } + } + chosen ?: File(internalBase, "artifacts/_fallback_${System.currentTimeMillis()}").apply { + mkdirs() + android.util.Log.w("LoggerFactory", "Using fallback artifacts root: $absolutePath") + } + } + + // Initialize artifact manager safely + try { + ArtifactManager.init(root) + } catch (t: Throwable) { + android.util.Log.w("LoggerFactory", "ArtifactManager init failed, using no-op logger: ${t.message}", t) + return noOpLogger() + } + + // Create sinks (best-effort; if file I/O fails, return a no-op logger) + return try { + val summary = SummarySink(File(root, "summary.log")) + val json = JsonSink(File(root, "details.jsonl")) + CombinedLogger(summary, json) + } catch (t: Throwable) { + android.util.Log.w("LoggerFactory", "Sink setup failed, using no-op logger: ${t.message}", t) + noOpLogger() + } + } + + /** Minimal logger that never writes; used when sinks cannot be initialized. */ + private fun noOpLogger(): StepLogger = object : StepLogger { + override fun testStart(testId: String, meta: Map<String, Any?>) {} + override fun testEnd(testId: String, status: TestStatus) {} + override fun stepStart(step: StepDescriptor) {} + override fun stepEnd(step: StepDescriptor, result: StepResult) {} + override fun info(msg: String, kv: Map<String, Any?>) {} + override fun warn(msg: String, kv: Map<String, Any?>) {} + override fun error(msg: String, kv: Map<String, Any?>, throwable: Throwable?) {} + override fun attachScreenshot(step: StepDescriptor, path: String) {} + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/ScreenshotTaker.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/ScreenshotTaker.kt @@ -0,0 +1,91 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.logging + +import android.graphics.Bitmap +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import java.io.File +import java.io.FileOutputStream + +/** + * Utility for capturing full-device screenshots during test execution. + * + * Screenshots are stored under the active run's artifact directory, in folders + * structured by test and step: + * ``` + * artifacts/<run-id>/<testId>/<leaf>/<name>.png + * ``` + * + * Capture strategy: + * 1. **Preferred:** [UiDevice.takeScreenshot] (works on Android 10+) + * 2. **Fallback:** [android.app.UiAutomation.takeScreenshot] when the first method fails + * + * Failures are silently ignored — factories always continue, returning `null` + * if capture was unsuccessful. This avoids introducing flakiness into tests. + * + * This class requires **no extra permissions**; screenshots are written into + * the app’s private external files directory managed by [ArtifactManager]. + */ +object ScreenshotTaker { + + /** + * Captures a screenshot and saves it into the artifacts tree. + * + * @param testId Identifier of the active test suite (e.g., `"PRIVATE_BROWSING.Presence"`). + * @param leaf Optional subfolder name (e.g., `"behavior-2"` or `"presence-0"`). + * @param name Base filename (without extension). `.png` will be appended automatically. + * @return The absolute file path if capture succeeded, or `null` if it failed. + */ + fun capture(testId: String, leaf: String? = null, name: String = "screenshot"): String? { + return try { + // Choose correct subdirectory for this test + step + val dir = if (leaf.isNullOrBlank()) { + ArtifactManager.dirForTest(testId) + } else { + ArtifactManager.dirForTest(testId, leaf) + } + val file = File(dir, "${safe(name)}.png") + + val instrumentation = InstrumentationRegistry.getInstrumentation() + val device = UiDevice.getInstance(instrumentation) + + // Preferred path: UiDevice.takeScreenshot(File) + val ok = try { + // Newer UiAutomator: + // device.takeScreenshot(file) returns Boolean + device.takeScreenshot(file) + } catch (_: Throwable) { + // Fallback: UiAutomation.takeScreenshot() -> PNG + tryUiAutomationFallback(file) + } + + if (ok) file.absolutePath else null + } catch (_: Throwable) { + null + } + } + + /** + * Secondary capture path using UiAutomation.takeScreenshot(). + * Used when UiDevice.takeScreenshot() is unavailable or fails silently. + */ + private fun tryUiAutomationFallback(outFile: File): Boolean { + return try { + val bmp: Bitmap = InstrumentationRegistry.getInstrumentation() + .uiAutomation.takeScreenshot() + ?: return false + FileOutputStream(outFile).use { fos -> + bmp.compress(Bitmap.CompressFormat.PNG, 100, fos) + } + true + } catch (_: Throwable) { + false + } + } + + /** Sanitizes filenames by replacing characters unsafe for most file systems. */ + private fun safe(s: String) = s.replace("""[^\w.\-]+""".toRegex(), "_") +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/StepLogger.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/StepLogger.kt @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.logging + +import org.mozilla.fenix.ui.efficiency.factory.steps.StepResult + +/** + * Enumeration of final outcomes for a test or step. + */ +enum class TestStatus { PASS, FAIL, SKIP } + +/** + * Lightweight metadata describing a logical step within a factory test. + * + * Used for structured logging and correlation between summary and JSON outputs. + * + * @property id Unique short identifier (e.g., `"presence-0"`). + * @property name Human-readable step name (e.g., `"Navigate.To.Home"`). + * @property args Optional arguments relevant to the step (for traceability). + */ +data class StepDescriptor( + val id: String, + val name: String, + val args: Map<String, Any?> = emptyMap(), +) + +/** + * Core logging interface for test factories. + * + * The factories never write directly to files — they only emit events through + * a [StepLogger]. Implementations (e.g., [CombinedLogger]) then route these + * events to one or more sinks ([SummarySink], [JsonSink]). + * + * Typical event sequence per suite: + * ``` + * testStart() + * stepStart() + * stepEnd() + * ... + * testEnd() + * ``` + */ + +interface StepLogger { + + /** Marks the beginning of a suite (Presence, Interaction, or Behavior). */ + fun testStart(testId: String, meta: Map<String, Any?> = emptyMap()) + + /** Marks the end of a suite with a terminal [TestStatus]. */ + fun testEnd(testId: String, status: TestStatus) + + /** Logs the beginning of a discrete step. */ + fun stepStart(step: StepDescriptor) + + /** Logs the end of a step with its resulting [StepResult]. */ + fun stepEnd(step: StepDescriptor, result: StepResult) + + /** Emits an informational message (non-step-level). */ + fun info(msg: String, kv: Map<String, Any?> = emptyMap()) + + /** Emits a warning message. */ + fun warn(msg: String, kv: Map<String, Any?> = emptyMap()) + + /** Emits an error message; optionally attaches a [Throwable] stack trace. */ + fun error(msg: String, kv: Map<String, Any?> = emptyMap(), throwable: Throwable? = null) + + /** + * Links a screenshot to the current step, ensuring traceability between + * step log entries and stored image artifacts. + * + * @param step Descriptor for which the screenshot was captured. + * @param path Absolute path to the PNG file on disk. + */ + fun attachScreenshot(step: StepDescriptor, path: String) +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/SummarySink.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/logging/SummarySink.kt @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.logging + +import android.util.Log +import java.io.File +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +/** + * Writes a **human-readable summary log** (`summary.log`) for a test run. + * + * Each call to [line] appends a single timestamped line both to logcat and + * to the on-device file. The format is intentionally simple and concise: + * ``` + * 12:34:56.789 [TEST] PRIVATE_BROWSING.Presence — START + * 12:34:56.905 [STEP] Navigate.To.Home — PASS + * 12:34:57.210 [TEST] PRIVATE_BROWSING.Presence — PASS + * ``` + * + * Used by [CombinedLogger] alongside [JsonSink] for richer structured output. + * + * Thread-safe: synchronized on writes to avoid interleaving lines from + * concurrent steps in multi-test processes. + */ +class SummarySink(private val file: File) { + private val tag = "TestFactorySummary" + private val ts = SimpleDateFormat("HH:mm:ss.SSS", Locale.US) + + /** + * Appends a line to both Logcat (`INFO` level) and the summary log file. + * + * @param s The message text to write (already formatted by caller). + */ + @Synchronized + fun line(s: String) { + try { + Log.i(tag, s) + } catch (_: Throwable) { + // Ignore rare Logcat exceptions (e.g., buffer full) + } + try { + file.appendText("${ts.format(Date())} $s\n") + } catch (t: Throwable) { + Log.w(tag, "Failed to append summary line: ${t.message}", t) + } + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/ActionSteps.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/ActionSteps.kt @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.steps + +import org.mozilla.fenix.ui.efficiency.factory.logging.StepDescriptor + +/** + * Defines reusable **action steps** for toggling settings or interacting + * with UI elements that represent feature state. + * + * Each action is modeled as a [TestStep] so it can be executed and logged + * consistently within a factory sequence. + * + * Currently includes: + * - [Toggle.PrivateBrowsing] — enables or disables Private Browsing mode. + */ +fun togglePrivateBrowsing(on: Boolean) = Toggle.PrivateBrowsing(on) + +/** + * Namespace for toggle-related steps. + */ +object Toggle { + + /** + * Toggles the **Private Browsing** setting within the Settings screen. + * + * Flow: + * 1. Navigate to the Private Browsing settings page. + * 2. Toggle the state via [setPrivateBrowsing] on the page object. + * 3. Emit step logs for start/end and mark result as PASS/FAIL. + * + * On failure, the exception is logged and a [StepResult.Fail] is returned. + * + * @param on Desired Private Browsing state (`true` = enable, `false` = disable). + */ + class PrivateBrowsing(private val on: Boolean) : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("toggle-pb-$on", "Toggle.PrivateBrowsing", mapOf("on" to on)) + ctx.logger.stepStart(d) + return try { + ctx.on.settingsPrivateBrowsing.navigateToPage() + // TODO: add test step in BasePage + ctx.on.settingsPrivateBrowsing.setPrivateBrowsing(on) + ctx.logger.stepEnd(d, StepResult.Ok); StepResult.Ok + } catch (t: Throwable) { + val r = StepResult.Fail("Toggle Private Browsing failed", t) + ctx.logger.stepEnd(d, r); r + } + } + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/NavigateSteps.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/NavigateSteps.kt @@ -0,0 +1,113 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.steps + +import org.mozilla.fenix.ui.efficiency.factory.logging.StepDescriptor + +/** + * NOTE: This is for demo/explanation purposes only and is a way + * to visualize what the factories do over-the-wire. + * + * Everything here can be replaced with <Page>.navigateToPage() + * + * This module, and others like it merely allow for demoing this feature + * without 'freeing' the factory methods to start creating every permutation + * of possible tests. + * + * This will be removed or moved to a demo directory later. + */ + +// --- tiny stubs to satisfy "single top-level declaration" lint +typealias UrlString = String + +fun navigateToHome() = Navigate.To.Home() +fun navigateToSettings() = Navigate.To.Settings() +fun navigateToHistory() = Navigate.To.History() +fun navigateToUrl(url: UrlString) = Navigate.To.Url(url) +// --- end stubs + +/** + * Defines navigation-related [TestStep]s for common app surfaces. + * + * Each navigation step encapsulates: + * - Logging (start / end) + * - Exception handling with [StepResult.Fail] on error + * - Page-object call for the actual transition + * + * Steps are grouped under [Navigate.To] for consistent naming and grouping + * with the DSL (`Navigate.To.Home`, `Navigate.To.Settings`, etc.). + */ +object Navigate { + + /** Namespace grouping the actual navigation steps. */ + object To { + + /** Navigates to the Home page. */ + class Home : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("navigate-home", "Navigate.To.Home") + ctx.logger.stepStart(d) + return try { + ctx.on.home.navigateToPage() + ctx.logger.stepEnd(d, StepResult.Ok); StepResult.Ok + } catch (t: Throwable) { + val r = StepResult.Fail("Navigate Home failed", t) + ctx.logger.stepEnd(d, r); r + } + } + } + + /** Navigates to the main Settings page. */ + class Settings : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("navigate-settings", "Navigate.To.Settings") + ctx.logger.stepStart(d) + return try { + ctx.on.settings.navigateToPage() + ctx.logger.stepEnd(d, StepResult.Ok); StepResult.Ok + } catch (t: Throwable) { + val r = StepResult.Fail("Navigate Settings failed", t) + ctx.logger.stepEnd(d, r); r + } + } + } + + /** Navigates to the History page. */ + class History : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("navigate-history", "Navigate.To.History") + ctx.logger.stepStart(d) + return try { + ctx.on.history.navigateToPage() + ctx.logger.stepEnd(d, StepResult.Ok); StepResult.Ok + } catch (t: Throwable) { + val r = StepResult.Fail("Navigate History failed", t) + ctx.logger.stepEnd(d, r); r + } + } + } + + /** + * Navigates to the given URL via the omnibox on the Home page. + * + * This combines a navigation to Home followed by a call to + * [visitWebsite] on the [HomePage] object. + */ + class Url(private val url: String) : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("navigate-url", "Navigate.To.Url", mapOf("url" to url)) + ctx.logger.stepStart(d) + return try { + ctx.on.home.navigateToPage() // omnibox entry is on home + ctx.on.home.visitWebsite(url) + ctx.logger.stepEnd(d, StepResult.Ok); StepResult.Ok + } catch (t: Throwable) { + val r = StepResult.Fail("Navigate Url failed: $url", t) + ctx.logger.stepEnd(d, r); r + } + } + } + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/NoOpsSteps.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/NoOpsSteps.kt @@ -0,0 +1,59 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.steps + +import org.mozilla.fenix.ui.efficiency.factory.logging.StepDescriptor + +/** + * Collection of minimal [TestStep]s used for dry-run or synthetic tests. + * + * These steps allow developers to validate logging and control flow + * without invoking real UI interactions. + */ + +/** + * A step that simply logs and succeeds. + * + * Useful for verifying logging output and execution ordering. + */ +class NoOpStep(private val name: String = "NoOp") : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("noop-$name", "NoOp", mapOf("name" to name)) + ctx.logger.stepStart(d) + ctx.logger.info("running no-op step", mapOf("name" to name)) + ctx.logger.stepEnd(d, StepResult.Ok) + return StepResult.Ok + } +} + +/** + * A step that pauses for [millis] milliseconds before succeeding. + * + * Helps visualize timing or simulate slow operations. + */ +class SleepStep(private val millis: Long, private val name: String = "Sleep") : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("sleep-$millis", "Sleep", mapOf("ms" to millis, "name" to name)) + ctx.logger.stepStart(d) + Thread.sleep(millis) + ctx.logger.stepEnd(d, StepResult.Ok) + return StepResult.Ok + } +} + +/** + * A step that always fails with the provided [reason]. + * + * Used to test failure handling, logging, and screenshot capture paths. + */ +class FailStep(private val reason: String, private val name: String = "Fail") : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("fail-$name", "Fail", mapOf("reason" to reason)) + ctx.logger.stepStart(d) + val r = StepResult.Fail(reason) + ctx.logger.stepEnd(d, r) + return r + } +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/StepContext.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/StepContext.kt @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.steps + +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.ui.efficiency.factory.logging.StepLogger +import org.mozilla.fenix.ui.efficiency.helpers.PageContext + +/** + * Immutable, per-execution context passed into every [TestStep]. + * + * Encapsulates the minimal set of services needed by steps: + * - [rule]: Compose rule + activity rule for driving UI and synchronization + * - [on]: typed access to page objects (e.g., `on.home`, `on.history`) + * - [logger]: the active [StepLogger] for summary + JSONL output + * + * Keeping this bundle small and explicit improves test readability and makes + * steps easy to unit-test (you can fake or stub each dependency). + */ +data class StepContext( + val rule: AndroidComposeTestRule<HomeActivityIntentTestRule, *>, + val on: PageContext, + val logger: StepLogger, +) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/StepResult.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/StepResult.kt @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.steps + +/** + * Outcome of executing a single [TestStep]. + * + * Factories treat any [Fail] as **fail fast** at the current tier, after logging + * and (usually) capturing a screenshot. [Ok] indicates the step completed + * successfully and the flow may continue. + */ +sealed class StepResult { + + /** Step completed successfully. */ + object Ok : StepResult() + + /** + * Step failed with a human-readable [reason] and optional [cause]. + * + * The [reason] should be end-user friendly (appears in summary logs). The + * [cause], when present, is captured into the JSON details for triage. + */ + data class Fail(val reason: String, val cause: Throwable? = null) : StepResult() +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/TestStep.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/TestStep.kt @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.steps + +/** + * Contract for an executable step in the factory pipeline. + * + * Steps are small, composable units (navigate, toggle, verify, etc.) that: + * - receive a [StepContext] + * - perform work + * - return a [StepResult] without throwing + * + * Implementations should handle exceptions internally and convert them to + * [StepResult.Fail] so factories can log consistently and attach artifacts. + */ +interface TestStep { + + /** + * Execute the step using the given [ctx]. Implementations should: + * - write start/end records via [ctx.logger] (usually done by the step itself) + * - avoid throwing (wrap errors into [StepResult.Fail]) + */ + fun perform(ctx: StepContext): StepResult + + /** + * Convenience identifier for diagnostics; defaults to the simple class name. + * Steps may override for more stable IDs if desired. + */ + val id: String get() = this::class.simpleName ?: "UnnamedStep" +} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/VerifySteps.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/factory/steps/VerifySteps.kt @@ -0,0 +1,65 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.factory.steps + +import org.mozilla.fenix.ui.efficiency.factory.logging.StepDescriptor +import org.mozilla.fenix.ui.efficiency.helpers.BasePage +import org.mozilla.fenix.ui.efficiency.helpers.PageContext + +/** + * NOTE: This is for demo/explanation purposes only and can be + * replaced with current custom commands, one that start with 'moz', + * e.g. mozVerifyElementsByGroup. + * + * This module, and others like it merely allow for demoing this feature + * without 'freeing' the factory methods to start creating every permutation + * of possible tests. + * + * This will be removed or moved to a demo directory later. + */ + +/** + * Verifies that a named **selector group** is present on a resolved page. + * + * This step delegates to the page object's `mozVerifyElementsByGroup(groupId)`, + * which is expected to assert that all elements in the group appear/are ready. + * + * @param groupId Logical UI group identifier (e.g., `"emptyHistoryList"`). + * @param resolvePage Function that selects the target [BasePage] from a [PageContext] + * (e.g., `{ it.history }`, `{ it.home }`). + */ +class VerifyElementsByGroup( + private val groupId: String, + private val resolvePage: (PageContext) -> BasePage, +) : TestStep { + override fun perform(ctx: StepContext): StepResult { + val d = StepDescriptor("verify-$groupId", "Verify.ElementsByGroup", mapOf("groupId" to groupId)) + ctx.logger.stepStart(d) + return try { + resolvePage(ctx.on).mozVerifyElementsByGroup(groupId) + ctx.logger.stepEnd(d, StepResult.Ok); StepResult.Ok + } catch (t: Throwable) { + val r = StepResult.Fail("Verify group failed: $groupId", t) + ctx.logger.stepEnd(d, r); r + } + } +} + +/** + * DSL-friendly builder for [VerifyElementsByGroup]. + * + * Enables concise usage in specs: + * ``` + * verifyStep = mozVerifyElementsByGroup("emptyHistoryList") { it.history } + * ``` + * + * @param groupId Logical UI group identifier to verify. + * @param resolvePage Selector that maps a [PageContext] to a [BasePage]. + * @return A [TestStep] performing the group verification on the resolved page. + */ +fun mozVerifyElementsByGroup( + groupId: String, + resolvePage: (PageContext) -> BasePage, +): TestStep = VerifyElementsByGroup(groupId, resolvePage) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/features/privatebrowsing/PrivateBrowsingSpec.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/features/privatebrowsing/PrivateBrowsingSpec.kt @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.efficiency.features.privatebrowsing + +import org.mozilla.fenix.ui.efficiency.factory.feature.BehaviorCheck +import org.mozilla.fenix.ui.efficiency.factory.feature.FeatureKey +import org.mozilla.fenix.ui.efficiency.factory.feature.FeatureSpec +import org.mozilla.fenix.ui.efficiency.factory.feature.InteractionCheck +import org.mozilla.fenix.ui.efficiency.factory.feature.SurfaceCheck +import org.mozilla.fenix.ui.efficiency.factory.steps.Navigate +import org.mozilla.fenix.ui.efficiency.factory.steps.Toggle +import org.mozilla.fenix.ui.efficiency.factory.steps.VerifyElementsByGroup + +/** + * Demonstration [FeatureSpec] showing how a concrete feature definition maps + * onto the abstract factory structure. + * + * This file exists primarily as an **educational and reference example** + * for developers learning how to author a feature specification. + * + * It illustrates how Presence, Interaction, and Behavior tiers are built + * from combinations of [TestStep]s, and what kind of test cases the factories + * will later generate and execute dynamically. + * + * **Note:** This is *not* intended as a permanent production test spec. + * As the factory system matures, the Private Browsing spec (and other demo + * examples) will likely be replaced by DSL-based or data-driven definitions. + */ +val PrivateBrowsingSpec = FeatureSpec( + key = FeatureKey.PRIVATE_BROWSING, + preconditions = listOf(Navigate.To.Home()), + surfaces = listOf( + SurfaceCheck( + navigateStep = Navigate.To.Home(), + verifyStep = VerifyElementsByGroup("privateHomeHeader") { it.home }, + ), + SurfaceCheck( + navigateStep = Navigate.To.History(), + verifyStep = VerifyElementsByGroup("emptyHistoryList") { it.history }, + ), + ), + interactions = listOf( + InteractionCheck( + navigateStep = Navigate.To.Home(), + actionStep = Toggle.PrivateBrowsing(true), + verifyStep = VerifyElementsByGroup("privateHomeHeader") { it.home }, + ), + ), + sanity = listOf( + BehaviorCheck( + setupSteps = listOf(Toggle.PrivateBrowsing(true)), + triggerSteps = listOf(Navigate.To.Url("https://mozilla-mobile.github.io/testapp/")), + crossPageVerifySteps = listOf( + Navigate.To.History(), + VerifyElementsByGroup("emptyHistoryList") { it.history }, + ), + ), + ), + cleanup = listOf(Toggle.PrivateBrowsing(false)), +) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/SwipeDirection.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/SwipeDirection.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.helpers enum class SwipeDirection { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/BookmarksPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/BookmarksPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/CollectionsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/CollectionsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/CustomTabsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/CustomTabsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/DownloadsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/DownloadsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/FindInPagePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/FindInPagePage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HistoryPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HistoryPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HomePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HomePage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule @@ -63,4 +67,19 @@ class HomePage(composeRule: AndroidComposeTestRule<HomeActivityIntentTestRule, * override fun mozGetSelectorsByGroup(group: String): List<Selector> { return HomeSelectors.all.filter { it.groups.contains(group) } } + + /** + * Temporary stub for the Test Factory demo. + * + * This method exists only to illustrate how the `SettingsPrivateBrowsingTest` + * (and the Test Factory pattern) would toggle Private Browsing in a real page + * object. It is **not** connected to functional UI code and should be replaced + * with the actual implementation when Settings pages are integrated. + * + * The `UnsupportedOperationException` is intentional to ensure this placeholder + * is never used in production or non-demo tests. + */ + fun visitWebsite(url: String) { + throw UnsupportedOperationException("visitWebsite is not supported by ${this::class.simpleName}") + } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuComposePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuComposePage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MicrosurveysPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MicrosurveysPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/NotificationPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/NotificationPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/PWAPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/PWAPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ReaderViewPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ReaderViewPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/RecentlyClosedTabsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/RecentlyClosedTabsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAboutPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAboutPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAccessibilityPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAccessibilityPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAddonsManagerPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAddonsManagerPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAutofillPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAutofillPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsCustomizePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsCustomizePage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDataCollectionPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDataCollectionPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDeleteBrowsingDataOnQuitPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDeleteBrowsingDataOnQuitPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDeleteBrowsingDataPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsDeleteBrowsingDataPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsEnhancedTrackingProtectionExceptionsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsEnhancedTrackingProtectionExceptionsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsEnhancedTrackingProtectionPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsEnhancedTrackingProtectionPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsExperimentsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsExperimentsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsHTTPSOnlyModePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsHTTPSOnlyModePage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsHomepagePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsHomepagePage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsLanguagePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsLanguagePage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsOpenLinksInAppsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsOpenLinksInAppsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPasswordsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPasswordsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPrivateBrowsingPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsPrivateBrowsingPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule @@ -30,4 +34,19 @@ class SettingsPrivateBrowsingPage(composeRule: AndroidComposeTestRule<HomeActivi override fun mozGetSelectorsByGroup(group: String): List<Selector> { return SettingsPrivateBrowsingSelectors.all.filter { it.groups.contains(group) } } + + /** + * NOTE: Temporary stub for the Test Factory demo. + * + * This method exists only to illustrate how the `SettingsPrivateBrowsingTest` + * (and the Test Factory pattern) would toggle Private Browsing in a real page + * object. It is **not** connected to functional UI code and should be replaced + * with the actual implementation when Settings pages are integrated. + * + * The `UnsupportedOperationException` is intentional to ensure this placeholder + * is never used in production or non-demo tests. + */ + fun setPrivateBrowsing(on: Boolean) { + throw UnsupportedOperationException("setPrivateBrowsing is not supported by ${this::class.simpleName}") + } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSavePasswordsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSavePasswordsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSavedPasswordsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSavedPasswordsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSearchPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSearchPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsExceptionsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsExceptionsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsPermissionsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsSiteSettingsPermissionsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTabsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTabsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTranslationsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTranslationsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTurnOnSyncPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsTurnOnSyncPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ShareOverlayPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ShareOverlayPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ShortcutsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/ShortcutsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SitePermissionsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SitePermissionsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SiteSecurityPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SiteSecurityPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SystemSettingsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SystemSettingsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/TabDrawerPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/TabDrawerPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/TranslationsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/TranslationsPage.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.pageObjects import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/BookmarksSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/BookmarksSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/CollectionsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/CollectionsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/CustomTabsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/CustomTabsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/DownloadsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/DownloadsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/FindInPageSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/FindInPageSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HistorySelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HistorySelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HomeSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HomeSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuComposeSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuComposeSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MicrosurveysSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MicrosurveysSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/NotificationSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/NotificationSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.helpers.TestHelper.appName diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/PWASelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/PWASelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ReaderViewSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ReaderViewSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/RecentlyClosedTabsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/RecentlyClosedTabsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAboutSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAboutSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAccessibilitySelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAccessibilitySelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAddonsManagerSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAddonsManagerSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAutofillSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsAutofillSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsCustomizeSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsCustomizeSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDataCollectionSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDataCollectionSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDeleteBrowsingDataOnQuitSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDeleteBrowsingDataOnQuitSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDeleteBrowsingDataSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsDeleteBrowsingDataSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsEnhancedTrackingProtectionExceptionsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsEnhancedTrackingProtectionExceptionsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsEnhancedTrackingProtectionSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsEnhancedTrackingProtectionSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.helpers.TestHelper.appName diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsExperimentsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsExperimentsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsHTTPSOnlyModeSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsHTTPSOnlyModeSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsHomepageSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsHomepageSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsLanguageSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsLanguageSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsOpenLinksInAppsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsOpenLinksInAppsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsPasswordsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsPasswordsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsPrivateBrowsingSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsPrivateBrowsingSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSavePasswordsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSavePasswordsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSavedPasswordsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSavedPasswordsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSearchSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSearchSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsExceptionsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsExceptionsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsPermissionsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsPermissionsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsSiteSettingsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTabsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTabsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTranslationSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTranslationSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTurnOnSyncSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SettingsTurnOnSyncSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ShareOverlaySelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ShareOverlaySelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ShortcutsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ShortcutsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SitePermissionsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SitePermissionsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SiteSecuritySelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SiteSecuritySelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SystemSettingsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SystemSettingsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.ui.efficiency.helpers.Selector diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/TabDrawerSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/TabDrawerSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.tabstray.TabsTrayTestTag diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/TranslationsSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/TranslationsSelectors.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.selectors import org.mozilla.fenix.R diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/BookmarksTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/BookmarksTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/HistoryTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/HistoryTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/HomeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/HomeTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuComposeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuComposeTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/RecentlyClosedTabsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/RecentlyClosedTabsTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAboutTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAboutTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAccessibilityTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAccessibilityTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAutofillTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsAutofillTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsCustomizeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsCustomizeTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDataCollectionTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDataCollectionTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDeleteBrowsingDataOnQuitTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDeleteBrowsingDataOnQuitTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDeleteBrowsingDataTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsDeleteBrowsingDataTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsEnhancedTrackingProtectionExceptionsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsEnhancedTrackingProtectionExceptionsTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsEnhancedTrackingProtectionTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsEnhancedTrackingProtectionTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsHTTPSOnlyModeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsHTTPSOnlyModeTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsHomepageTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsHomepageTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsLanguageTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsLanguageTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsOpenLinksInAppsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsOpenLinksInAppsTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsPasswordsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsPasswordsTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsPrivateBrowsingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsPrivateBrowsingTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsSearchTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsSearchTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsSiteSettingsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsSiteSettingsTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTabsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTabsTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTurnOnSyncTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/SettingsTurnOnSyncTest.kt @@ -1,3 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.efficiency.tests import org.junit.Test