diff --git a/app/src/androidTest/assets/pages/download.html b/app/src/androidTest/assets/pages/download.html deleted file mode 100644 index e8928cfe301c..000000000000 --- a/app/src/androidTest/assets/pages/download.html +++ /dev/null @@ -1,10 +0,0 @@ - - - Page content: tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFHPSD4wzCkRWiaOorNI574zLtv4Hjiz6O6T7onmUTGgUQ2YQoiQFyrCrPv8ZB9Kvmt.svg - - - diff --git a/app/src/androidTest/assets/resources/tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFHPSD4wzCkRWiaOorNI574zLtv4Hjiz6O6T7onmUTGgUQ2YQoiQFyrCrPv8ZB9Kvmt.svg b/app/src/androidTest/assets/resources/tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFHPSD4wzCkRWiaOorNI574zLtv4Hjiz6O6T7onmUTGgUQ2YQoiQFyrCrPv8ZB9Kvmt.svg deleted file mode 100644 index 82d41832ae23..000000000000 --- a/app/src/androidTest/assets/resources/tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFHPSD4wzCkRWiaOorNI574zLtv4Hjiz6O6T7onmUTGgUQ2YQoiQFyrCrPv8ZB9Kvmt.svg +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt index 304e5ad698f2..d02f5114bbdd 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt @@ -16,6 +16,7 @@ class FeatureSettingsHelper { private var isPocketEnabled: Boolean = settings.showPocketRecommendationsFeature private var isJumpBackInCFREnabled: Boolean = settings.shouldShowJumpBackInCFR private var isRecentTabsFeatureEnabled: Boolean = settings.showRecentTabsFeature + private var isUserKnowsAboutPwasTrue: Boolean = settings.userKnowsAboutPwas fun setPocketEnabled(enabled: Boolean) { settings.showPocketRecommendationsFeature = enabled @@ -33,6 +34,10 @@ class FeatureSettingsHelper { settings.setStrictETP() } + fun disablePwaCFR(disable: Boolean) { + settings.userKnowsAboutPwas = disable + } + // Important: // Use this after each test if you have modified these feature settings // to make sure the app goes back to the default state @@ -40,5 +45,6 @@ class FeatureSettingsHelper { settings.showPocketRecommendationsFeature = isPocketEnabled settings.shouldShowJumpBackInCFR = isJumpBackInCFREnabled settings.showRecentTabsFeature = isRecentTabsFeatureEnabled + settings.userKnowsAboutPwas = isUserKnowsAboutPwasTrue } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt index 4d9d5fecec58..562c3ef1d611 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt @@ -5,10 +5,9 @@ package org.mozilla.fenix.helpers import android.net.Uri - +import java.util.concurrent.TimeUnit import okhttp3.mockwebserver.MockWebServer import org.mozilla.fenix.helpers.ext.toUri -import java.util.concurrent.TimeUnit /** * Helper for hosting web pages locally for testing purposes. @@ -17,8 +16,6 @@ object TestAssetHelper { @Suppress("MagicNumber") val waitingTime: Long = TimeUnit.SECONDS.toMillis(15) val waitingTimeShort: Long = TimeUnit.SECONDS.toMillis(1) - // A long enough file name to not fit on a single line in the UI. - const val downloadFileName = "tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFHPSD4wzCkRWiaOorNI574zLtv4Hjiz6O6T7onmUTGgUQ2YQoiQFyrCrPv8ZB9Kvmt.svg" data class TestAsset(val url: Uri, val content: String, val title: String) @@ -70,13 +67,6 @@ object TestAssetHelper { return TestAsset(url, content, "") } - fun getDownloadAsset(server: MockWebServer): TestAsset { - val url = server.url("pages/download.html").toString().toUri()!! - val content = "Page content: $downloadFileName" - - return TestAsset(url, content, "") - } - fun getEnhancedTrackingProtectionAsset(server: MockWebServer): TestAsset { val url = server.url("pages/trackingPage.html").toString().toUri()!! diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt new file mode 100644 index 000000000000..871600d81b82 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt @@ -0,0 +1,95 @@ +/* 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 + +import androidx.core.net.toUri +import androidx.test.rule.GrantPermissionRule +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.helpers.FeatureSettingsHelper +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.RetryTestRule +import org.mozilla.fenix.helpers.TestHelper +import org.mozilla.fenix.ui.robots.navigationToolbar + +/** + * Test for verifying downloading a list of different file types: + * - Initiates a download + * - Verifies download prompt + * - Verifies downloading of varying file types and the appearance inside the Downloads listing. + **/ +@RunWith(Parameterized::class) +class DownloadFileTypesTest(fileName: String) { + /* Remote test page managed by Mozilla Mobile QA team at https://github.com/mozilla-mobile/testapp */ + private val downloadTestPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html" + private var downloadFile: String = fileName + private val featureSettingsHelper = FeatureSettingsHelper() + + @get:Rule + val activityTestRule = HomeActivityIntentTestRule() + + @Rule + @JvmField + val retryTestRule = RetryTestRule(3) + + @get:Rule + var mGrantPermissions = GrantPermissionRule.grant( + android.Manifest.permission.WRITE_EXTERNAL_STORAGE, + android.Manifest.permission.READ_EXTERNAL_STORAGE + ) + + companion object { + // Creating test data. The test will take each file name as a parameter and run it individually. + @JvmStatic + @Parameterized.Parameters + fun downloadList() = listOf( + "washington.pdf", + "MyDocument.docx", + "audioSample.mp3", + "textfile.txt", + "web_icon.png", + "videoSample.webm", + "CSVfile.csv", + "XMLfile.xml" + ) + } + + @Before + fun setUp() { + // disabling the jump-back-in pop-up that interferes with the tests. + featureSettingsHelper.setJumpBackCFREnabled(false) + // disabling the PWA CFR on 3rd visit + featureSettingsHelper.disablePwaCFR(true) + } + + @After + fun tearDown() { + TestHelper.deleteDownloadFromStorage(downloadFile) + featureSettingsHelper.resetAllFeatureFlags() + } + + @SmokeTest + @Test + fun downloadMultipleFileTypesTest() { + navigationToolbar { + }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { + }.clickDownloadLink(downloadFile) { + verifyDownloadPrompt(downloadFile) + }.clickDownload { + verifyDownloadNotificationPopup() + }.closePrompt { + }.openThreeDotMenu { + }.openDownloadsManager { + waitForDownloadsListToExist() + verifyDownloadedFileName(downloadFile) + verifyDownloadedFileIcon() + }.exitDownloadsManagerToBrowser { } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt index e8e754847068..4148cd52ca86 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt @@ -4,39 +4,45 @@ package org.mozilla.fenix.ui +import androidx.core.net.toUri import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.GrantPermissionRule import androidx.test.uiautomator.UiDevice -import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mozilla.fenix.helpers.AndroidAssetDispatcher -import org.mozilla.fenix.helpers.HomeActivityTestRule -import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestAssetHelper.downloadFileName -import org.mozilla.fenix.helpers.TestHelper +import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.helpers.FeatureSettingsHelper +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.RetryTestRule +import org.mozilla.fenix.helpers.TestHelper.deleteDownloadFromStorage +import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.downloadRobot import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.notificationShade /** - * Tests for verifying basic functionality of download prompt UI + * Tests for verifying basic functionality of download * * - Initiates a download * - Verifies download prompt - * - Verifies download notification + * - Verifies download notification and actions + * - Verifies managing downloads inside the Downloads listing. **/ - class DownloadTest { - private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - private lateinit var mockWebServer: MockWebServer + private val featureSettingsHelper = FeatureSettingsHelper() + /* Remote test page managed by Mozilla Mobile QA team at https://github.com/mozilla-mobile/testapp */ + private val downloadTestPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html" + private var downloadFile: String = "" - /* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping. @get:Rule - val activityTestRule = HomeActivityTestRule() + val activityTestRule = HomeActivityIntentTestRule() + + @Rule + @JvmField + val retryTestRule = RetryTestRule(3) @get:Rule var mGrantPermissions = GrantPermissionRule.grant( @@ -46,53 +52,122 @@ class DownloadTest { @Before fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } + // disabling the jump-back-in pop-up that interferes with the tests. + featureSettingsHelper.setJumpBackCFREnabled(false) + // disabling the PWA CFR on 3rd visit + featureSettingsHelper.disablePwaCFR(true) } @After fun tearDown() { - mockWebServer.shutdown() - - TestHelper.deleteDownloadFromStorage(downloadFileName) + deleteDownloadFromStorage(downloadFile) + featureSettingsHelper.resetAllFeatureFlags() } @Test fun testDownloadPrompt() { - val defaultWebPage = TestAssetHelper.getDownloadAsset(mockWebServer) + downloadFile = "web_icon.png" navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() - } - + }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { + }.clickDownloadLink(downloadFile) { + verifyDownloadPrompt(downloadFile) + }.clickDownload { + verifyDownloadNotificationPopup() + }.clickOpen("image/png") {} downloadRobot { - verifyDownloadPrompt() - }.closePrompt {} + verifyPhotosAppOpens() + } } @Test - fun testDownloadNotification() { - val defaultWebPage = TestAssetHelper.getDownloadAsset(mockWebServer) + fun testCloseDownloadPrompt() { + downloadFile = "smallZip.zip" navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() + }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { + }.clickDownloadLink(downloadFile) { + verifyDownloadPrompt(downloadFile) + }.closePrompt { + }.openThreeDotMenu { + }.openDownloadsManager { + verifyEmptyDownloadsList() } + } - downloadRobot { - verifyDownloadPrompt() + @Test + fun testDownloadCompleteNotification() { + downloadFile = "smallZip.zip" + + navigationToolbar { + }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { + }.clickDownloadLink(downloadFile) { + verifyDownloadPrompt(downloadFile) }.clickDownload { verifyDownloadNotificationPopup() } - mDevice.openNotification() notificationShade { verifySystemNotificationExists("Download completed") } - // close notification shade before the next test - mDevice.pressBack() + } + + @SmokeTest + @Test + fun pauseResumeCancelDownloadTest() { + downloadFile = "1GB.zip" + + navigationToolbar { + }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { + }.clickDownloadLink(downloadFile) { + verifyDownloadPrompt(downloadFile) + }.clickDownload {} + mDevice.openNotification() + notificationShade { + expandNotificationMessage() + clickSystemNotificationControlButton("Pause") + clickSystemNotificationControlButton("Resume") + clickSystemNotificationControlButton("Cancel") + mDevice.pressBack() + } + browserScreen { + }.openThreeDotMenu { + }.openDownloadsManager { + verifyEmptyDownloadsList() + } + } + + @SmokeTest + @Test + /* Verifies downloads in the Downloads Menu: + - downloads appear in the list + - deleting a download from device storage, removes it from the Downloads Menu too + */ + fun manageDownloadsInDownloadsMenuTest() { + // a long filename to verify it's correctly displayed on the prompt and in the Downloads menu + downloadFile = "tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFt.svg" + + navigationToolbar { + }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { + }.clickDownloadLink(downloadFile) { + verifyDownloadPrompt(downloadFile) + }.clickDownload { + verifyDownloadNotificationPopup() + } + browserScreen { + }.openThreeDotMenu { + }.openDownloadsManager { + waitForDownloadsListToExist() + verifyDownloadedFileName(downloadFile) + verifyDownloadedFileIcon() + openDownloadedFile(downloadFile) + verifyPhotosAppOpens() + mDevice.pressBack() + deleteDownloadFromStorage(downloadFile) + }.exitDownloadsManagerToBrowser { + }.openThreeDotMenu { + }.openDownloadsManager { + verifyEmptyDownloadsList() + } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt index ac17093b225b..2a802f17eb38 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt @@ -66,7 +66,7 @@ class MediaNotificationTest { assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) }.openNotificationShade { verifySystemNotificationExists(videoTestPage.title) - clickMediaSystemNotificationControlButton("Pause") + clickSystemNotificationControlButton("Pause") verifyMediaSystemNotificationButtonState("Play") } @@ -101,7 +101,7 @@ class MediaNotificationTest { assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) }.openNotificationShade { verifySystemNotificationExists("A site is playing media") - clickMediaSystemNotificationControlButton("Pause") + clickSystemNotificationControlButton("Pause") verifyMediaSystemNotificationButtonState("Play") } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index f15a177990eb..8265ffbb8490 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -32,12 +32,10 @@ import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestAssetHelper.downloadFileName import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.appName import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.TestHelper.createCustomTabIntent -import org.mozilla.fenix.helpers.TestHelper.deleteDownloadFromStorage import org.mozilla.fenix.helpers.TestHelper.isPackageInstalled import org.mozilla.fenix.helpers.TestHelper.returnToBrowser import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText @@ -46,7 +44,6 @@ import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickTabCrashedRestoreButton import org.mozilla.fenix.ui.robots.collectionRobot import org.mozilla.fenix.ui.robots.customTabScreen -import org.mozilla.fenix.ui.robots.downloadRobot import org.mozilla.fenix.ui.robots.enhancedTrackingProtection import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar @@ -133,8 +130,6 @@ class SmokeTest { IdlingRegistry.getInstance().unregister(recentlyClosedTabsListIdlingResource!!) } - deleteDownloadFromStorage(downloadFileName) - if (bookmarksListIdlingResource != null) { IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!) } @@ -734,40 +729,6 @@ class SmokeTest { } } - @Test - /* Verifies downloads in the Downloads Menu: - - downloads appear in the list - - deleting a download from device storage, removes it from the Downloads Menu too - */ - fun manageDownloadsInDownloadsMenuTest() { - val downloadWebPage = TestAssetHelper.getDownloadAsset(mockWebServer) - - navigationToolbar { - }.enterURLAndEnterToBrowser(downloadWebPage.url) { - mDevice.waitForIdle() - } - - downloadRobot { - verifyDownloadPrompt() - }.clickDownload { - mDevice.waitForIdle() - verifyDownloadNotificationPopup() - } - - browserScreen { - }.openThreeDotMenu { - }.openDownloadsManager { - waitForDownloadsListToExist() - verifyDownloadedFileName(downloadFileName) - verifyDownloadedFileIcon() - deleteDownloadFromStorage(downloadFileName) - }.exitDownloadsManagerToBrowser { - }.openThreeDotMenu { - }.openDownloadsManager { - verifyEmptyDownloadsList() - } - } - @Test fun createFirstCollectionTest() { // disabling these features to have better visibility of Collections @@ -1243,7 +1204,7 @@ class SmokeTest { assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) }.openNotificationShade { verifySystemNotificationExists(audioTestPage.title) - clickMediaSystemNotificationControlButton("Pause") + clickSystemNotificationControlButton("Pause") verifyMediaSystemNotificationButtonState("Play") } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index 24debb7c9253..0c019b535800 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -19,7 +19,6 @@ import androidx.test.espresso.intent.matcher.BundleMatchers import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.matcher.RootMatchers.isDialog import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility @@ -305,14 +304,6 @@ class BrowserRobot { }.bookmarkPage { } } - fun clickLinkMatchingText(expectedText: String) { - val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mDevice.waitNotNull(Until.findObject(text(expectedText)), waitingTime) - - val element = mDevice.findObject(text(expectedText)) - element.click() - } - fun longClickMatchingText(expectedText: String) { try { mDevice.waitForWindowUpdate(packageName, waitingTime) @@ -651,6 +642,19 @@ class BrowserRobot { ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() } + + fun clickDownloadLink(title: String, interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { + val downloadLink = mDevice.findObject(UiSelector().textContains(title)) + + assertTrue( + "$title download link not found", + downloadLink.waitForExists(waitingTime) + ) + downloadLink.click() + + DownloadRobot().interact() + return DownloadRobot.Transition() + } } } @@ -666,9 +670,9 @@ fun searchBar() = onView(withId(R.id.mozac_browser_toolbar_url_view)) fun homeScreenButton() = onView(withContentDescription(R.string.browser_toolbar_home)) private fun assertHomeScreenButton() = - homeScreenButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + homeScreenButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) -private fun assertSearchBar() = searchBar().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +private fun assertSearchBar() = searchBar().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) private fun assertNavURLBar() = assertTrue(navURLBar().waitForExists(waitingTime)) @@ -676,14 +680,14 @@ private fun assertNavURLBarHidden() = assertTrue(navURLBar().waitUntilGone(waiti private fun assertSecureConnectionLockIcon() { onView(withId(R.id.mozac_browser_toolbar_security_indicator)) - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) } private fun menuButton() = onView(withId(R.id.icon)) private fun assertMenuButton() { menuButton() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) } private fun tabsCounter() = mDevice.findObject(By.res("$packageName:id/counter_root")) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt index 17057bc868c2..5687dcb7cc14 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt @@ -12,7 +12,6 @@ import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.matcher.RootMatchers.isDialog -import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withId @@ -26,7 +25,6 @@ import org.hamcrest.CoreMatchers import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS -import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens @@ -40,15 +38,18 @@ import org.mozilla.fenix.helpers.ext.waitNotNull class DownloadRobot { - fun verifyDownloadPrompt() = assertDownloadPrompt() + fun verifyDownloadPrompt(fileName: String) = assertDownloadPrompt(fileName) fun verifyDownloadNotificationPopup() = assertDownloadNotificationPopup() fun verifyPhotosAppOpens() = assertExternalAppOpens(GOOGLE_APPS_PHOTOS) fun verifyDownloadedFileName(fileName: String) { - mDevice.findObject(UiSelector().text(fileName)).waitForExists(waitingTime) - downloadedFile(fileName).check(matches(isDisplayed())) + assertTrue( + "$fileName not found in Downloads list", + mDevice.findObject(UiSelector().text(fileName)) + .waitForExists(waitingTime) + ) } fun verifyDownloadedFileIcon() = assertDownloadedFileIcon() @@ -61,13 +62,20 @@ class DownloadRobot { fun waitForDownloadsListToExist() = assertTrue( + "Downloads list either empty or not displayed", mDevice.findObject(UiSelector().resourceId("$packageName:id/download_list")) .waitForExists(waitingTime) ) + fun openDownloadedFile(fileName: String) { + downloadedFile(fileName) + .check(matches(isDisplayed())) + .click() + } + class Transition { fun clickDownload(interact: DownloadRobot.() -> Unit): Transition { - clickDownloadButton().click() + downloadButton().click() DownloadRobot().interact() return Transition() @@ -81,7 +89,7 @@ class DownloadRobot { } fun clickOpen(type: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - clickOpenButton().click() + openDownloadButton().click() // verify open intent is matched with associated data type Intents.intended( @@ -100,7 +108,7 @@ class DownloadRobot { mDevice.waitNotNull( Until.findObject(By.res(TestHelper.getPermissionAllowID() + ":id/permission_allow_button")), - TestAssetHelper.waitingTime + waitingTime ) val allowPermissionButton = mDevice.findObject(By.res(TestHelper.getPermissionAllowID() + ":id/permission_allow_button")) @@ -124,30 +132,54 @@ fun downloadRobot(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition return DownloadRobot.Transition() } -private fun assertDownloadPrompt() { - mDevice.waitNotNull(Until.findObjects(By.res("$packageName:id/download_button"))) +private fun assertDownloadPrompt(fileName: String) { + assertTrue( + "Download prompt button not visible", + mDevice.findObject(UiSelector().resourceId("$packageName:id/download_button")) + .waitForExists(waitingTime) + ) + assertTrue( + "$fileName title doesn't match", + mDevice.findObject(UiSelector().text(fileName)) + .waitForExists(waitingTime) + ) } private fun assertDownloadNotificationPopup() { - val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mDevice.waitNotNull(Until.findObjects(By.text("Open")), TestAssetHelper.waitingTime) - onView(withId(R.id.download_dialog_title)) - .check(matches(withText(CoreMatchers.containsString("Download completed")))) - onView(withId(R.id.download_dialog_filename)) - .check(matches(ViewMatchers.isCompletelyDisplayed())) + assertTrue( + "Download notification Open button not found", + mDevice.findObject(UiSelector().text("Open")) + .waitForExists(waitingTime) + ) + assertTrue( + "Download completed notification text doesn't match", + mDevice.findObject(UiSelector().textContains("Download completed")) + .waitForExists(waitingTime) + ) + assertTrue( + "Downloaded file name not visible", + mDevice.findObject(UiSelector().resourceId("$packageName:id/download_dialog_filename")) + .waitForExists(waitingTime) + ) } private fun closePromptButton() = - onView(withId(R.id.close_button)).inRoot(isDialog()).check(matches(isDisplayed())) + onView(withContentDescription("Close")) -private fun clickDownloadButton() = - onView(withText("Download")).inRoot(isDialog()).check(matches(isDisplayed())) +private fun downloadButton() = + onView(withText("Download")) + .inRoot(isDialog()) + .check(matches(isDisplayed())) -private fun clickOpenButton() = - onView(withId(R.id.download_dialog_action_button)).check( - matches(isDisplayed()) - ) +private fun openDownloadButton() = + onView(withId(R.id.download_dialog_action_button)) + .check(matches(isDisplayed())) private fun downloadedFile(fileName: String) = onView(withText(fileName)) -private fun assertDownloadedFileIcon() = onView(withId(R.id.favicon)).check(matches(isDisplayed())) +private fun assertDownloadedFileIcon() = + assertTrue( + "Downloaded file icon not found", + mDevice.findObject(UiSelector().resourceId("$packageName:id/favicon")) + .exists() + ) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt index 18bd75ee3f09..57d1eade7b31 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt @@ -12,15 +12,12 @@ import androidx.test.uiautomator.Until import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime +import org.mozilla.fenix.helpers.TestHelper.appName import org.mozilla.fenix.helpers.ext.waitNotNull class NotificationRobot { fun verifySystemNotificationExists(notificationMessage: String) { - fun notificationTray() = UiScrollable( - UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller") - ) - var notificationFound = false do { @@ -54,13 +51,20 @@ class NotificationRobot { assertPrivateTabsNotification() } - fun clickMediaSystemNotificationControlButton(action: String) { + fun clickSystemNotificationControlButton(action: String) { mediaSystemNotificationButton(action).waitForExists(waitingTime) mediaSystemNotificationButton(action).click() } fun verifyMediaSystemNotificationButtonState(action: String) { - mediaSystemNotificationButton(action).waitForExists(waitingTime) + assertTrue(mediaSystemNotificationButton(action).waitForExists(waitingTime)) + } + + fun expandNotificationMessage() { + while (!notificationHeader.exists()) { + notificationTray().scrollForward() + } + notificationHeader.click() } class Transition { @@ -94,3 +98,14 @@ private fun mediaSystemNotificationButton(action: String) = .resourceId("android:id/action0") .descriptionContains(action) ) + +private fun notificationTray() = UiScrollable( + UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller") +) + +private val notificationHeader = + mDevice.findObject( + UiSelector() + .resourceId("android:id/app_name_text") + .text(appName) + )