From 6ddab788576e99510373cf4ee1fc4c092ac787f6 Mon Sep 17 00:00:00 2001 From: Juan Manuel Pereira Date: Thu, 29 Aug 2024 18:53:19 -0300 Subject: [PATCH] Implement pinned tabs tests --- DuckDuckGo.xcodeproj/project.pbxproj | 4 + UITests/Common/UITests.swift | 2 +- UITests/PinnedTabsTests.swift | 179 +++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 UITests/PinnedTabsTests.swift diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index c41c4f9db9..9ea2b4f50e 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -2577,6 +2577,7 @@ B6F9BDE52B45CD1900677B33 /* ModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9BDE32B45CD1900677B33 /* ModalView.swift */; }; B6FA893F269C424500588ECD /* PrivacyDashboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6FA893E269C424500588ECD /* PrivacyDashboardViewController.swift */; }; B6FA8941269C425400588ECD /* PrivacyDashboardPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6FA8940269C425400588ECD /* PrivacyDashboardPopover.swift */; }; + BB4339DB2C7F9606005D7ED7 /* PinnedTabsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB4339DA2C7F9606005D7ED7 /* PinnedTabsTests.swift */; }; 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 */; }; @@ -4330,6 +4331,7 @@ B6F9BDE32B45CD1900677B33 /* ModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalView.swift; sourceTree = ""; }; B6FA893E269C424500588ECD /* PrivacyDashboardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyDashboardViewController.swift; sourceTree = ""; }; B6FA8940269C425400588ECD /* PrivacyDashboardPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyDashboardPopover.swift; sourceTree = ""; }; + BB4339DA2C7F9606005D7ED7 /* PinnedTabsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedTabsTests.swift; sourceTree = ""; }; BB470EBA2C5A66D6002EE91D /* BookmarkManagementDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkManagementDetailViewModel.swift; sourceTree = ""; }; BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionSubscriptionEventHandler.swift; sourceTree = ""; }; BB5F46A22C8751F6005F72DF /* BookmarkSortTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkSortTests.swift; sourceTree = ""; }; @@ -6318,6 +6320,7 @@ 56A054522C2592CE007D8FAB /* OnboardingUITests.swift */, BBBB653F2C77BB9400E69AC6 /* BookmarkSearchTests.swift */, BB5F46A22C8751F6005F72DF /* BookmarkSortTests.swift */, + BB4339DA2C7F9606005D7ED7 /* PinnedTabsTests.swift */, ); path = UITests; sourceTree = ""; @@ -11510,6 +11513,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + BB4339DB2C7F9606005D7ED7 /* PinnedTabsTests.swift in Sources */, EEBCE6842BA4643200B9DF00 /* NSSizeExtension.swift in Sources */, BB5F46A32C8751F6005F72DF /* BookmarkSortTests.swift in Sources */, EE7F74912BB5D76600CD9456 /* BookmarksBarTests.swift in Sources */, diff --git a/UITests/Common/UITests.swift b/UITests/Common/UITests.swift index 10ebf5046d..a92f64ce90 100644 --- a/UITests/Common/UITests.swift +++ b/UITests/Common/UITests.swift @@ -40,7 +40,7 @@ enum UITests { \(title) -

Sample text

+

Sample text for \(title)

""".utf8data) diff --git a/UITests/PinnedTabsTests.swift b/UITests/PinnedTabsTests.swift new file mode 100644 index 0000000000..a1324d1080 --- /dev/null +++ b/UITests/PinnedTabsTests.swift @@ -0,0 +1,179 @@ +// +// PinnedTabsTests.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 PinnedTabsTests: XCTestCase { + private var app: XCUIApplication! + + override func setUpWithError() throws { + continueAfterFailure = false + app = XCUIApplication() + app.launchEnvironment["UITEST_MODE"] = "1" + app.launch() + + app.typeKey("n", modifierFlags: .command) + } + + override class func setUp() { + UITests.firstRun() + } + + func testPinnedTabsFunctionality() { + openThreeSitesOnSameWindow() + openNewWindowAndLoadSite() + moveBackToPreviousWindows() + + /// It is important that we wait some seconds to execute the navigate tabs commands + /// the reason is that switching windows take its time and the other windows is not show + /// immediately. + sleep(2) + pinsPageOne() + sleep(1) + pinsPageTwo() + sleep (1) + assertsPageTwoIsPinned() + sleep(1) + assertsPageOneIsPinned() + sleep(1) + dragsPageTwoPinnedTabToTheFirstPosition() + sleep(1) + assertsCommandWFunctionality() + assertWindowTwoHasTheTwoPinnedTabFromWindowsOne() + sleep(2) + app.terminate() + assertPinnedTabsRestoredState() + } + + // MARK: - Utilities + + private func openThreeSitesOnSameWindow() { + openSite(pageTitle: "Page #1") + app.openNewTab() + openSite(pageTitle: "Page #2") + app.openNewTab() + openSite(pageTitle: "Page #3") + } + + private func openNewWindowAndLoadSite() { + app.typeKey("n", modifierFlags: .command) + openSite(pageTitle: "Page #4") + } + + private func moveBackToPreviousWindows() { + let menuItem = app.menuItems["Page #3"].firstMatch + XCTAssertTrue( + menuItem.waitForExistence(timeout: UITests.Timeouts.elementExistence), + "Reset bookmarks menu item didn't become available in a reasonable timeframe." + ) + menuItem.hover() + app.typeKey(XCUIKeyboardKey.return, modifierFlags: []) + } + + private func openSite(pageTitle: String) { + let url = UITests.simpleServedPage(titled: pageTitle) + let addressBarTextField = app.windows.firstMatch.textFields["AddressBarViewController.addressBarTextField"] + XCTAssertTrue( + addressBarTextField.waitForExistence(timeout: UITests.Timeouts.elementExistence), + "The address bar text field didn't become available in a reasonable timeframe." + ) + addressBarTextField.typeURL(url) + XCTAssertTrue( + app.windows.firstMatch.webViews[pageTitle].waitForExistence(timeout: UITests.Timeouts.elementExistence), + "Visited site didn't load with the expected title in a reasonable timeframe." + ) + } + + private func pinsPageOne() { + app.typeKey("[", modifierFlags: [.command, .shift]) + app.typeKey("[", modifierFlags: [.command, .shift]) + app.menuItems["Pin Tab"].tap() + } + + private func pinsPageTwo() { + app.typeKey("]", modifierFlags: [.command, .shift]) + app.menuItems["Pin Tab"].tap() + } + + private func assertsPageTwoIsPinned() { + XCTAssertTrue(app.menuItems["Unpin Tab"].firstMatch.exists) + XCTAssertFalse(app.menuItems["Pin Tab"].firstMatch.exists) + } + + private func assertsPageOneIsPinned() { + app.typeKey("[", modifierFlags: [.command, .shift]) + XCTAssertTrue(app.menuItems["Unpin Tab"].firstMatch.exists) + XCTAssertFalse(app.menuItems["Pin Tab"].firstMatch.exists) + } + + private func dragsPageTwoPinnedTabToTheFirstPosition() { + app.typeKey("]", modifierFlags: [.command, .shift]) + let toolbar = app.toolbars.firstMatch + let toolbarCoordinate = toolbar.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)) + let startPoint = toolbarCoordinate.withOffset(CGVector(dx: 120, dy: 15)) + let endPoint = toolbarCoordinate.withOffset(CGVector(dx: 0, dy: 0)) + startPoint.press(forDuration: 0, thenDragTo: endPoint) + + sleep(1) + + /// Asserts the re-order worked by moving to the next tab and checking is Page #1 + app.typeKey("]", modifierFlags: [.command, .shift]) + XCTAssertTrue(app.staticTexts["Sample text for Page #1"].exists) + } + + private func assertsCommandWFunctionality() { + app.typeKey("w", modifierFlags: .command) + XCTAssertTrue(app.staticTexts["Sample text for Page #3"].exists) + } + + private func assertWindowTwoHasTheTwoPinnedTabFromWindowsOne() { + let items = app.menuItems.matching(identifier: "Page #4") + let pageFourMenuItem = items.element(boundBy: 1) + XCTAssertTrue( + pageFourMenuItem.waitForExistence(timeout: UITests.Timeouts.elementExistence), + "Reset bookmarks menu item didn't become available in a reasonable timeframe." + ) + pageFourMenuItem.hover() + app.typeKey(XCUIKeyboardKey.return, modifierFlags: []) + + sleep(2) + + /// Goes to Page #2 to check the state + app.typeKey("[", modifierFlags: [.command, .shift]) + app.typeKey("[", modifierFlags: [.command, .shift]) + XCTAssertTrue(app.staticTexts["Sample text for Page #2"].exists) + /// Goes to Page #1 to check the state + app.typeKey("]", modifierFlags: [.command, .shift]) + XCTAssertTrue(app.staticTexts["Sample text for Page #1"].exists) + } + + private func assertPinnedTabsRestoredState() { + let newApp = XCUIApplication() + newApp.launch() + + sleep(2) + + /// Goes to Page #2 to check the state + newApp.typeKey("[", modifierFlags: [.command, .shift]) + newApp.typeKey("[", modifierFlags: [.command, .shift]) + XCTAssertTrue(newApp.staticTexts["Sample text for Page #2"].waitForExistence(timeout: UITests.Timeouts.elementExistence)) + /// Goes to Page #1 to check the state + newApp.typeKey("]", modifierFlags: [.command, .shift]) + XCTAssertTrue(newApp.staticTexts["Sample text for Page #1"].waitForExistence(timeout: UITests.Timeouts.elementExistence)) + } +}