diff --git a/app/src/androidTest/assets/pages/generic4.html b/app/src/androidTest/assets/pages/generic4.html
new file mode 100644
index 0000000000..78a55d22b0
--- /dev/null
+++ b/app/src/androidTest/assets/pages/generic4.html
@@ -0,0 +1,19 @@
+
+
+ Test_Page_4
+
+
+ Page content: 4
+ Link 1
+ Link 2
+ Link 3
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/androidTest/assets/resources/rabbit.jpg b/app/src/androidTest/assets/resources/rabbit.jpg
new file mode 100644
index 0000000000..3225407b1c
Binary files /dev/null and b/app/src/androidTest/assets/resources/rabbit.jpg differ
diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt
index b83e20a724..a14d459d3a 100644
--- a/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt
+++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/Constants.kt
@@ -4,5 +4,10 @@ object Constants {
object PackageName {
const val GOOGLE_PLAY_SERVICES = "com.android.vending"
+ const val GOOGLE_APPS_PHOTOS = "com.google.android.apps.photos"
+ }
+
+ object LongClickDuration {
+ const val LONG_CLICK_DURATION: Long = 5000
}
}
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 e2fc730277..be77243966 100644
--- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt
+++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt
@@ -30,7 +30,7 @@ object TestAssetHelper {
*/
fun getGenericAssets(server: MockWebServer): List {
@Suppress("MagicNumber")
- return (1..3).map {
+ return (1..4).map {
TestAsset(
server.url("pages/generic$it.html").toString().toUri()!!,
"Page content: $it"
@@ -77,4 +77,10 @@ object TestAssetHelper {
return TestAsset(url, "")
}
+
+ fun getImageAsset(server: MockWebServer): TestAsset {
+ val url = server.url("resources/rabbit.jpg").toString().toUri()!!
+
+ return TestAsset(url, "")
+ }
}
diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt
index b671cd4d73..d82f47731b 100644
--- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt
+++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt
@@ -4,7 +4,10 @@
package org.mozilla.fenix.helpers
+import android.content.Context
import android.net.Uri
+import android.os.Build
+import android.preference.PreferenceManager
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.longClick
import androidx.test.espresso.matcher.ViewMatchers.withId
@@ -17,8 +20,6 @@ import org.hamcrest.CoreMatchers.allOf
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.ext.waitNotNull
import org.mozilla.fenix.ui.robots.mDevice
-import android.preference.PreferenceManager
-import android.content.Context
object TestHelper {
fun scrollToElementByText(text: String): UiScrollable {
@@ -46,4 +47,12 @@ object TestHelper {
editor.putInt(pref, value)
editor.apply()
}
+
+ fun getPermissionAllowID(): String {
+ return when
+ (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
+ true -> "com.android.permissioncontroller"
+ false -> "com.android.packageinstaller"
+ }
+ }
}
diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt
new file mode 100644
index 0000000000..1c6da38439
--- /dev/null
+++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt
@@ -0,0 +1,220 @@
+/* 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.test.platform.app.InstrumentationRegistry
+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.HomeActivityIntentTestRule
+import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.ui.robots.downloadRobot
+import org.mozilla.fenix.ui.robots.navigationToolbar
+
+/**
+ * Tests for verifying basic functionality of content context menus
+ *
+ * - Verifies long click "Open link in new tab" UI and functionality
+ * - Verifies long click "Open link in new Private tab" UI and functionality
+ * - Verifies long click "Copy Link" UI and functionality
+ * - Verifies long click "Share Link" UI and functionality
+ * - Verifies long click "Open image in new tab" UI and functionality
+ * - Verifies long click "Save Image" UI and functionality
+ * - Verifies long click "Copy image location" UI and functionality
+ * - Verifies long click items of mixed hypertext items
+ *
+ */
+
+class ContextMenusTest {
+ private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ private lateinit var mockWebServer: MockWebServer
+
+ @get:Rule
+ val activityIntentTestRule = HomeActivityIntentTestRule()
+
+ @Before
+ fun setUp() {
+ mockWebServer = MockWebServer().apply {
+ setDispatcher(AndroidAssetDispatcher())
+ start()
+ }
+ }
+
+ @After
+ fun tearDown() {
+ mockWebServer.shutdown()
+ }
+
+ @Test
+ fun verifyContextOpenLinkNewTab() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val genericURL =
+ TestAssetHelper.getGenericAsset(mockWebServer, 1)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("Link 1")
+ verifyLinkContextMenuItems(genericURL.url)
+ clickContextOpenLinkInNewTab()
+ verifySnackBarText("New tab opened")
+ snackBarButtonClick("Switch")
+ verifyUrl(genericURL.url.toString())
+ }.openHomeScreen {
+ verifyHomeScreen()
+ verifyExistingOpenTabs("Test_Page_1")
+ verifyExistingOpenTabs("Test_Page_4")
+ }
+ }
+
+ @Test
+ fun verifyContextOpenLinkPrivateTab() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val genericURL =
+ TestAssetHelper.getGenericAsset(mockWebServer, 2)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("Link 2")
+ verifyLinkContextMenuItems(genericURL.url)
+ clickContextOpenLinkInPrivateTab()
+ verifySnackBarText("New private tab opened")
+ snackBarButtonClick("Switch")
+ verifyUrl(genericURL.url.toString())
+ }.openHomeScreen {
+ verifyPrivateSessionHeader()
+ verifyExistingOpenTabs("Test_Page_2")
+ }
+ }
+
+ @Test
+ fun verifyContextCopyLink() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val genericURL =
+ TestAssetHelper.getGenericAsset(mockWebServer, 3)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("Link 3")
+ verifyLinkContextMenuItems(genericURL.url)
+ clickContextCopyLink()
+ verifySnackBarText("Link copied to clipboard")
+ }.openNavigationToolbar {
+ }.visitLinkFromClipboard(genericURL.url) {
+ verifyUrl(genericURL.url.toString())
+ }
+ }
+
+ @Test
+ fun verifyContextShareLink() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val genericURL =
+ TestAssetHelper.getGenericAsset(mockWebServer, 1)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("Link 1")
+ verifyLinkContextMenuItems(genericURL.url)
+ clickContextShareLink(genericURL.url) // verify share intent is matched with associated URL
+ }
+ }
+
+ @Test
+ fun verifyContextOpenImageNewTab() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val imageResource =
+ TestAssetHelper.getImageAsset(mockWebServer)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("test_link_image")
+ verifyLinkImageContextMenuItems(imageResource.url)
+ clickContextOpenImageNewTab()
+ verifySnackBarText("New tab opened")
+ snackBarButtonClick("Switch")
+ verifyUrl(imageResource.url.toString())
+ }
+ }
+
+ @Test
+ fun verifyContextCopyImageLocation() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val imageResource =
+ TestAssetHelper.getImageAsset(mockWebServer)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("test_link_image")
+ verifyLinkImageContextMenuItems(imageResource.url)
+ clickContextCopyImageLocation()
+ verifySnackBarText("Link copied to clipboard")
+ }.openNavigationToolbar {
+ }.visitLinkFromClipboard(imageResource.url) {
+ verifyUrl(imageResource.url.toString())
+ }
+ }
+
+ @Test
+ fun verifyContextSaveImage() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val imageResource =
+ TestAssetHelper.getImageAsset(mockWebServer)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("test_link_image")
+ verifyLinkImageContextMenuItems(imageResource.url)
+ clickContextSaveImage()
+ }
+
+ downloadRobot {
+ }.clickAllowPermission {
+ verifyDownloadNotificationPopup()
+ }.clickOpen("image/jpeg") {} // verify open intent is matched with associated data type
+ downloadRobot {
+ verifyPhotosAppOpens()
+ }
+ }
+
+ @Test
+ fun verifyContextMixedVariations() {
+ val pageLinks =
+ TestAssetHelper.getGenericAsset(mockWebServer, 4)
+ val genericURL =
+ TestAssetHelper.getGenericAsset(mockWebServer, 1)
+ val imageResource =
+ TestAssetHelper.getImageAsset(mockWebServer)
+
+ navigationToolbar {
+ }.enterURLAndEnterToBrowser(pageLinks.url) {
+ verifyPageContent(pageLinks.content)
+ longClickMatchingText("Link 1")
+ verifyLinkContextMenuItems(genericURL.url)
+ mDevice.pressBack()
+ longClickMatchingText("test_link_image")
+ verifyLinkImageContextMenuItems(imageResource.url)
+ mDevice.pressBack()
+ longClickMatchingText("test_no_link_image")
+ verifyNoLinkImageContextMenuItems("test_no_link_image")
+ }
+ }
+}
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 b99c968038..b0964dea34 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
@@ -6,10 +6,14 @@
package org.mozilla.fenix.ui.robots
+import android.content.Intent
import android.net.Uri
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.intent.Intents
+import androidx.test.espresso.intent.matcher.BundleMatchers
+import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withId
@@ -19,11 +23,13 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers
+import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
+import org.mozilla.fenix.helpers.Constants.LongClickDuration
class BrowserRobot {
@@ -34,7 +40,10 @@ class BrowserRobot {
fun verifyUrl(redirectUrl: String) {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/mozac_browser_toolbar_url_view")), TestAssetHelper.waitingTime)
+ mDevice.waitNotNull(
+ Until.findObject(By.res("org.mozilla.fenix.debug:id/mozac_browser_toolbar_url_view")),
+ TestAssetHelper.waitingTime
+ )
onView(withId(R.id.mozac_browser_toolbar_url_view))
.check(matches(withText(containsString(redirectUrl))))
}
@@ -64,9 +73,157 @@ class BrowserRobot {
.check((matches(withText(containsString(expectedText)))))
}
+ fun verifySnackBarText(expectedText: String) {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(Until.findObject(By.text(expectedText)), TestAssetHelper.waitingTime)
+ }
+
+ fun verifyLinkContextMenuItems(containsURL: Uri) {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(
+ Until.findObject(By.textContains(containsURL.toString())),
+ TestAssetHelper.waitingTime
+ )
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open link in new tab")),
+ TestAssetHelper.waitingTime
+ )
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open link in private tab")),
+ TestAssetHelper.waitingTime
+ )
+ mDevice.waitNotNull(Until.findObject(By.text("Copy link")), TestAssetHelper.waitingTime)
+ mDevice.waitNotNull(Until.findObject(By.text("Share link")), TestAssetHelper.waitingTime)
+ }
+
+ fun verifyLinkImageContextMenuItems(containsURL: Uri) {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(Until.findObject(By.textContains(containsURL.toString())))
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open link in new tab")), TestAssetHelper.waitingTime
+ )
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open link in private tab")), TestAssetHelper.waitingTime
+ )
+ mDevice.waitNotNull(Until.findObject(By.text("Copy link")), TestAssetHelper.waitingTime)
+ mDevice.waitNotNull(Until.findObject(By.text("Share link")), TestAssetHelper.waitingTime)
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open image in new tab")), TestAssetHelper.waitingTime
+ )
+ mDevice.waitNotNull(Until.findObject(By.text("Save image")), TestAssetHelper.waitingTime)
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Copy image location")), TestAssetHelper.waitingTime
+ )
+ }
+
+ fun verifyNoLinkImageContextMenuItems(containsTitle: String) {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(Until.findObject(By.textContains(containsTitle)))
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open image in new tab")),
+ TestAssetHelper.waitingTime
+ )
+ mDevice.waitNotNull(Until.findObject(By.text("Save image")), TestAssetHelper.waitingTime)
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Copy image location")), TestAssetHelper.waitingTime
+ )
+ }
+
+ fun clickContextOpenLinkInNewTab() {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open link in new tab")),
+ TestAssetHelper.waitingTime
+ )
+
+ val menuOpenInNewTab = mDevice.findObject(By.text("Open link in new tab"))
+ menuOpenInNewTab.click()
+ }
+
+ fun clickContextOpenLinkInPrivateTab() {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open link in private tab")),
+ TestAssetHelper.waitingTime
+ )
+
+ val menuOpenInPrivateTab = mDevice.findObject(By.text("Open link in private tab"))
+ menuOpenInPrivateTab.click()
+ }
+
+ fun clickContextCopyLink() {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(Until.findObject(By.text("Copy link")), TestAssetHelper.waitingTime)
+
+ val menuCopyLink = mDevice.findObject(By.text("Copy link"))
+ menuCopyLink.click()
+ }
+
+ fun clickContextShareLink(url: Uri) {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(Until.findObject(By.text("Share link")), TestAssetHelper.waitingTime)
+
+ val menuShareLink = mDevice.findObject(By.text("Share link"))
+ menuShareLink.click()
+
+ // verify share intent is launched and matched with associated passed in URL
+ Intents.intended(
+ allOf(
+ IntentMatchers.hasAction(Intent.ACTION_CHOOSER),
+ IntentMatchers.hasExtras(
+ allOf(
+ BundleMatchers.hasEntry(
+ Intent.EXTRA_INTENT,
+ allOf(
+ IntentMatchers.hasAction(Intent.ACTION_SEND),
+ IntentMatchers.hasType("text/plain"),
+ IntentMatchers.hasExtra(
+ Intent.EXTRA_TEXT,
+ url.toString()
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ }
+
+ fun clickContextCopyImageLocation() {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Copy image location")),
+ TestAssetHelper.waitingTime
+ )
+
+ val menuCopyImageLocation = mDevice.findObject(By.text("Copy image location"))
+ menuCopyImageLocation.click()
+ }
+
+ fun clickContextOpenImageNewTab() {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Open image in new tab")),
+ TestAssetHelper.waitingTime
+ )
+
+ val menuOpenImageNewTab = mDevice.findObject(By.text("Open image in new tab"))
+ menuOpenImageNewTab.click()
+ }
+
+ fun clickContextSaveImage() {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(Until.findObject(By.text("Save image")), TestAssetHelper.waitingTime)
+
+ val menuSaveImage = mDevice.findObject(By.text("Save image"))
+ menuSaveImage.click()
+ }
+
fun waitForCollectionSavedPopup() {
- mDevice.wait(Until.findObject(By.text("Tab saved!")),
- TestAssetHelper.waitingTime)
+ mDevice.wait(
+ Until.findObject(By.text("Tab saved!")),
+ TestAssetHelper.waitingTime
+ )
}
fun createBookmark(url: Uri) {
@@ -85,6 +242,20 @@ class BrowserRobot {
element.click()
}
+ fun longClickMatchingText(expectedText: String) {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(Until.findObject(By.text(expectedText)), TestAssetHelper.waitingTime)
+
+ val element = mDevice.findObject(By.text(expectedText))
+ element.click(LongClickDuration.LONG_CLICK_DURATION)
+ }
+
+ fun snackBarButtonClick(expectedText: String) {
+ onView(allOf(withId(R.id.snackbar_btn), withText(expectedText))).check(
+ matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))
+ ).perform(ViewActions.click())
+ }
+
class Transition {
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private fun threeDotButton() = onView(
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 531084fe1a..5d8d2a2bfb 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
@@ -6,12 +6,15 @@
package org.mozilla.fenix.ui.robots
+import android.content.Intent
import androidx.test.espresso.Espresso.onView
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.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
@@ -19,8 +22,10 @@ import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
+import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS
/**
* Implementation of Robot Pattern for download UI handling.
@@ -34,13 +39,15 @@ class DownloadRobot {
fun verifyDownloadNotificationShade() = assertDownloadNotificationShade()
+ fun verifyPhotosAppOpens() = assertPhotosOpens()
+
class Transition {
- fun clickDownload(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition {
+ fun clickDownload(interact: DownloadRobot.() -> Unit): Transition {
clickDownloadButton().click()
DownloadRobot().interact()
- return DownloadRobot.Transition()
+ return Transition()
}
fun closePrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
@@ -49,6 +56,36 @@ class DownloadRobot {
BrowserRobot().interact()
return BrowserRobot.Transition()
}
+
+ fun clickOpen(type: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
+ clickOpenButton().click()
+
+ // verify open intent is matched with associated data type
+ Intents.intended(
+ CoreMatchers.allOf(
+ IntentMatchers.hasAction(Intent.ACTION_VIEW),
+ IntentMatchers.hasType(type)
+ )
+ )
+
+ BrowserRobot().interact()
+ return BrowserRobot.Transition()
+ }
+
+ fun clickAllowPermission(interact: DownloadRobot.() -> Unit): Transition {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+ mDevice.waitNotNull(
+ Until.findObject(By.res(TestHelper.getPermissionAllowID() + ":id/permission_allow_button")),
+ TestAssetHelper.waitingTime
+ )
+
+ val allowPermissionButton = mDevice.findObject(By.res(TestHelper.getPermissionAllowID() + ":id/permission_allow_button"))
+ allowPermissionButton.click()
+
+ DownloadRobot().interact()
+ return Transition()
+ }
}
}
@@ -84,3 +121,20 @@ private fun closePromptButton() =
private fun clickDownloadButton() =
onView(withText("Download")).inRoot(isDialog()).check(matches(isDisplayed()))
+
+private fun clickOpenButton() =
+ onView(withId(R.id.download_notification_action_button)).inRoot(isDialog()).check(
+ matches(isDisplayed())
+ )
+
+private fun assertPhotosOpens() {
+ if (isPackageInstalled(GOOGLE_APPS_PHOTOS)) {
+ Intents.intended(IntentMatchers.toPackage(GOOGLE_APPS_PHOTOS))
+ } else {
+ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ mDevice.waitNotNull(
+ Until.findObject(By.text("Could not open file")),
+ TestAssetHelper.waitingTime
+ )
+ }
+}
diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt
index feda6ba00c..aa2f264fe9 100644
--- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt
+++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt
@@ -6,11 +6,13 @@
package org.mozilla.fenix.ui.robots
+import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
@@ -82,6 +84,7 @@ class HomeScreenRobot {
fun verifyCloseTabsButton(visible: Boolean = true) = assertCloseTabsButton(visible)
fun verifyExistingTabList() = assertExistingTabList()
+ fun verifyExistingOpenTabs(title: String) = assertExistingOpenTabs(title)
// Collections element
fun clickCollectionThreeDotButton() {
@@ -361,6 +364,13 @@ private fun assertExistingTabList() =
onView(CoreMatchers.allOf(withId(R.id.item_tab)))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+private fun assertExistingOpenTabs(title: String) =
+ onView(withId(R.id.home_component)).perform(
+ RecyclerViewActions.scrollTo(
+ ViewMatchers.hasDescendant(withText(title))
+ )
+ ).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
private fun tabsListThreeDotButton() = onView(allOf(withId(R.id.tabs_overflow_button)))
private fun collectionThreeDotButton() = onView(allOf(withId(R.id.collection_overflow_button)))
diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt
index bc923adbae..4f5e6f4005 100644
--- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt
+++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt
@@ -53,6 +53,27 @@ class NavigationToolbarRobot {
BrowserRobot().interact()
return BrowserRobot.Transition()
}
+
+ fun visitLinkFromClipboard(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
+ mDevice.waitNotNull(
+ Until.findObject(By.res("org.mozilla.fenix.debug:id/mozac_browser_toolbar_clear_view")),
+ waitingTime
+ )
+ clearAddressBar().click()
+
+ mDevice.waitNotNull(
+ Until.findObject(By.text(url.toString())), waitingTime
+ )
+
+ mDevice.waitNotNull(
+ Until.findObject(By.res("org.mozilla.fenix.debug:id/fill_link_from_clipboard")),
+ waitingTime
+ )
+ fillLinkButton().click()
+
+ BrowserRobot().interact()
+ return BrowserRobot.Transition()
+ }
}
}
@@ -66,3 +87,5 @@ private fun urlBar() = onView(ViewMatchers.withId(R.id.toolbar))
private fun awesomeBar() = onView(ViewMatchers.withId(R.id.mozac_browser_toolbar_edit_url_view))
private fun threeDotButton() = onView(ViewMatchers.withContentDescription("Menu"))
private fun newTab() = onView(ViewMatchers.withContentDescription("Add tab"))
+private fun fillLinkButton() = onView(ViewMatchers.withId(R.id.fill_link_from_clipboard))
+private fun clearAddressBar() = onView(ViewMatchers.withId(R.id.mozac_browser_toolbar_clear_view))