From c86683fb9e6e147e2d4faeead8a210a20c55e3f0 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Wed, 24 Nov 2021 15:12:26 +0200 Subject: [PATCH] For #21002: improves the share tabs smoke tests coverage --- .../org/mozilla/fenix/ui/ContextMenusTest.kt | 13 +++ .../org/mozilla/fenix/ui/ShareButtonTest.kt | 65 ------------- .../java/org/mozilla/fenix/ui/SmokeTest.kt | 64 ++++++++----- .../mozilla/fenix/ui/robots/BrowserRobot.kt | 8 ++ .../fenix/ui/robots/CollectionRobot.kt | 9 +- .../fenix/ui/robots/HomeScreenRobot.kt | 9 -- .../mozilla/fenix/ui/robots/SearchRobot.kt | 2 +- .../fenix/ui/robots/ShareOverlayRobot.kt | 91 +++++++++++++++++++ .../fenix/ui/robots/ThreeDotMenuMainRobot.kt | 49 +++------- 9 files changed, 177 insertions(+), 133 deletions(-) delete mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/ShareButtonTest.kt create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt index 89dfaecf1335..c663649aa083 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -222,4 +222,17 @@ class ContextMenusTest { verifyNoLinkImageContextMenuItems(imageResource.url) } } + + @SmokeTest + @Test + fun shareSelectedTextTest() { + val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(genericURL.url) { + longClickMatchingText(genericURL.content) + }.clickShareSelectedText { + verifyAndroidShareLayout() + } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ShareButtonTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ShareButtonTest.kt deleted file mode 100644 index 2329bde05002..000000000000 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ShareButtonTest.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* 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.HomeActivityTestRule -import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.ui.robots.navigationToolbar - -/** - * Tests for verifying basic functionality of history - * - */ - -class ShareButtonTest { - /* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping. - - private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - private lateinit var mockWebServer: MockWebServer - - @get:Rule - val activityTestRule = HomeActivityTestRule() - - @Before - fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - - @Test - fun ShareButtonAppearanceTest() { - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) - - // - Visit a URL, wait until it's loaded - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() - } - - // From the 3-dot menu next to the Select share menu - navigationToolbar { - }.openThreeDotMenu { - clickShareButton() - verifyShareScrim() - verifySendToDeviceTitle() - verifyShareALinkTitle() - } - } -} 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 c778e3d35e30..e50f2696ba3b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -417,8 +417,10 @@ class SmokeTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.sharePage { - verifyShareAppsLayout() + }.clickShareButton { + verifyShareTabLayout() + verifySendToDeviceTitle() + verifyShareALinkTitle() } } @@ -879,22 +881,28 @@ class SmokeTest { @Test fun shareCollectionTest() { - val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) + val sharingApp = "Gmail" + val urlString = "${secondWebsite.url}\n\n${firstWebsite.url}" navigationToolbar { - }.enterURLAndEnterToBrowser(webPage.url) { + }.enterURLAndEnterToBrowser(firstWebsite.url) { + verifyPageContent(firstWebsite.content) }.openTabDrawer { - createCollection(webPage.title, collectionName) - snackBarButtonClick("VIEW") - } - - homeScreen { + createCollection(firstWebsite.title, collectionName) + }.openNewTab { + }.submitQuery(secondWebsite.url.toString()) { + verifyPageContent(secondWebsite.content) + }.openThreeDotMenu { + }.openSaveToCollection { + }.selectExistingCollection(collectionName) { + }.goToHomescreen { }.expandCollection(collectionName) { - clickShareCollectionButton() - } - - homeScreen { - verifyShareTabsOverlay() + }.clickShareCollectionButton { + verifyShareTabsOverlay(firstWebsite.title, secondWebsite.title) + selectAppToShareWith(sharingApp) + verifySharedTabsIntent(urlString, collectionName) } } @@ -964,21 +972,33 @@ class SmokeTest { @Test fun shareTabsFromTabsTrayTest() { - val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) + val firstWebsiteTitle = firstWebsite.title + val secondWebsiteTitle = secondWebsite.title + val sharingApp = "Gmail" + val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" homeScreen { }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(website.url) { - mDevice.waitForIdle() + }.enterURLAndEnterToBrowser(firstWebsite.url) { + verifyPageContent(firstWebsite.content) + }.openTabDrawer { + }.openNewTab { + }.submitQuery(secondWebsite.url.toString()) { + verifyPageContent(secondWebsite.content) }.openTabDrawer { - verifyNormalModeSelected() - verifyExistingTabList() verifyExistingOpenTabs("Test_Page_1") - verifyTabTrayOverflowMenu(true) + verifyExistingOpenTabs("Test_Page_2") }.openTabsListThreeDotMenu { verifyShareAllTabsButton() - clickShareAllTabsButton() - verifyShareTabsOverlay() + }.clickShareAllTabsButton { + verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle) + selectAppToShareWith(sharingApp) + verifySharedTabsIntent( + sharedUrlsString, + "$firstWebsiteTitle, $secondWebsiteTitle" + ) } } 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 480db90a9251..6a6c389dfbd6 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 @@ -612,6 +612,14 @@ class BrowserRobot { HomeScreenRobot().interact() return HomeScreenRobot.Transition() } + + fun clickShareSelectedText(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + val shareTextButton = org.mozilla.fenix.ui.robots.mDevice.findObject(By.textContains("Share")) + shareTextButton.click() + + ShareOverlayRobot().interact() + return ShareOverlayRobot.Transition() + } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt index 60ddb1d03698..b5f881aec8d6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -94,8 +94,6 @@ class CollectionRobot { ) } - fun clickShareCollectionButton() = onView(withId(R.id.collection_share_button)).click() - fun verifyCollectionMenuIsVisible(visible: Boolean) { collectionThreeDotButton() .check( @@ -240,6 +238,13 @@ class CollectionRobot { BrowserRobot().interact() return BrowserRobot.Transition() } + + fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + shareCollectionButton().click() + + ShareOverlayRobot().interact() + return ShareOverlayRobot.Transition() + } } } 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 e6666c4e6fce..2f2529cfcfed 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 @@ -136,8 +136,6 @@ class HomeScreenRobot { fun verifyCollectionIcon() = onView(withId(R.id.collection_icon)).check(matches(isDisplayed())) - fun verifyShareTabsOverlay() = assertShareTabsOverlay() - fun togglePrivateBrowsingModeOnOff() { onView(ViewMatchers.withResourceName("privateBrowsingButton")) .perform(click()) @@ -584,13 +582,6 @@ private fun assertTopSiteContextMenuItems() { ) } -private fun assertShareTabsOverlay() { - onView(withId(R.id.shared_site_list)).check(matches(isDisplayed())) - onView(withId(R.id.share_tab_title)).check(matches(isDisplayed())) - onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed())) - onView(withId(R.id.share_tab_url)).check(matches(isDisplayed())) -} - private fun assertJumpBackInSectionIsDisplayed() = jumpBackInSection().check(matches(isDisplayed())) private fun assertJumpBackInSectionIsNotDisplayed() = jumpBackInSection().check(doesNotExist()) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt index abb4533b33e4..312d928bc64b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt @@ -214,7 +214,7 @@ class SearchRobot { fun submitQuery(query: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { sessionLoadedIdlingResource = SessionLoadedIdlingResource() - mDevice.waitForIdle() + searchWrapper().waitForExists(waitingTime) browserToolbarEditView().setText(query) mDevice.pressEnter() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt new file mode 100644 index 000000000000..430017015b31 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt @@ -0,0 +1,91 @@ +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.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.hasSibling +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withResourceName +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until +import org.hamcrest.Matchers.allOf +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.ext.waitNotNull + +class ShareOverlayRobot { + + // This function verifies the share layout when more than one tab is shared - a list of tabs is shown + fun verifyShareTabsOverlay(vararg tabsTitles: String) { + onView(withId(R.id.shared_site_list)) + .check(matches(isDisplayed())) + for (tabs in tabsTitles) { + onView(withText(tabs)) + .check( + matches( + allOf( + hasSibling(withId(R.id.share_tab_favicon)), + hasSibling(withId(R.id.share_tab_url)) + ) + ) + ) + } + } + + // This function verifies the share layout when a single tab is shared - no tab info shown + fun verifyShareTabLayout() = assertShareTabLayout() + + // this verifies the Android sharing layout - not customized for sharing tabs + fun verifyAndroidShareLayout() { + mDevice.waitNotNull(Until.findObject(By.res("android:id/resolver_list"))) + } + + fun selectAppToShareWith(appName: String) = + mDevice.findObject(UiSelector().text(appName)).clickAndWaitForNewWindow() + + fun verifySendToDeviceTitle() = assertSendToDeviceTitle() + + fun verifyShareALinkTitle() = assertShareALinkTitle() + + fun verifySharedTabsIntent(text: String, subject: String) { + Intents.intended( + allOf( + IntentMatchers.hasExtra(Intent.EXTRA_TEXT, text), + IntentMatchers.hasExtra(Intent.EXTRA_SUBJECT, subject) + ) + ) + } + + class Transition +} + +private fun shareTabsLayout() = onView(withResourceName("shareWrapper")) + +private fun assertShareTabLayout() = + shareTabsLayout().check(matches(isDisplayed())) + +private fun sendToDeviceTitle() = + onView( + allOf( + withText("SEND TO DEVICE"), + withResourceName("accountHeaderText") + ) + ) + +private fun assertSendToDeviceTitle() = sendToDeviceTitle() + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + +private fun shareALinkTitle() = + onView( + allOf( + withText("ALL ACTIONS"), + withResourceName("apps_link_header") + ) + ) + +private fun assertShareALinkTitle() = shareALinkTitle() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt index fb91e5296907..91b0ec1439f6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt @@ -21,7 +21,6 @@ import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withResourceName import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By @@ -37,7 +36,6 @@ import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.ext.waitNotNull -import org.mozilla.fenix.share.ShareFragment /** * Implementation of Robot Pattern for the three dot (main) menu. @@ -45,7 +43,6 @@ import org.mozilla.fenix.share.ShareFragment @Suppress("ForbiddenComment") class ThreeDotMenuMainRobot { fun verifyShareAllTabsButton() = assertShareAllTabsButton() - fun clickShareAllTabsButton() = shareAllTabsButton().click() fun verifySettingsButton() = assertSettingsButton() fun verifyCustomizeHomeButton() = assertCustomizeHomeButton() fun verifyAddOnsButton() = assertAddOnsButton() @@ -66,19 +63,11 @@ class ThreeDotMenuMainRobot { onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeUp()) } - fun clickShareButton() { - shareButton().click() - mDevice.waitNotNull(Until.findObject(By.text("ALL ACTIONS")), waitingTime) - } - fun verifyShareTabButton() = assertShareTabButton() fun verifySaveCollection() = assertSaveCollectionButton() fun verifySelectTabs() = assertSelectTabsButton() fun verifyFindInPageButton() = assertFindInPageButton() - fun verifyShareScrim() = assertShareScrim() - fun verifySendToDeviceTitle() = assertSendToDeviceTitle() - fun verifyShareALinkTitle() = assertShareALinkTitle() fun verifyWhatsNewButton() = assertWhatsNewButton() fun verifyAddToTopSitesButton() = assertAddToTopSitesButton() fun verifyAddToMobileHome() = assertAddToMobileHome() @@ -186,13 +175,6 @@ class ThreeDotMenuMainRobot { return BrowserRobot.Transition() } - fun sharePage(interact: LibrarySubMenusMultipleSelectionToolbarRobot.() -> Unit): LibrarySubMenusMultipleSelectionToolbarRobot.Transition { - shareButton().click() - - LibrarySubMenusMultipleSelectionToolbarRobot().interact() - return LibrarySubMenusMultipleSelectionToolbarRobot.Transition() - } - fun openHelp(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { mDevice.waitNotNull(Until.findObject(By.text("Help")), waitingTime) helpButton().click() @@ -235,6 +217,14 @@ class ThreeDotMenuMainRobot { return BrowserRobot.Transition() } + fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + shareButton().click() + mDevice.waitNotNull(Until.findObject(By.text("ALL ACTIONS")), waitingTime) + + ShareOverlayRobot().interact() + return ShareOverlayRobot.Transition() + } + fun close(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { // Close three dot mDevice.pressBack() @@ -364,6 +354,13 @@ class ThreeDotMenuMainRobot { BrowserRobot().interact() return BrowserRobot.Transition() } + + fun clickShareAllTabsButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + shareAllTabsButton().click() + + ShareOverlayRobot().interact() + return ShareOverlayRobot.Transition() + } } } private fun threeDotMenuRecyclerView() = @@ -454,22 +451,6 @@ private fun findInPageButton() = onView(allOf(withText("Find in page"))) private fun assertFindInPageButton() = findInPageButton() -private fun shareScrim() = onView(withResourceName("closeSharingScrim")) - -private fun assertShareScrim() = - shareScrim().check(matches(ViewMatchers.withAlpha(ShareFragment.SHOW_PAGE_ALPHA))) - -private fun SendToDeviceTitle() = - onView(allOf(withText("SEND TO DEVICE"), withResourceName("accountHeaderText"))) - -private fun assertSendToDeviceTitle() = SendToDeviceTitle() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun shareALinkTitle() = - onView(allOf(withText("ALL ACTIONS"), withResourceName("apps_link_header"))) - -private fun assertShareALinkTitle() = shareALinkTitle() - private fun whatsNewButton() = onView( allOf( withText("What’s New"),