Skip to content

Commit

Permalink
Implement bookmarks sort UI tests (#3162)
Browse files Browse the repository at this point in the history
Task/Issue URL:
https://app.asana.com/0/1204006570077678/1208153822177986/f
Tech Design URL:
CC:

## Description
Adds UI tests for bookmarks sort:
- Test that changing sort in the panel is reflected in the Bookmarks
Manager page and vice versa
- Test that manual, name ascending and name descending sorting work as
expected (both in panel and manager)
- Test that selected sorting is persisted through browser restarts

## Steps to test this PR
1. Run the `BookmarkSortTests` class
2. Check the UI tests work.

**Definition of Done**:

* [x] Does this PR satisfy our [Definition of
Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)?

—
###### Internal references:
[Pull Request Review
Checklist](https://app.asana.com/0/1202500774821704/1203764234894239/f)
[Software Engineering
Expectations](https://app.asana.com/0/59792373528535/199064865822552)
[Technical Design
Template](https://app.asana.com/0/59792373528535/184709971311943)
[Pull Request
Documentation](https://app.asana.com/0/1202500774821704/1204012835277482/f)
  • Loading branch information
jotaemepereira authored Sep 3, 2024
1 parent 8561bd2 commit 10359ba
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 25 deletions.
4 changes: 4 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2580,6 +2580,7 @@
BB470EBB2C5A66D6002EE91D /* BookmarkManagementDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB470EBA2C5A66D6002EE91D /* BookmarkManagementDetailViewModel.swift */; };
BB470EBC2C5A66D6002EE91D /* BookmarkManagementDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB470EBA2C5A66D6002EE91D /* BookmarkManagementDetailViewModel.swift */; };
BB5789722B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */; };
BB5F46A32C8751F6005F72DF /* BookmarkSortTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB5F46A22C8751F6005F72DF /* BookmarkSortTests.swift */; };
BB7B5F982C4ED73800BA4AF8 /* BookmarksSearchAndSortMetrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7B5F972C4ED73800BA4AF8 /* BookmarksSearchAndSortMetrics.swift */; };
BB7B5F992C4ED73800BA4AF8 /* BookmarksSearchAndSortMetrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7B5F972C4ED73800BA4AF8 /* BookmarksSearchAndSortMetrics.swift */; };
BBB881882C4029BA001247C6 /* BookmarkListTreeControllerSearchDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB881872C4029BA001247C6 /* BookmarkListTreeControllerSearchDataSource.swift */; };
Expand Down Expand Up @@ -4331,6 +4332,7 @@
B6FA8940269C425400588ECD /* PrivacyDashboardPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyDashboardPopover.swift; sourceTree = "<group>"; };
BB470EBA2C5A66D6002EE91D /* BookmarkManagementDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkManagementDetailViewModel.swift; sourceTree = "<group>"; };
BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionSubscriptionEventHandler.swift; sourceTree = "<group>"; };
BB5F46A22C8751F6005F72DF /* BookmarkSortTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkSortTests.swift; sourceTree = "<group>"; };
BB7B5F972C4ED73800BA4AF8 /* BookmarksSearchAndSortMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksSearchAndSortMetrics.swift; sourceTree = "<group>"; };
BBB881872C4029BA001247C6 /* BookmarkListTreeControllerSearchDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkListTreeControllerSearchDataSource.swift; sourceTree = "<group>"; };
BBBB653F2C77BB9400E69AC6 /* BookmarkSearchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkSearchTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -6315,6 +6317,7 @@
7B4CE8E626F02134009134B1 /* TabBarTests.swift */,
56A054522C2592CE007D8FAB /* OnboardingUITests.swift */,
BBBB653F2C77BB9400E69AC6 /* BookmarkSearchTests.swift */,
BB5F46A22C8751F6005F72DF /* BookmarkSortTests.swift */,
);
path = UITests;
sourceTree = "<group>";
Expand Down Expand Up @@ -11508,6 +11511,7 @@
buildActionMask = 2147483647;
files = (
EEBCE6842BA4643200B9DF00 /* NSSizeExtension.swift in Sources */,
BB5F46A32C8751F6005F72DF /* BookmarkSortTests.swift in Sources */,
EE7F74912BB5D76600CD9456 /* BookmarksBarTests.swift in Sources */,
EE02D41C2BB460A600DBE6B3 /* BrowsingHistoryTests.swift in Sources */,
EE02D41A2BB4609900DBE6B3 /* UITests.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/Bookmarks/View/BookmarkListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ final class BookmarkListViewController: NSViewController {
private lazy var searchBookmarksButton = MouseOverButton(image: .searchBookmarks, target: self, action: #selector(searchBookmarkButtonClicked))
.withAccessibilityIdentifier("BookmarkListViewController.searchBookmarksButton")
private lazy var sortBookmarksButton = MouseOverButton(image: .bookmarkSortAsc, target: self, action: #selector(sortBookmarksButtonClicked))
.withAccessibilityIdentifier("BookmarkListViewController.sortBookmarksButton")

private lazy var buttonsDivider = NSBox()
private lazy var manageBookmarksButton = MouseOverButton(title: UserText.bookmarksManage, target: self, action: #selector(openManagementInterface))
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/Menus/MainMenuActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,7 @@ extension MainViewController {
LocalBookmarkManager.shared.resetBookmarks()
UserDefaults.standard.set(false, forKey: UserDefaultsWrapper<Bool>.Key.homePageContinueSetUpImport.rawValue)
UserDefaults.standard.set(false, forKey: UserDefaultsWrapper<Bool>.Key.bookmarksBarPromptShown.rawValue)
LocalBookmarkManager.shared.sortMode = .manual
}

@objc func resetPinnedTabs(_ sender: Any?) {
Expand Down
25 changes: 7 additions & 18 deletions UITests/BookmarkSearchTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class BookmarkSearchTests: XCTestCase {
func testFilteredResultsInPanel() {
addThreeBookmarks()
closeShowBookmarksBarAlert()
openBookmarksPanel()
app.openBookmarksPanel()
searchInBookmarksPanel(for: "Bookmark #2")
assertOnlyBookmarkExists(on: app.outlines.firstMatch, bookmarkTitle: "Bookmark #2")
}
Expand Down Expand Up @@ -95,7 +95,7 @@ class BookmarkSearchTests: XCTestCase {
}

func testSearchActionIsHiddenOnBookmarksPanelWhenUserHasNoBookmarks() {
openBookmarksPanel()
app.openBookmarksPanel()
let bookmarksPanelPopover = app.popovers.firstMatch
XCTAssertFalse(bookmarksPanelPopover.buttons[AccessibilityIdentifiers.searchBookmarksButton].exists)
}
Expand All @@ -110,7 +110,7 @@ class BookmarkSearchTests: XCTestCase {
private func addBookmarkAndOpenBookmarksPanel(bookmarkPageTitle: String, in folder: String? = nil) {
addBookmark(pageTitle: bookmarkPageTitle, in: folder)
closeShowBookmarksBarAlert()
openBookmarksPanel()
app.openBookmarksPanel()
}

private func addBookmarkAndOpenBookmarksManager(bookmarkPageTitle: String, in folder: String? = nil) {
Expand All @@ -127,8 +127,7 @@ class BookmarkSearchTests: XCTestCase {

private func addBookmark(pageTitle: String, in folder: String? = nil) {
let urlForBookmarksBar = UITests.simpleServedPage(titled: pageTitle)
app.openSiteToBookmark(app: app,
url: urlForBookmarksBar,
app.openSiteToBookmark(url: urlForBookmarksBar,
pageTitle: pageTitle,
bookmarkingViaDialog: true,
escapingDialog: true,
Expand Down Expand Up @@ -181,10 +180,6 @@ class BookmarkSearchTests: XCTestCase {
popover.buttons[AccessibilityIdentifiers.searchBookmarksButton].tap()
}

private func openBookmarksPanel() {
app.showAndTapBookmarksPanelShortcut()
}

private func openBookmarksManager() {
app.openBookmarksManager()
}
Expand All @@ -200,7 +195,7 @@ class BookmarkSearchTests: XCTestCase {
closeShowBookmarksBarAlert()

if mode == .panel {
openBookmarksPanel()
app.openBookmarksPanel()
searchInBookmarksPanel(for: "Bookmark #1")
} else {
openBookmarksManager()
Expand Down Expand Up @@ -244,7 +239,7 @@ class BookmarkSearchTests: XCTestCase {
addThreeBookmarks()
if mode == .panel {
closeShowBookmarksBarAlert()
openBookmarksPanel()
app.openBookmarksPanel()
} else {
openBookmarksManager()
}
Expand Down Expand Up @@ -306,7 +301,7 @@ class BookmarkSearchTests: XCTestCase {
}

private func createFolderWithSubFolder() {
openBookmarksPanel()
app.openBookmarksPanel()
let bookmarksPanel = app.popovers.firstMatch
bookmarksPanel.buttons[AccessibilityIdentifiers.newFolderButton].tap()

Expand All @@ -326,9 +321,3 @@ class BookmarkSearchTests: XCTestCase {
app.dismissPopover(buttonIdentifier: "Hide")
}
}

// Enum to represent bookmark modes
private enum BookmarkMode {
case panel
case manager
}
208 changes: 208 additions & 0 deletions UITests/BookmarkSortTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
//
// BookmarkSortTests.swift
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import XCTest

class BookmarkSortTests: XCTestCase {
private var app: XCUIApplication!

private enum AccessibilityIdentifiers {
static let addressBarTextField = "AddressBarViewController.addressBarTextField"
static let resetBookmarksMenuItem = "MainMenu.resetBookmarks"
static let sortBookmarksButtonPanel = "BookmarkListViewController.sortBookmarksButton"
static let sortBookmarksButtonManager = "BookmarkManagementDetailViewController.sortItemsButton"
}

override class func setUp() {
UITests.firstRun()
}

override func setUpWithError() throws {
continueAfterFailure = false
app = XCUIApplication()
app.launchEnvironment["UITEST_MODE"] = "1"
app.launch()
app.resetBookmarks()
app.enforceSingleWindow()
}

func testWhenChangingSortingInThePanelIsReflectedInTheManager() {
app.openBookmarksPanel()
selectSortByName(mode: .panel)
app.openBookmarksManager()

app.buttons[AccessibilityIdentifiers.sortBookmarksButtonManager].tap()

/// If the ascending and descending sort options are enabled, means that the sort in the panel was reflected here.
XCTAssertTrue(app.menuItems["Ascending"].isEnabled)
XCTAssertTrue(app.menuItems["Descending"].isEnabled)
}

func testWhenChangingSortingInTheManagerIsReflectedInThePanel() {
app.openBookmarksManager()
selectSortByName(mode: .manager)
app.openBookmarksPanel()

let bookmarksPanelPopover = app.popovers.firstMatch
bookmarksPanelPopover.buttons[AccessibilityIdentifiers.sortBookmarksButtonPanel].tap()

XCTAssertTrue(bookmarksPanelPopover.menuItems["Ascending"].isEnabled)
XCTAssertTrue(bookmarksPanelPopover.menuItems["Descending"].isEnabled)
}

func testManualSortWorksAsExpectedOnBookmarksPanel() {
["Bookmark #2", "Bookmark #3", "Bookmark #1"].forEach {
addBookmark(pageTitle: $0)
app.openNewTab()
}

closeShowBookmarksBarAlert()
app.openBookmarksPanel()
app.verifyBookmarkOrder(expectedOrder: ["Bookmark #2", "Bookmark #3", "Bookmark #1"], mode: .panel)
}

func testManualSortWorksAsExpectedOnBookmarksManager() {
["Bookmark #2", "Bookmark #3", "Bookmark #1"].forEach {
addBookmark(pageTitle: $0)
app.openNewTab()
}

closeShowBookmarksBarAlert()
app.openBookmarksManager()
app.verifyBookmarkOrder(expectedOrder: ["Bookmark #2", "Bookmark #3", "Bookmark #1"], mode: .manager)
}

func testNameAscendingSortWorksAsExpectedOnBookmarksPanel() {
["Bookmark #2", "Bookmark #3", "Bookmark #1"].forEach {
addBookmark(pageTitle: $0)
app.openNewTab()
}

closeShowBookmarksBarAlert()
app.openBookmarksPanel()
selectSortByName(mode: .panel)
app.verifyBookmarkOrder(expectedOrder: ["Bookmark #1", "Bookmark #2", "Bookmark #3"], mode: .panel)
}

func testNameAscendingSortWorksAsExpectedOnBookmarksManager() {
["Bookmark #2", "Bookmark #3", "Bookmark #1"].forEach {
addBookmark(pageTitle: $0)
app.openNewTab()
}

closeShowBookmarksBarAlert()
app.openBookmarksManager()
selectSortByName(mode: .manager)
app.verifyBookmarkOrder(expectedOrder: ["Bookmark #1", "Bookmark #2", "Bookmark #3"], mode: .manager)
}

func testNameDescendingSortWorksAsExpectedOnBookmarksPanel() {
["Bookmark #2", "Bookmark #3", "Bookmark #1"].forEach {
addBookmark(pageTitle: $0)
app.openNewTab()
}

closeShowBookmarksBarAlert()
app.openBookmarksPanel()
selectSortByName(mode: .panel, descending: true)
app.verifyBookmarkOrder(expectedOrder: ["Bookmark #3", "Bookmark #2", "Bookmark #1"], mode: .panel)
}

func testNameDescendingSortWorksAsExpectedOnBookmarksManager() {
["Bookmark #2", "Bookmark #3", "Bookmark #1"].forEach {
addBookmark(pageTitle: $0)
app.openNewTab()
}

closeShowBookmarksBarAlert()
app.openBookmarksManager()
selectSortByName(mode: .manager, descending: true)
app.verifyBookmarkOrder(expectedOrder: ["Bookmark #3", "Bookmark #2", "Bookmark #1"], mode: .manager)
}

func testThatSortIsPersistedThroughBrowserRestarts() {
app.openBookmarksPanel()
selectSortByName(mode: .panel)

app.terminate()
let newApp = XCUIApplication()
newApp.launch()

app.openBookmarksPanel()

Check failure on line 146 in UITests/BookmarkSortTests.swift

View workflow job for this annotation

GitHub Actions / UI tests (macos-13-xlarge)

testThatSortIsPersistedThroughBrowserRestarts, Failed to tap "NavigationBarViewController.bookmarkListButton" Button: No matches found for Descendants matching type Button from input {(

Check failure on line 146 in UITests/BookmarkSortTests.swift

View workflow job for this annotation

GitHub Actions / UI tests (macos-13-xlarge)

testThatSortIsPersistedThroughBrowserRestarts, Failed to tap "NavigationBarViewController.bookmarkListButton" Button: No matches found for Descendants matching type Button from input {(

let sortBookmarksPanelButton = newApp.buttons[AccessibilityIdentifiers.sortBookmarksButtonPanel]
sortBookmarksPanelButton.tap()

let sortByNameManual = newApp.menuItems["Manual"]
let sortByNameMenuItem = newApp.menuItems["Name"]
let sortByNameAscendingMenuItem = newApp.menuItems["Ascending"]
let sortByNameDescendingMenuItem = newApp.menuItems["Descending"]

XCTAssertTrue(sortByNameManual.isEnabled)
XCTAssertTrue(sortByNameMenuItem.isEnabled)
XCTAssertTrue(sortByNameAscendingMenuItem.isEnabled)
XCTAssertTrue(sortByNameDescendingMenuItem.isEnabled)
}

// MARK: - Utilities

private func tapPanelSortButton() {
let bookmarksPanelPopover = app.popovers.firstMatch
let sortBookmarksButton = bookmarksPanelPopover.buttons[AccessibilityIdentifiers.sortBookmarksButtonPanel]
sortBookmarksButton.tap()
}

private func selectSortByName(mode: BookmarkMode, descending: Bool = false) {
if mode == .panel {
let bookmarksPanelPopover = app.popovers.firstMatch
let sortBookmarksButton = bookmarksPanelPopover.buttons[AccessibilityIdentifiers.sortBookmarksButtonPanel]
sortBookmarksButton.tap()
bookmarksPanelPopover.menuItems["Name"].tap()

if descending {
sortBookmarksButton.tap()
bookmarksPanelPopover.menuItems["Descending"].tap()
}
} else {
let sortBookmarksButton = app.buttons[AccessibilityIdentifiers.sortBookmarksButtonManager]
sortBookmarksButton.tap()
app.menuItems["Name"].tap()

if descending {
sortBookmarksButton.tap()
app.menuItems["Descending"].tap()
/// Here we hover over the sort button, because if we stay where the 'Descending' was selected
/// the label of the bookmark being hovered is different because it shows the URL.
sortBookmarksButton.hover()
}
}
}

private func addBookmark(pageTitle: String, in folder: String? = nil) {
let urlForBookmarksBar = UITests.simpleServedPage(titled: pageTitle)
app.openSiteToBookmark(url: urlForBookmarksBar,
pageTitle: pageTitle,
bookmarkingViaDialog: true,
escapingDialog: true,
folderName: folder)
}

private func closeShowBookmarksBarAlert() {
app.dismissPopover(buttonIdentifier: "Hide")
}
}
Loading

0 comments on commit 10359ba

Please sign in to comment.