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 androidx.compose.ui.test.junit4.AndroidComposeTestRule
8 import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
9 import androidx.test.espresso.Espresso.pressBack
10 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
13 import org.mozilla.fenix.R
14 import org.mozilla.fenix.customannotations.SmokeTest
15 import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
16 import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
17 import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
18 import org.mozilla.fenix.helpers.RetryTestRule
19 import org.mozilla.fenix.helpers.TestAssetHelper
20 import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
21 import org.mozilla.fenix.helpers.TestHelper.exitMenu
22 import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
23 import org.mozilla.fenix.helpers.TestHelper.mDevice
24 import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
25 import org.mozilla.fenix.helpers.TestSetup
26 import org.mozilla.fenix.ui.robots.bookmarksMenu
27 import org.mozilla.fenix.ui.robots.browserScreen
28 import org.mozilla.fenix.ui.robots.homeScreen
29 import org.mozilla.fenix.ui.robots.multipleSelectionToolbar
30 import org.mozilla.fenix.ui.robots.navigationToolbar
33 * Tests for verifying basic functionality of bookmarks
35 class ComposeBookmarksTest : TestSetup() {
36 private val bookmarksFolderName = "New Folder"
37 private val testBookmark = object {
38 var title: String = "Bookmark title"
39 var url: String = "https://www.example.com"
43 val activityTestRule =
44 AndroidComposeTestRule(
45 HomeActivityIntentTestRule.withDefaultSettingsOverrides(
46 tabsTrayRewriteEnabled = true,
52 val retryTestRule = RetryTestRule(3)
54 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522919
56 fun verifyEmptyBookmarksMenuTest() {
60 registerAndCleanupIdlingResources(
61 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
63 verifyBookmarksMenuView()
64 verifyAddFolderButton()
66 verifyBookmarkTitle("Desktop Bookmarks")
67 selectFolder("Desktop Bookmarks")
68 verifyFolderTitle("Bookmarks Menu")
69 verifyFolderTitle("Bookmarks Toolbar")
70 verifyFolderTitle("Other Bookmarks")
71 verifySyncSignInButton()
73 }.clickSingInToSyncButton {
74 verifyTurnOnSyncToolbarTitle()
78 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522920
80 fun cancelCreateBookmarkFolderTest() {
84 clickAddFolderButton()
85 addNewFolderName(bookmarksFolderName)
87 verifyKeyboardHidden(isExpectedToBeVisible = false)
88 verifyBookmarkFolderIsNotCreated(bookmarksFolderName)
92 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299619
94 fun cancelingChangesInEditModeAreNotSavedTest() {
95 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
98 }.enterURLAndEnterToBrowser(defaultWebPage.url) {
101 clickSnackbarButton("EDIT")
104 verifyEditBookmarksView()
105 changeBookmarkTitle(testBookmark.title)
106 changeBookmarkUrl(testBookmark.url)
107 }.closeEditBookmarkSection {
112 verifyBookmarkTitle(defaultWebPage.title)
113 verifyBookmarkedURL(defaultWebPage.url.toString())
117 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325633
120 fun editBookmarksNameAndUrlTest() {
121 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
124 createBookmark(defaultWebPage.url)
127 verifyEditBookmarksView()
128 changeBookmarkTitle(testBookmark.title)
129 changeBookmarkUrl(testBookmark.url)
135 registerAndCleanupIdlingResources(
136 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
138 verifyBookmarkTitle(testBookmark.title)
139 verifyBookmarkedURL(testBookmark.url)
140 }.openBookmarkWithTitle(testBookmark.title) {
141 verifyUrl("example.com")
145 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/341696
147 fun copyBookmarkURLTest() {
148 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
151 createBookmark(defaultWebPage.url)
154 registerAndCleanupIdlingResources(
155 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
157 }.openThreeDotMenu(defaultWebPage.title) {
159 verifySnackBarText(expectedText = "URL copied")
168 verifyTypedToolbarText(defaultWebPage.url.toString())
172 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325634
174 fun shareBookmarkTest() {
175 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
178 createBookmark(defaultWebPage.url)
181 registerAndCleanupIdlingResources(
182 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
184 }.openThreeDotMenu(defaultWebPage.title) {
187 verifyShareBookmarkFavicon()
188 verifyShareBookmarkTitle()
189 verifyShareBookmarkUrl()
193 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325636
195 fun openBookmarkInNewTabTest() {
196 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
199 createBookmark(defaultWebPage.url)
202 registerAndCleanupIdlingResources(
203 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
205 }.openThreeDotMenu(defaultWebPage.title) {
206 }.clickOpenInNewTab(activityTestRule) {
207 verifyTabTrayIsOpen()
208 verifyNormalBrowsingButtonIsSelected()
212 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1919261
214 fun verifyOpenAllInNewTabsOptionTest() {
215 val webPages = listOf(
216 TestAssetHelper.getGenericAsset(mockWebServer, 1),
217 TestAssetHelper.getGenericAsset(mockWebServer, 2),
218 TestAssetHelper.getGenericAsset(mockWebServer, 3),
219 TestAssetHelper.getGenericAsset(mockWebServer, 4),
226 createFolder("sub", "root")
227 createFolder("empty", "root")
232 createBookmark(webPages[0].url)
233 createBookmark(webPages[1].url, "root")
234 createBookmark(webPages[2].url, "root")
235 createBookmark(webPages[3].url, "sub")
236 }.openComposeTabDrawer(activityTestRule) {
243 }.openThreeDotMenu("root") {
244 }.clickOpenAllInTabs(activityTestRule) {
245 verifyTabTrayIsOpen()
246 verifyNormalBrowsingButtonIsSelected()
248 verifyExistingOpenTabs("Test_Page_2", "Test_Page_3", "Test_Page_4")
250 // Bookmark that is not under the root folder should not be opened
251 verifyNoExistingOpenTabs("Test_Page_1")
255 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1919262
257 fun verifyOpenAllInPrivateTabsTest() {
258 val webPages = listOf(
259 TestAssetHelper.getGenericAsset(mockWebServer, 1),
260 TestAssetHelper.getGenericAsset(mockWebServer, 2),
267 createFolder("sub", "root")
268 createFolder("empty", "root")
273 createBookmark(webPages[0].url, "root")
274 createBookmark(webPages[1].url, "sub")
275 }.openComposeTabDrawer(activityTestRule) {
282 }.openThreeDotMenu("root") {
283 }.clickOpenAllInPrivateTabs(activityTestRule) {
284 verifyTabTrayIsOpen()
285 verifyPrivateBrowsingButtonIsSelected()
287 verifyExistingOpenTabs("Test_Page_1", "Test_Page_2")
291 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325637
293 fun openBookmarkInPrivateTabTest() {
294 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
297 createBookmark(defaultWebPage.url)
300 registerAndCleanupIdlingResources(
301 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
303 }.openThreeDotMenu(defaultWebPage.title) {
304 }.clickOpenInPrivateTab(activityTestRule) {
305 verifyTabTrayIsOpen()
306 verifyPrivateBrowsingButtonIsSelected()
310 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325635
312 fun deleteBookmarkTest() {
313 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
316 createBookmark(defaultWebPage.url)
319 registerAndCleanupIdlingResources(
320 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
322 }.openThreeDotMenu(defaultWebPage.title) {
324 verifyUndoDeleteSnackBarButton()
325 clickSnackbarButton("UNDO")
326 verifySnackBarHidden()
327 registerAndCleanupIdlingResources(
328 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
330 verifyBookmarkedURL(defaultWebPage.url.toString())
332 }.openThreeDotMenu(defaultWebPage.title) {
334 verifyBookmarkIsDeleted(defaultWebPage.title)
338 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2300275
340 fun bookmarksMultiSelectionToolbarItemsTest() {
341 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
344 createBookmark(defaultWebPage.url)
347 registerAndCleanupIdlingResources(
348 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
350 longTapSelectItem(defaultWebPage.url)
354 multipleSelectionToolbar {
355 verifyMultiSelectionCheckmark(defaultWebPage.url)
356 verifyMultiSelectionCounter()
357 verifyShareBookmarksButton()
358 verifyCloseToolbarButton()
359 }.closeToolbarReturnToBookmarks {
360 verifyBookmarksMenuView()
364 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2300276
367 fun openMultipleSelectedBookmarksInANewTabTest() {
368 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
371 createBookmark(defaultWebPage.url)
372 }.openComposeTabDrawer(activityTestRule) {
379 registerAndCleanupIdlingResources(
380 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
382 longTapSelectItem(defaultWebPage.url)
383 openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
387 multipleSelectionToolbar {
388 }.clickOpenNewTab(activityTestRule) {
389 verifyTabTrayIsOpen()
390 verifyNormalBrowsingButtonIsSelected()
391 verifyNormalTabsList()
395 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2300277
397 fun openMultipleSelectedBookmarksInPrivateTabTest() {
398 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
401 createBookmark(defaultWebPage.url)
404 registerAndCleanupIdlingResources(
405 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
407 longTapSelectItem(defaultWebPage.url)
408 openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
412 multipleSelectionToolbar {
413 }.clickOpenPrivateTab(activityTestRule) {
414 verifyPrivateBrowsingButtonIsSelected()
415 verifyPrivateTabsList()
419 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325644
422 fun deleteMultipleSelectedBookmarksTest() {
423 val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
424 val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
427 createBookmark(firstWebPage.url)
428 createBookmark(secondWebPage.url)
431 registerAndCleanupIdlingResources(
432 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3),
434 longTapSelectItem(firstWebPage.url)
435 longTapSelectItem(secondWebPage.url)
437 openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
440 multipleSelectionToolbar {
441 clickMultiSelectionDelete()
445 verifySnackBarText(expectedText = "Bookmarks deleted")
446 clickSnackbarButton("UNDO")
447 verifyBookmarkedURL(firstWebPage.url.toString())
448 verifyBookmarkedURL(secondWebPage.url.toString())
449 registerAndCleanupIdlingResources(
450 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3),
452 longTapSelectItem(firstWebPage.url)
453 longTapSelectItem(secondWebPage.url)
455 openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
458 multipleSelectionToolbar {
459 clickMultiSelectionDelete()
463 verifySnackBarText(expectedText = "Bookmarks deleted")
467 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301355
469 fun shareMultipleSelectedBookmarksTest() {
470 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
473 createBookmark(defaultWebPage.url)
476 registerAndCleanupIdlingResources(
477 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
479 longTapSelectItem(defaultWebPage.url)
483 multipleSelectionToolbar {
484 clickShareBookmarksButton()
486 verifyShareTabFavicon()
487 verifyShareTabTitle()
492 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325639
494 fun createBookmarkFolderTest() {
495 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
498 createBookmark(defaultWebPage.url)
501 registerAndCleanupIdlingResources(
502 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
504 }.openThreeDotMenu(defaultWebPage.title) {
506 clickParentFolderSelector()
507 clickAddNewFolderButtonFromSelectFolderView()
508 addNewFolderName(bookmarksFolderName)
512 selectFolder(bookmarksFolderName)
513 verifyBookmarkedURL(defaultWebPage.url.toString())
517 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325645
519 fun navigateBookmarksFoldersTest() {
524 getInstrumentation().waitForIdleSync()
525 waitForBookmarksFolderContentToExist("Bookmarks", "1")
527 verifyCurrentFolderTitle("1")
529 getInstrumentation().waitForIdleSync()
530 waitForBookmarksFolderContentToExist("1", "2")
532 verifyCurrentFolderTitle("2")
534 waitForBookmarksFolderContentToExist("1", "2")
535 verifyCurrentFolderTitle("1")
537 verifyBookmarksMenuView()
541 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/374855
543 fun cantSelectDefaultFoldersTest() {
547 registerAndCleanupIdlingResources(
548 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list)),
550 longTapDesktopFolder("Desktop Bookmarks")
551 verifySnackBarText(expectedText = "Can’t edit default folders")
556 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299703
558 fun deleteBookmarkInEditModeTest() {
559 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
562 createBookmark(defaultWebPage.url)
565 registerAndCleanupIdlingResources(
566 RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
568 }.openThreeDotMenu(defaultWebPage.title) {
570 clickDeleteInEditModeButton()
572 clickDeleteInEditModeButton()
574 verifySnackBarText(expectedText = "Deleted")
575 verifyBookmarkIsDeleted("Test_Page_1")
579 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715710
581 fun verifySearchBookmarksViewTest() {
582 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
585 createBookmark(defaultWebPage.url)
588 }.clickSearchButton {
590 verifySearchToolbar(true)
591 verifySearchSelectorButton()
592 verifySearchEngineIcon("Bookmarks")
593 verifySearchBarPlaceholder("Search bookmarks")
594 verifySearchBarPosition(true)
595 tapOutsideToDismissSearchBar()
596 verifySearchToolbar(false)
599 }.goBackToBrowserScreen {
602 }.openCustomizeSubMenu {
603 clickTopToolbarToggle()
611 }.clickSearchButton {
612 verifySearchToolbar(true)
613 verifySearchEngineIcon("Bookmarks")
614 verifySearchBarPosition(false)
616 verifySearchToolbar(false)
620 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715712
622 fun verifySearchForBookmarkedItemsTest() {
623 val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
624 val secondWebPage = TestAssetHelper.getHTMLControlsFormAsset(mockWebServer)
629 createFolder(bookmarksFolderName)
635 createBookmark(firstWebPage.url, bookmarksFolderName)
636 createBookmark(secondWebPage.url)
639 }.clickSearchButton {
640 // Search for a valid term
641 typeSearch(firstWebPage.title)
642 verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title)
643 verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
644 // Search for invalid term
645 typeSearch("Android")
646 verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
647 verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
651 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715711
653 fun verifyVoiceSearchInBookmarksTest() {
654 val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
657 createBookmark(defaultWebPage.url)
660 }.clickSearchButton {
661 verifySearchToolbar(true)
662 verifySearchEngineIcon("Bookmarks")
667 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715714
669 fun verifyDeletedBookmarksAreNotDisplayedAsSearchResultsTest() {
670 val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
671 val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
672 val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
675 createBookmark(firstWebPage.url)
676 createBookmark(secondWebPage.url)
677 createBookmark(thirdWebPage.url)
680 }.openThreeDotMenu(firstWebPage.title) {
682 verifyBookmarkIsDeleted(firstWebPage.title)
683 }.openThreeDotMenu(secondWebPage.title) {
685 verifyBookmarkIsDeleted(secondWebPage.title)
686 }.clickSearchButton {
687 // Search for a valid term
688 typeSearch("generic")
689 verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
690 verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
691 verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic")
695 }.openThreeDotMenu(thirdWebPage.title) {
697 verifyBookmarkIsDeleted(thirdWebPage.title)
698 }.clickSearchButton {
699 // Search for a valid term
700 typeSearch("generic")
701 verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString())
705 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325642
706 // Verifies that deleting a Bookmarks folder also removes the item from inside it.
709 fun deleteBookmarkFoldersTest() {
710 val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
713 createBookmark(website.url)
716 verifyBookmarkTitle("Test_Page_1")
717 createFolder("My Folder")
718 verifyFolderTitle("My Folder")
719 }.openThreeDotMenu("Test_Page_1") {
721 clickParentFolderSelector()
722 selectFolder("My Folder")
725 createFolder("My Folder 2")
726 verifyFolderTitle("My Folder 2")
727 }.openThreeDotMenu("My Folder 2") {
729 clickParentFolderSelector()
730 selectFolder("My Folder")
733 }.openThreeDotMenu("My Folder") {
735 cancelFolderDeletion()
736 verifyFolderTitle("My Folder")
737 }.openThreeDotMenu("My Folder") {
740 verifySnackBarText(expectedText = "Deleted")
741 clickSnackbarButton("UNDO")
742 verifyFolderTitle("My Folder")
743 }.openThreeDotMenu("My Folder") {
746 verifySnackBarText(expectedText = "Deleted")
747 verifyBookmarkIsDeleted("My Folder")
748 verifyBookmarkIsDeleted("My Folder 2")
749 verifyBookmarkIsDeleted("Test_Page_1")