1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 package org.mozilla.fenix.ui
7 import com.google.android.material.bottomsheet.BottomSheetBehavior
8 import mozilla.components.concept.engine.mediasession.MediaSession
11 import org.mozilla.fenix.customannotations.SmokeTest
12 import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
13 import org.mozilla.fenix.helpers.MatcherHelper
14 import org.mozilla.fenix.helpers.RetryTestRule
15 import org.mozilla.fenix.helpers.TestAssetHelper
16 import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
17 import org.mozilla.fenix.helpers.TestHelper.closeApp
18 import org.mozilla.fenix.helpers.TestHelper.mDevice
19 import org.mozilla.fenix.helpers.TestHelper.restartApp
20 import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
21 import org.mozilla.fenix.helpers.TestSetup
22 import org.mozilla.fenix.ui.robots.browserScreen
23 import org.mozilla.fenix.ui.robots.clickPageObject
24 import org.mozilla.fenix.ui.robots.homeScreen
25 import org.mozilla.fenix.ui.robots.navigationToolbar
26 import org.mozilla.fenix.ui.robots.notificationShade
29 * Tests for verifying basic functionality of tabbed browsing
33 * - Opening a private tab
34 * - Verifying tab list
37 * - Swipe to close tab (temporarily disabled)
39 * - Close private tabs persistent notification
40 * - Empty tab tray state
42 * - Shortcut context menu navigation
45 class TabbedBrowsingTest : TestSetup() {
47 val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
51 val retryTestRule = RetryTestRule(3)
53 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903599
55 fun closeAllTabsTest() {
56 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
59 }.enterURLAndEnterToBrowser(defaultWebPage.url) {
61 verifyExistingTabList()
62 }.openTabsListThreeDotMenu {
63 verifyCloseAllTabsButton()
64 verifyShareTabButton()
70 // Repeat for Private Tabs
72 }.togglePrivateBrowsingMode()
75 }.enterURLAndEnterToBrowser(defaultWebPage.url) {
77 verifyPrivateModeSelected()
78 verifyExistingTabList()
79 }.openTabsListThreeDotMenu {
80 verifyCloseAllTabsButton()
86 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2349580
88 fun closingTabsTest() {
89 val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
92 }.enterURLAndEnterToBrowser(genericURL.url) {
94 verifyExistingOpenTabs("Test_Page_1")
96 verifySnackBarText("Tab closed")
97 clickSnackbarButton("UNDO")
100 verifyTabCounter("1")
104 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903604
106 fun swipeToCloseTabsTest() {
107 val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
110 }.enterURLAndEnterToBrowser(genericURL.url) {
113 verifyExistingOpenTabs("Test_Page_1")
114 swipeTabRight("Test_Page_1")
115 verifySnackBarText("Tab closed")
118 verifyTabCounter("0")
119 }.openNavigationToolbar {
120 }.enterURLAndEnterToBrowser(genericURL.url) {
123 verifyExistingOpenTabs("Test_Page_1")
124 swipeTabLeft("Test_Page_1")
125 verifySnackBarText("Tab closed")
128 verifyTabCounter("0")
132 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903591
134 fun closingPrivateTabsTest() {
135 val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
137 homeScreen { }.togglePrivateBrowsingMode(switchPBModeOn = true)
139 }.enterURLAndEnterToBrowser(genericURL.url) {
141 verifyExistingOpenTabs("Test_Page_1")
142 verifyCloseTabsButton("Test_Page_1")
144 verifySnackBarText("Private tab closed")
145 clickSnackbarButton("UNDO")
148 verifyTabCounter("1")
152 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903606
155 fun tabMediaControlButtonTest() {
156 val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
159 }.enterURLAndEnterToBrowser(audioTestPage.url) {
160 mDevice.waitForIdle()
161 clickPageObject(MatcherHelper.itemWithText("Play"))
162 assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING)
164 verifyTabMediaControlButtonState("Pause")
165 clickTabMediaControlButton("Pause")
166 verifyTabMediaControlButtonState("Play")
167 }.openTab(audioTestPage.title) {
168 assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED)
172 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903592
175 fun verifyCloseAllPrivateTabsNotificationTest() {
176 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
179 }.togglePrivateBrowsingMode()
182 }.enterURLAndEnterToBrowser(defaultWebPage.url) {
183 mDevice.openNotification()
187 verifyPrivateTabsNotification()
188 }.clickClosePrivateTabsNotification {
193 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903598
196 fun shareTabsFromTabsTrayTest() {
197 val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
198 val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2)
199 val firstWebsiteTitle = firstWebsite.title
200 val secondWebsiteTitle = secondWebsite.title
201 val sharingApp = "Gmail"
202 val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}"
205 }.openNavigationToolbar {
206 }.enterURLAndEnterToBrowser(firstWebsite.url) {
207 verifyPageContent(firstWebsite.content)
210 }.submitQuery(secondWebsite.url.toString()) {
211 verifyPageContent(secondWebsite.content)
213 verifyExistingOpenTabs("Test_Page_1")
214 verifyExistingOpenTabs("Test_Page_2")
215 }.openTabsListThreeDotMenu {
216 verifyShareAllTabsButton()
217 }.clickShareAllTabsButton {
218 verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
219 verifySharingWithSelectedApp(
222 "$firstWebsiteTitle, $secondWebsiteTitle",
227 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903602
229 fun verifyTabTrayNotShowingStateHalfExpanded() {
232 verifyNoOpenTabsInNormalBrowsing()
233 // With no tabs opened the state should be STATE_COLLAPSED.
234 verifyBehaviorState(BottomSheetBehavior.STATE_COLLAPSED)
235 // Need to ensure the halfExpandedRatio is very small so that when in STATE_HALF_EXPANDED
236 // the tabTray will actually have a very small height (for a very short time) akin to being hidden.
237 verifyHalfExpandedRatio()
239 }.waitForTabTrayBehaviorToIdle {
240 // Touching the topBar would normally advance the tabTray to the next state.
241 // We don't want that.
242 verifyBehaviorState(BottomSheetBehavior.STATE_COLLAPSED)
243 }.advanceToHalfExpandedState {
244 }.waitForTabTrayBehaviorToIdle {
245 // TabTray should not be displayed in STATE_HALF_EXPANDED.
246 // When advancing to this state it should immediately be hidden.
247 verifyTabTrayIsClosed()
251 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903600
253 fun verifyEmptyTabTray() {
256 verifyNormalBrowsingButtonIsSelected(true)
257 verifyPrivateBrowsingButtonIsSelected(false)
258 verifySyncedTabsButtonIsSelected(false)
259 verifyNoOpenTabsInNormalBrowsing()
260 verifyNormalBrowsingNewTabButton()
261 verifyTabTrayOverflowMenu(true)
262 verifyEmptyTabsTrayMenuButtons()
266 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903585
268 fun verifyEmptyPrivateTabsTrayTest() {
271 }.toggleToPrivateTabs {
272 verifyNormalBrowsingButtonIsSelected(false)
273 verifyPrivateBrowsingButtonIsSelected(true)
274 verifySyncedTabsButtonIsSelected(false)
275 verifyNoOpenTabsInPrivateBrowsing()
276 verifyPrivateBrowsingNewTabButton()
277 verifyTabTrayOverflowMenu(true)
278 verifyEmptyTabsTrayMenuButtons()
282 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903601
284 fun verifyTabsTrayWithOpenTabTest() {
285 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
290 }.submitQuery(defaultWebPage.url.toString()) {
292 verifyNormalBrowsingButtonIsSelected(true)
293 verifyPrivateBrowsingButtonIsSelected(false)
294 verifySyncedTabsButtonIsSelected(false)
295 verifyTabTrayOverflowMenu(true)
296 verifyTabsTrayCounter()
297 verifyExistingTabList()
298 verifyNormalBrowsingNewTabButton()
299 verifyOpenedTabThumbnail()
300 verifyExistingOpenTabs(defaultWebPage.title)
301 verifyCloseTabsButton(defaultWebPage.title)
302 }.openTab(defaultWebPage.title) {
303 verifyUrl(defaultWebPage.url.toString())
304 verifyTabCounter("1")
308 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903587
311 fun verifyPrivateTabsTrayWithOpenTabTest() {
312 val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
316 }.toggleToPrivateTabs {
318 }.submitQuery(website.url.toString()) {
320 verifyNormalBrowsingButtonIsSelected(false)
321 verifyPrivateBrowsingButtonIsSelected(true)
322 verifySyncedTabsButtonIsSelected(false)
323 verifyTabTrayOverflowMenu(true)
324 verifyTabsTrayCounter()
325 verifyExistingTabList()
326 verifyExistingOpenTabs(website.title)
327 verifyCloseTabsButton(website.title)
328 verifyOpenedTabThumbnail()
329 verifyPrivateBrowsingNewTabButton()
333 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/927314
335 fun tabsCounterShortcutMenuCloseTabTest() {
336 val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
337 val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
340 }.enterURLAndEnterToBrowser(firstWebPage.url) {
343 }.openNavigationToolbar {
344 }.enterURLAndEnterToBrowser(secondWebPage.url) {
348 }.openTabButtonShortcutsMenu {
349 verifyTabButtonShortcutMenuItems()
350 }.closeTabFromShortcutsMenu {
352 verifyTabCounter("1")
353 verifyPageContent(firstWebPage.content)
358 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2343663
360 fun tabsCounterShortcutMenuNewPrivateTabTest() {
361 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
364 }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
366 }.openTabButtonShortcutsMenu {
367 }.openNewPrivateTabFromShortcutsMenu {
368 verifySearchBarPlaceholder("Search or enter address")
370 verifyIfInPrivateOrNormalMode(privateBrowsingEnabled = true)
374 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2343662
376 fun tabsCounterShortcutMenuNewTabTest() {
377 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
380 }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
382 }.openTabButtonShortcutsMenu {
383 }.openNewTabFromShortcutsMenu {
384 verifySearchBarPlaceholder("Search or enter address")
386 verifyIfInPrivateOrNormalMode(privateBrowsingEnabled = false)
390 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/927315
392 fun privateTabsCounterShortcutMenuCloseTabTest() {
393 val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
394 val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
396 homeScreen {}.togglePrivateBrowsingMode(switchPBModeOn = true)
398 }.enterURLAndEnterToBrowser(firstWebPage.url) {
401 }.openNavigationToolbar {
402 }.enterURLAndEnterToBrowser(secondWebPage.url) {
406 }.openTabButtonShortcutsMenu {
407 verifyTabButtonShortcutMenuItems()
408 }.closeTabFromShortcutsMenu {
410 verifyTabCounter("1")
411 verifyPageContent(firstWebPage.content)
413 }.openTabButtonShortcutsMenu {
414 }.closeTabFromShortcutsMenu {
416 verifyIfInPrivateOrNormalMode(privateBrowsingEnabled = true)
421 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2344199
423 fun privateTabsCounterShortcutMenuNewPrivateTabTest() {
424 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
426 homeScreen {}.togglePrivateBrowsingMode(switchPBModeOn = true)
428 }.enterURLAndEnterToBrowser(defaultWebPage.url) {
432 }.openTabButtonShortcutsMenu {
433 }.openNewPrivateTabFromShortcutsMenu {
434 verifySearchBarPlaceholder("Search or enter address")
436 verifyIfInPrivateOrNormalMode(privateBrowsingEnabled = true)
440 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2344198
442 fun privateTabsCounterShortcutMenuNewTabTest() {
443 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
445 homeScreen {}.togglePrivateBrowsingMode(switchPBModeOn = true)
447 }.enterURLAndEnterToBrowser(defaultWebPage.url) {
448 verifyPageContent(defaultWebPage.content)
451 }.openTabButtonShortcutsMenu {
452 }.openNewTabFromShortcutsMenu {
453 verifySearchToolbar(isDisplayed = true)
455 verifyIfInPrivateOrNormalMode(privateBrowsingEnabled = false)
459 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1046683
461 fun verifySyncedTabsWhenUserIsNotSignedInTest() {
464 verifySyncedTabsButtonIsSelected(isSelected = false)
465 clickSyncedTabsButton()
466 }.toggleToSyncedTabs {
467 verifySyncedTabsButtonIsSelected(isSelected = true)
468 verifySyncedTabsListWhenUserIsNotSignedIn()
469 }.clickSignInToSyncButton {
470 verifyTurnOnSyncMenu()
474 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/526244
476 fun privateModeStaysAsDefaultAfterRestartTest() {
477 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
480 }.enterURLAndEnterToBrowser(defaultWebPage.url) {
482 }.togglePrivateBrowsingMode()
483 closeApp(activityTestRule)
484 restartApp(activityTestRule)
486 verifyPrivateBrowsingHomeScreenItems()
488 }.toggleToNormalTabs {
489 verifyExistingOpenTabs(defaultWebPage.title)
493 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2228470
496 fun privateTabsDoNotPersistAfterClosingAppTest() {
497 val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
498 val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
501 }.togglePrivateBrowsingMode()
504 }.enterURLAndEnterToBrowser(firstWebPage.url) {
507 }.submitQuery(secondWebPage.url.toString()) {}
508 closeApp(activityTestRule)
509 restartApp(activityTestRule)
511 verifyPrivateBrowsingHomeScreenItems()
513 verifyNoOpenTabsInPrivateBrowsing()