diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index 2ddc0806ca..4fd41cf2f7 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -852,6 +852,9 @@ extension Pixel { case protectedDataUnavailableWhenBecomeActive case statisticsLoaderATBStateMismatch case adAttributionReportStateMismatch + + // MARK: Browsing + case stopPageLoad // MARK: - DuckPlayer Overlay Navigation case duckPlayerYouTubeOverlayNavigationBack @@ -1702,6 +1705,9 @@ extension Pixel.Event { case .protectedDataUnavailableWhenBecomeActive: return "m_protected_data_unavailable_when_become_active" case .statisticsLoaderATBStateMismatch: return "m_statistics_loader_atb_state_mismatch" case .adAttributionReportStateMismatch: return "m_ad_attribution_report_state_mismatch" + + // MARK: Browsing + case .stopPageLoad: return "m_stop-page-load" // MARK: - DuckPlayer Overlay Navigation case .duckPlayerYouTubeOverlayNavigationBack: return "duckplayer.youtube.overlay.navigation.back" @@ -1710,8 +1716,7 @@ extension Pixel.Event { case .duckPlayerYouTubeOverlayNavigationOutsideYoutube: return "duckplayer.youtube.overlay.navigation.outside-youtube" case .duckPlayerYouTubeOverlayNavigationClosed: return "duckplayer.youtube.overlay.navigation.closed" case .duckPlayerYouTubeNavigationIdle30: return "duckplayer.youtube.overlay.idle-30" - - + } } } diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 84113f95a0..401aeaa3e7 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -299,6 +299,7 @@ 6F04224D2CD2A3AD00729FA6 /* StorageInconsistencyMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F98573F2CD2933B001BE9A0 /* StorageInconsistencyMonitor.swift */; }; 6F0FEF6B2C516D540090CDE4 /* NewTabPageSettingsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0FEF6A2C516D540090CDE4 /* NewTabPageSettingsStorage.swift */; }; 6F0FEF6D2C52639E0090CDE4 /* ReorderableForEach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0FEF6C2C52639E0090CDE4 /* ReorderableForEach.swift */; }; + 6F3529FF2CDCEDFF00A59170 /* OmniBarLoadingStateBearerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F3529FE2CDCEDF700A59170 /* OmniBarLoadingStateBearerTests.swift */; }; 6F35379E2C4AAF2E009F8717 /* NewTabPageSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F35379D2C4AAF2E009F8717 /* NewTabPageSettingsView.swift */; }; 6F3537A02C4AAFD2009F8717 /* NewTabPageSettingsSectionItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F35379F2C4AAFD2009F8717 /* NewTabPageSettingsSectionItemView.swift */; }; 6F3537A22C4AB97A009F8717 /* NewTabPageSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F3537A12C4AB97A009F8717 /* NewTabPageSettingsModel.swift */; }; @@ -1599,6 +1600,7 @@ 6F03CB082C32F331004179A8 /* PixelFiringAsync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelFiringAsync.swift; sourceTree = ""; }; 6F0FEF6A2C516D540090CDE4 /* NewTabPageSettingsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTabPageSettingsStorage.swift; sourceTree = ""; }; 6F0FEF6C2C52639E0090CDE4 /* ReorderableForEach.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReorderableForEach.swift; sourceTree = ""; }; + 6F3529FE2CDCEDF700A59170 /* OmniBarLoadingStateBearerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OmniBarLoadingStateBearerTests.swift; sourceTree = ""; }; 6F35379D2C4AAF2E009F8717 /* NewTabPageSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTabPageSettingsView.swift; sourceTree = ""; }; 6F35379F2C4AAFD2009F8717 /* NewTabPageSettingsSectionItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTabPageSettingsSectionItemView.swift; sourceTree = ""; }; 6F3537A12C4AB97A009F8717 /* NewTabPageSettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTabPageSettingsModel.swift; sourceTree = ""; }; @@ -6309,6 +6311,7 @@ F1D477C71F2139210031ED49 /* OmniBar */ = { isa = PBXGroup; children = ( + 6F3529FE2CDCEDF700A59170 /* OmniBarLoadingStateBearerTests.swift */, BBFF18B02C76448100C48D7D /* QuerySubmittedTests.swift */, 8588026424E4209900C24AB6 /* LargeOmniBarStateTests.swift */, 85F20005221702F7006BB258 /* AddressDisplayHelperTests.swift */, @@ -8107,6 +8110,7 @@ 9F4CC51D2C48D240006A96EB /* CoreDataDatabaseTestUtilities.swift in Sources */, C185ED672BD43DA100BAE9DC /* ImportPasswordsStatusHandlerTests.swift in Sources */, F198D7981E3A45D90088DA8A /* WKWebViewConfigurationExtensionTests.swift in Sources */, + 6F3529FF2CDCEDFF00A59170 /* OmniBarLoadingStateBearerTests.swift in Sources */, 564DE45E2C45218500D23241 /* OnboardingNavigationDelegateTests.swift in Sources */, C14E2F7729DE14EA002AC515 /* AutofillInterfaceUsernameTruncatorTests.swift in Sources */, 9F7CFF782C86E3E10012833E /* OnboardingManagerTests.swift in Sources */, diff --git a/DuckDuckGo/Base.lproj/OmniBar.xib b/DuckDuckGo/Base.lproj/OmniBar.xib index c0a18404df..0cd7d0a6c2 100644 --- a/DuckDuckGo/Base.lproj/OmniBar.xib +++ b/DuckDuckGo/Base.lproj/OmniBar.xib @@ -82,10 +82,10 @@ - + - + @@ -217,7 +217,7 @@ - + @@ -260,7 +260,7 @@ + @@ -398,6 +409,7 @@ + @@ -449,6 +461,7 @@ + diff --git a/DuckDuckGo/BlankSnapshotViewController.swift b/DuckDuckGo/BlankSnapshotViewController.swift index 9c55649c0d..0268aa3f2b 100644 --- a/DuckDuckGo/BlankSnapshotViewController.swift +++ b/DuckDuckGo/BlankSnapshotViewController.swift @@ -162,7 +162,7 @@ extension BlankSnapshotViewController: UICollectionViewDataSource { } extension BlankSnapshotViewController: OmniBarDelegate { - + func onVoiceSearchPressed() { // No-op } @@ -202,6 +202,10 @@ extension BlankSnapshotViewController: OmniBarDelegate { func onClearPressed() { // No-op } + + func onAbortPressed() { + // no-op + } } extension BlankSnapshotViewController: TabSwitcherButtonDelegate { diff --git a/DuckDuckGo/LargeOmniBarState.swift b/DuckDuckGo/LargeOmniBarState.swift index eb543f9f96..f80578a679 100644 --- a/DuckDuckGo/LargeOmniBarState.swift +++ b/DuckDuckGo/LargeOmniBarState.swift @@ -22,7 +22,7 @@ import Core struct LargeOmniBarState { - struct HomeEmptyEditingState: OmniBarState { + struct HomeEmptyEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = true let showBackButton: Bool = true let showForwardButton: Bool = true @@ -33,27 +33,37 @@ struct LargeOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = false + let showAbort = false let showRefresh = false let showMenu = false let showSettings = true let showCancel: Bool = false var name: String { return "Pad" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } var onTextClearedState: OmniBarState { return self } - var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onBrowsingStoppedState: OmniBarState { return self } var onEnterPadState: OmniBarState { return self } - var onEnterPhoneState: OmniBarState { return SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onReloadState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEnterPhoneState: OmniBarState { return SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onReloadState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showSearchLoupe: Bool { !voiceSearchHelper.isVoiceSearchEnabled } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool + + func withLoading() -> LargeOmniBarState.HomeEmptyEditingState { + Self.init(voiceSearchHelper: voiceSearchHelper, isLoading: true) + } + + func withoutLoading() -> LargeOmniBarState.HomeEmptyEditingState { + Self.init(voiceSearchHelper: voiceSearchHelper, isLoading: false) + } } - struct HomeTextEditingState: OmniBarState { + struct HomeTextEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = true let showBackButton: Bool = true let showForwardButton: Bool = true @@ -64,27 +74,29 @@ struct LargeOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = true + let showAbort = false let showRefresh = false let showMenu = false let showSettings = true let showCancel: Bool = false var name: String { return "Pad" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } - var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onTextEnteredState: OmniBarState { return self } - var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPadState: OmniBarState { return self } - var onEnterPhoneState: OmniBarState { return SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } - var onReloadState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEnterPhoneState: OmniBarState { return SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onReloadState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showSearchLoupe: Bool { !voiceSearchHelper.isVoiceSearchEnabled } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct HomeNonEditingState: OmniBarState { + struct HomeNonEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = true let showBackButton: Bool = true let showForwardButton: Bool = true @@ -96,26 +108,28 @@ struct LargeOmniBarState { let showPrivacyIcon = false let showBackground = true let showClear = false + let showAbort = false let showRefresh = false let showMenu = false let showSettings = true let showCancel: Bool = false var name: String { return "Pad" + Type.name(self) } var onEditingStoppedState: OmniBarState { return self } - var onEditingStartedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStartedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPadState: OmniBarState { return self } - var onEnterPhoneState: OmniBarState { return SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onReloadState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEnterPhoneState: OmniBarState { return SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onReloadState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct BrowsingEmptyEditingState: OmniBarState { + struct BrowsingEmptyEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = true let showBackButton: Bool = true let showForwardButton: Bool = true @@ -126,27 +140,29 @@ struct LargeOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = false + let showAbort = false let showRefresh = false let showMenu = true let showSettings = false let showCancel: Bool = false var name: String { return "Pad" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } var onTextClearedState: OmniBarState { return self } - var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onBrowsingStartedState: OmniBarState { return self } - var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPadState: OmniBarState { return self } - var onEnterPhoneState: OmniBarState { return SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onReloadState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEnterPhoneState: OmniBarState { return SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onReloadState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showSearchLoupe: Bool { !voiceSearchHelper.isVoiceSearchEnabled } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct BrowsingTextEditingState: OmniBarState { + struct BrowsingTextEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = true let showBackButton: Bool = true let showForwardButton: Bool = true @@ -157,27 +173,29 @@ struct LargeOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = true + let showAbort = false let showRefresh = false let showMenu = true let showSettings = false let showCancel: Bool = false var name: String { return "Pad" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } - var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onTextEnteredState: OmniBarState { return self } var onBrowsingStartedState: OmniBarState { return self } - var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPadState: OmniBarState { return self } - var onEnterPhoneState: OmniBarState { return SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } - var onReloadState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEnterPhoneState: OmniBarState { return SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onReloadState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showSearchLoupe: Bool { !voiceSearchHelper.isVoiceSearchEnabled } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct BrowsingNonEditingState: OmniBarState { + struct BrowsingNonEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = true let showBackButton: Bool = true let showForwardButton: Bool = true @@ -189,23 +207,25 @@ struct LargeOmniBarState { let showPrivacyIcon = true let showBackground = true let showClear = false - let showRefresh = true + var showAbort: Bool { isLoading } + var showRefresh: Bool { !isLoading } let showMenu = true let showSettings = false let showCancel: Bool = false let showVoiceSearch = false var name: String { return "Pad" + Type.name(self) } var onEditingStoppedState: OmniBarState { return self } - var onEditingStartedState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStartedState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onBrowsingStartedState: OmniBarState { return self } - var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPadState: OmniBarState { return self } - var onEnterPhoneState: OmniBarState { return SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onReloadState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEnterPhoneState: OmniBarState { return SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onReloadState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } } diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index de806d9737..75c5777782 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -950,6 +950,10 @@ class MainViewController: UIViewController { loadUrl(url) } + func stopLoading() { + currentTab?.stopLoading() + } + func loadUrl(_ url: URL, fromExternalLink: Bool = false) { prepareTabForRequest { self.currentTab?.load(url: url) @@ -1072,6 +1076,8 @@ class MainViewController: UIViewController { } private func refreshOmniBar() { + updateOmniBarLoadingState() + guard let tab = currentTab, tab.link != nil else { viewCoordinator.omniBar.stopBrowsing() return @@ -1086,10 +1092,18 @@ class MainViewController: UIViewController { } else { viewCoordinator.omniBar.resetPrivacyIcon(for: tab.url) } - + viewCoordinator.omniBar.startBrowsing() } + private func updateOmniBarLoadingState() { + if currentTab?.isLoading == true { + omniBar.startLoading() + } else { + omniBar.stopLoading() + } + } + func dismissOmniBar() { viewCoordinator.omniBar.resignFirstResponder() hideSuggestionTray() @@ -1948,6 +1962,11 @@ extension MainViewController: OmniBarDelegate { performCancel() } + func onAbortPressed() { + Pixel.fire(pixel: .stopPageLoad) + stopLoading() + } + func onClearPressed() { fireControllerAwarePixel(ntp: .addressBarClearPressedOnNTP, serp: .addressBarClearPressedOnSERP, diff --git a/DuckDuckGo/OmniBar.swift b/DuckDuckGo/OmniBar.swift index c2b6877be7..91a1214bd4 100644 --- a/DuckDuckGo/OmniBar.swift +++ b/DuckDuckGo/OmniBar.swift @@ -50,7 +50,8 @@ class OmniBar: UIView { @IBOutlet weak var cancelButton: UIButton! @IBOutlet weak var refreshButton: UIButton! @IBOutlet weak var voiceSearchButton: UIButton! - + @IBOutlet weak var abortButton: UIButton! + @IBOutlet weak var bookmarksButton: UIButton! @IBOutlet weak var backButton: UIButton! @IBOutlet weak var forwardButton: UIButton! @@ -80,7 +81,7 @@ class OmniBar: UIView { static func loadFromXib(voiceSearchHelper: VoiceSearchHelperProtocol) -> OmniBar { let omniBar = OmniBar.load(nibName: "OmniBar") - omniBar.state = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) + omniBar.state = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: false) omniBar.refreshState(omniBar.state) return omniBar @@ -92,7 +93,7 @@ class OmniBar: UIView { // Tests require this init(voiceSearchHelper: VoiceSearchHelperProtocol, frame: CGRect) { - self.state = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) + self.state = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: false) super.init(frame: frame) } @@ -249,6 +250,14 @@ class OmniBar: UIView { refreshState(state.onBrowsingStoppedState) } + func startLoading() { + refreshState(state.withLoading()) + } + + func stopLoading() { + refreshState(state.withoutLoading()) + } + func removeTextSelection() { textField.selectedTextRange = nil } @@ -350,9 +359,9 @@ class OmniBar: UIView { textField.selectedTextRange = textField.textRange(from: fromPosition, to: textField.endOfDocument) } - fileprivate func refreshState(_ newState: OmniBarState) { - if state.name != newState.name { - Logger.general.debug("OmniBar entering \(newState.name) from \(self.state.name)") + fileprivate func refreshState(_ newState: any OmniBarState) { + if !newState.isEquivalent(to: state) { + Logger.general.debug("OmniBar entering \(newState.description) from \(self.state.description)") if newState.clearTextOnStart { clear() } @@ -370,6 +379,7 @@ class OmniBar: UIView { setVisibility(cancelButton, hidden: !state.showCancel) setVisibility(refreshButton, hidden: !state.showRefresh) setVisibility(voiceSearchButton, hidden: !state.showVoiceSearch) + setVisibility(abortButton, hidden: !state.showAbort) setVisibility(backButton, hidden: !state.showBackButton) setVisibility(forwardButton, hidden: !state.showForwardButton) @@ -462,7 +472,11 @@ class OmniBar: UIView { @IBAction func onVoiceSearchButtonPressed(_ sender: UIButton) { omniDelegate?.onVoiceSearchPressed() } - + + @IBAction func onAbortButtonPressed(_ sender: Any) { + omniDelegate?.onAbortPressed() + } + @IBAction func onClearButtonPressed(_ sender: Any) { omniDelegate?.onClearPressed() refreshState(state.onTextClearedState) diff --git a/DuckDuckGo/OmniBarDelegate.swift b/DuckDuckGo/OmniBarDelegate.swift index e1153fd7a3..d5122cac32 100644 --- a/DuckDuckGo/OmniBarDelegate.swift +++ b/DuckDuckGo/OmniBarDelegate.swift @@ -47,6 +47,8 @@ protocol OmniBarDelegate: AnyObject { func onClearPressed() + func onAbortPressed() + func onCancelPressed() func onEnterPressed() diff --git a/DuckDuckGo/OmniBarState.swift b/DuckDuckGo/OmniBarState.swift index db7330bd9c..3e486652c5 100644 --- a/DuckDuckGo/OmniBarState.swift +++ b/DuckDuckGo/OmniBarState.swift @@ -20,8 +20,10 @@ import Foundation import Core -protocol OmniBarState { - +protocol OmniBarState: CustomStringConvertible { + + var name: String { get } + var hasLargeWidth: Bool { get } var showBackButton: Bool { get } var showForwardButton: Bool { get } @@ -39,7 +41,8 @@ protocol OmniBarState { var showMenu: Bool { get } var showSettings: Bool { get } var showVoiceSearch: Bool { get } - var name: String { get } + var showAbort: Bool { get } + var onEditingStoppedState: OmniBarState { get } var onEditingSuspendedState: OmniBarState { get } var onEditingStartedState: OmniBarState { get } @@ -50,10 +53,43 @@ protocol OmniBarState { var onEnterPhoneState: OmniBarState { get } var onEnterPadState: OmniBarState { get } var onReloadState: OmniBarState { get } + + var voiceSearchHelper: VoiceSearchHelperProtocol { get } + + var isLoading: Bool { get } + + func withLoading() -> Self + func withoutLoading() -> Self + + func isEquivalent(to other: OmniBarState) -> Bool } extension OmniBarState { + func isEquivalent(to other: OmniBarState) -> Bool { + name == other.name && isLoading == other.isLoading + } + + var description: String { + "\(name)\(isLoading ? " (loading)" : "")" + } + var onEditingSuspendedState: OmniBarState { - UniversalOmniBarState.EditingSuspendedState(baseState: self.onEditingStartedState) + UniversalOmniBarState.EditingSuspendedState(baseState: onEditingStartedState, + voiceSearchHelper: voiceSearchHelper, + isLoading: isLoading) + } +} + +protocol OmniBarLoadingBearerStateCreating { + init(voiceSearchHelper: VoiceSearchHelperProtocol, isLoading: Bool) +} + +extension OmniBarLoadingBearerStateCreating where Self: OmniBarState { + func withLoading() -> Self { + Self.init(voiceSearchHelper: voiceSearchHelper, isLoading: true) + } + + func withoutLoading() -> Self { + Self.init(voiceSearchHelper: voiceSearchHelper, isLoading: false) } } diff --git a/DuckDuckGo/SmallOmniBarState.swift b/DuckDuckGo/SmallOmniBarState.swift index ee47e1af6d..f00abfac23 100644 --- a/DuckDuckGo/SmallOmniBarState.swift +++ b/DuckDuckGo/SmallOmniBarState.swift @@ -22,7 +22,7 @@ import Core struct SmallOmniBarState { - struct HomeEmptyEditingState: OmniBarState { + struct HomeEmptyEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = false let showBackButton: Bool = false let showForwardButton: Bool = false @@ -33,27 +33,29 @@ struct SmallOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = false + let showAbort = false let showRefresh = false let showMenu = false let showSettings = false let showCancel: Bool = true var name: String { return "Phone" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } var onTextClearedState: OmniBarState { return self } - var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onBrowsingStoppedState: OmniBarState { return self } - var onEnterPadState: OmniBarState { return LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEnterPadState: OmniBarState { return LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPhoneState: OmniBarState { return self } - var onReloadState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onReloadState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showSearchLoupe: Bool { !voiceSearchHelper.isSpeechRecognizerAvailable } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct HomeTextEditingState: OmniBarState { + struct HomeTextEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = false let showBackButton: Bool = false let showForwardButton: Bool = false @@ -64,27 +66,29 @@ struct SmallOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = true + let showAbort = false let showRefresh = false let showMenu = false let showSettings = false let showCancel: Bool = true let showVoiceSearch = false var name: String { return "Phone" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } - var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onTextEnteredState: OmniBarState { return self } - var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onEnterPadState: OmniBarState { return LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onEnterPadState: OmniBarState { return LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPhoneState: OmniBarState { return self } - var onReloadState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onReloadState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showSearchLoupe: Bool { !voiceSearchHelper.isSpeechRecognizerAvailable } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct HomeNonEditingState: OmniBarState { + struct HomeNonEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = false let showBackButton: Bool = false let showForwardButton: Bool = false @@ -96,26 +100,29 @@ struct SmallOmniBarState { let showPrivacyIcon = false let showBackground = true let showClear = false + let showAbort = false let showRefresh = false let showMenu = false let showSettings = true let showCancel: Bool = false var name: String { return "Phone" + Type.name(self) } var onEditingStoppedState: OmniBarState { return self } - var onEditingStartedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onEnterPadState: OmniBarState { return LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStartedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextClearedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextEnteredState: OmniBarState { return HomeTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStartedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onEnterPadState: OmniBarState { return LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPhoneState: OmniBarState { return self } - var onReloadState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onReloadState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct BrowsingEmptyEditingState: OmniBarState { + struct BrowsingEmptyEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = false let showBackButton: Bool = false let showForwardButton: Bool = false @@ -126,27 +133,30 @@ struct SmallOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = false + let showAbort = false let showRefresh = false let showMenu = false let showSettings = false let showCancel: Bool = true var name: String { return "Phone" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } var onTextClearedState: OmniBarState { return self } - var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onBrowsingStartedState: OmniBarState { return self } - var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPhoneState: OmniBarState { return self } - var onReloadState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onReloadState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var showSearchLoupe: Bool { !voiceSearchHelper.isVoiceSearchEnabled } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct BrowsingTextEditingState: OmniBarState { + struct BrowsingTextEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = false let showBackButton: Bool = false let showForwardButton: Bool = false @@ -157,27 +167,30 @@ struct SmallOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = true + let showAbort = false let showRefresh = false let showMenu = false let showSettings = false let showCancel: Bool = true let showVoiceSearch = false var name: String { return "Phone" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } - var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onTextEnteredState: OmniBarState { return self } var onBrowsingStartedState: OmniBarState { return self } - var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPhoneState: OmniBarState { return self } - var onReloadState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onReloadState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var showSearchLoupe: Bool { !voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct BrowsingNonEditingState: OmniBarState { + struct BrowsingNonEditingState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = false let showBackButton: Bool = false let showForwardButton: Bool = false @@ -189,26 +202,28 @@ struct SmallOmniBarState { let showPrivacyIcon = true let showBackground = true let showClear = false - let showRefresh = true + var showAbort: Bool { isLoading } + var showRefresh: Bool { !isLoading } let showMenu = false let showSettings = false let showCancel: Bool = false let showVoiceSearch = false var name: String { return "Phone" + Type.name(self) } var onEditingStoppedState: OmniBarState { return self } - var onEditingStartedState: OmniBarState { return BrowsingTextEditingStartedState(voiceSearchHelper: voiceSearchHelper) } - var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStartedState: OmniBarState { return BrowsingTextEditingStartedState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onBrowsingStartedState: OmniBarState { return self } - var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper) } - var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStoppedState: OmniBarState { return HomeNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPhoneState: OmniBarState { return self } - var onReloadState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onReloadState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } - struct BrowsingTextEditingStartedState: OmniBarState { + struct BrowsingTextEditingStartedState: OmniBarState, OmniBarLoadingBearerStateCreating { let hasLargeWidth: Bool = false let showBackButton: Bool = false let showForwardButton: Bool = false @@ -219,23 +234,25 @@ struct SmallOmniBarState { let showPrivacyIcon = false let showBackground = false let showClear = true + let showAbort = false let showRefresh = false let showMenu = false let showSettings = false let showCancel: Bool = true var name: String { return "Phone" + Type.name(self) } - var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper) } + var onEditingStoppedState: OmniBarState { return BrowsingNonEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEditingStartedState: OmniBarState { return self } - var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onTextClearedState: OmniBarState { return BrowsingEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onTextEnteredState: OmniBarState { return BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onBrowsingStartedState: OmniBarState { return self } - var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper) } - var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper) } + var onBrowsingStoppedState: OmniBarState { return HomeEmptyEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } + var onEnterPadState: OmniBarState { return LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var onEnterPhoneState: OmniBarState { return self } - var onReloadState: OmniBarState { return BrowsingTextEditingStartedState(voiceSearchHelper: voiceSearchHelper) } + var onReloadState: OmniBarState { return BrowsingTextEditingStartedState(voiceSearchHelper: voiceSearchHelper, isLoading: isLoading) } var showSearchLoupe: Bool { !voiceSearchHelper.isVoiceSearchEnabled } var showVoiceSearch: Bool { voiceSearchHelper.isVoiceSearchEnabled } let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool } } diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index 6be661152c..5609aec797 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -66,7 +66,12 @@ class TabViewController: UIViewController { private let instrumentation = TabInstrumentation() var isLinkPreview = false - + + // A workaround for an issue when in some cases webview reports `isLoading == true` when it was stoppped. + var isLoading: Bool { + webView.isLoading && !wasLoadingStoppedExternally + } + var openedByPage = false weak var openingTab: TabViewController? { didSet { @@ -163,6 +168,9 @@ class TabViewController: UIViewController { // Temporary to gather some data. Fire a follow up if no trackers dax dialog was shown and then trackers appear. private var fireWoFollowUp = false + // Indicates if there was an external call to stop loading current request. Resets on new load request, refresh and failures. + private var wasLoadingStoppedExternally = false + // In certain conditions we try to present a dax dialog when one is already showing, so check to ensure we don't var isShowingFullScreenDaxDialog = false @@ -660,6 +668,7 @@ class TabViewController: UIViewController { } public func load(url: URL) { + wasLoadingStoppedExternally = false webView.stopLoading() dismissJSAlertIfNeeded() @@ -828,6 +837,7 @@ class TabViewController: UIViewController { } public func reload() { + wasLoadingStoppedExternally = false updateContentMode() cachedRuntimeConfigurationForDomain = [:] if let handler = duckPlayerNavigationHandler { @@ -835,6 +845,7 @@ class TabViewController: UIViewController { } else { webView.reload() } + delegate?.tabLoadingStateDidChange(tab: self) privacyDashboard?.dismiss(animated: true) } @@ -1168,6 +1179,14 @@ class TabViewController: UIViewController { UIPasteboard.general.string = text } + func stopLoading() { + webView.stopLoading() + wasLoadingStoppedExternally = true + + hideProgressIndicator() + delegate?.tabLoadingStateDidChange(tab: self) + } + private func cleanUpBeforeClosing() { let job = { [weak webView, userContentController] in userContentController.cleanUpBeforeClosing() @@ -1606,6 +1625,7 @@ extension TabViewController: WKNavigationDelegate { } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { + Logger.general.debug("didFailNavigation; error: \(error)") adClickAttributionDetection.onDidFailNavigation() hideProgressIndicator() webpageDidFailToLoad() @@ -1617,6 +1637,9 @@ extension TabViewController: WKNavigationDelegate { private func webpageDidFailToLoad() { Logger.general.debug("webpageLoading failed") + + wasLoadingStoppedExternally = false + if isError { showBars(animated: true) privacyInfo = nil @@ -1627,6 +1650,7 @@ extension TabViewController: WKNavigationDelegate { } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { + Logger.general.debug("didFailProvisionalNavigation; error: \(error)") adClickAttributionDetection.onDidFailNavigation() hideProgressIndicator() linkProtection.setMainFrameUrl(nil) @@ -1639,7 +1663,7 @@ extension TabViewController: WKNavigationDelegate { if error.code == 102 && error.domain == "WebKitErrorDomain" { return } - + if let url = url, let domain = url.host, error.code == Constants.frameLoadInterruptedErrorCode { @@ -1650,6 +1674,15 @@ extension TabViewController: WKNavigationDelegate { self.url = webView.url } + // Bail out before showing error when navigation was cancelled by the user + if error.code == NSURLErrorCancelled && error.domain == NSURLErrorDomain { + webpageDidFailToLoad() + + // Reset url to current one, as navigation was not successful + self.url = webView.url + return + } + // wait before showing errors in case they recover automatically DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.showErrorNow() diff --git a/DuckDuckGo/UniversalOmniBarState.swift b/DuckDuckGo/UniversalOmniBarState.swift index 2e15892c02..3dd7fd48f7 100644 --- a/DuckDuckGo/UniversalOmniBarState.swift +++ b/DuckDuckGo/UniversalOmniBarState.swift @@ -36,19 +36,31 @@ enum UniversalOmniBarState { var showPrivacyIcon: Bool { baseState.showPrivacyIcon } var showBackground: Bool { baseState.showBackground } var showClear: Bool { false } + var showAbort: Bool { baseState.showAbort } var showRefresh: Bool { baseState.showRefresh } var showMenu: Bool { baseState.showMenu } var showSettings: Bool { baseState.showSettings } var showVoiceSearch: Bool { baseState.showVoiceSearch } var name: String { Type.name(self) } - var onEditingStoppedState: OmniBarState { baseState.onEditingStoppedState } - var onEditingStartedState: OmniBarState { baseState.onEditingStartedState } - var onTextClearedState: OmniBarState { baseState.onTextClearedState } - var onTextEnteredState: OmniBarState { baseState.onTextEnteredState } - var onBrowsingStartedState: OmniBarState { baseState.onBrowsingStartedState } - var onBrowsingStoppedState: OmniBarState { baseState.onBrowsingStoppedState } - var onEnterPhoneState: OmniBarState { baseState.onEnterPhoneState } - var onEnterPadState: OmniBarState { baseState.onEnterPadState } - var onReloadState: OmniBarState { baseState.onReloadState } + var onEditingStoppedState: any OmniBarState { baseState.onEditingStoppedState } + var onEditingStartedState: any OmniBarState { baseState.onEditingStartedState } + var onTextClearedState: any OmniBarState { baseState.onTextClearedState } + var onTextEnteredState: any OmniBarState { baseState.onTextEnteredState } + var onBrowsingStartedState: any OmniBarState { baseState.onBrowsingStartedState } + var onBrowsingStoppedState: any OmniBarState { baseState.onBrowsingStoppedState } + var onEnterPhoneState: any OmniBarState { baseState.onEnterPhoneState } + var onEnterPadState: any OmniBarState { baseState.onEnterPadState } + var onReloadState: any OmniBarState { baseState.onReloadState } + + let voiceSearchHelper: VoiceSearchHelperProtocol + let isLoading: Bool + + func withLoading() -> UniversalOmniBarState.EditingSuspendedState { + Self.init(baseState: baseState, voiceSearchHelper: voiceSearchHelper, isLoading: true) + } + + func withoutLoading() -> UniversalOmniBarState.EditingSuspendedState { + Self.init(baseState: baseState, voiceSearchHelper: voiceSearchHelper, isLoading: false) + } } } diff --git a/DuckDuckGoTests/LargeOmniBarStateTests.swift b/DuckDuckGoTests/LargeOmniBarStateTests.swift index f65af8ec0a..caeedfc75d 100644 --- a/DuckDuckGoTests/LargeOmniBarStateTests.swift +++ b/DuckDuckGoTests/LargeOmniBarStateTests.swift @@ -28,7 +28,7 @@ class LargeOmniBarStateTests: XCTestCase { let disabledVoiceSearchHelper = MockVoiceSearchHelper(isSpeechRecognizerAvailable: false) func testWhenInHomeEmptyEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) @@ -38,7 +38,9 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) - + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) + XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) XCTAssertTrue(testee.showForwardButton) @@ -47,7 +49,7 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenInHomeEmptyEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) @@ -57,7 +59,9 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) - + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) + XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) XCTAssertTrue(testee.showForwardButton) @@ -66,42 +70,42 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenEnteringHomeEmptyEditingStateThenTextIsCleared() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.clearTextOnStart) } func testWhenInHomeEmptyEditingStateThenEditingStartedMaintainsState() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenEditingStoppedTrainsitionsToNonEditingState() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenClearingTextMaintainsState() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenBrowsingStartedTransitionsToBrowsingNonEditingState() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenBrowsingStoppedMaintainsState() { - let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) @@ -111,7 +115,9 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) - + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) + XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) XCTAssertTrue(testee.showForwardButton) @@ -120,7 +126,7 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenInHomeTextEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) @@ -130,7 +136,9 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) - + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) + XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) XCTAssertTrue(testee.showForwardButton) @@ -138,42 +146,42 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showShareButton) } func testWhenEnteringHomeTextEditingStateThenTextIsNotCleared() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.clearTextOnStart) } func testWhenInHomeTextEditingStateThenEditingStartedMaintainsState() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenEditingStoppedTrainsitionsToNonEditingState() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenEnteringTextMaintainstState() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenBrowsingStartedTransitionsToBrowsingNonEditingState() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenBrowsingStoppedTransitionsToHomeTextEditingState() { - let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -182,6 +190,8 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) @@ -189,9 +199,9 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showBookmarksButton) XCTAssertFalse(testee.showShareButton) } - + func testWhenInHomeNonEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -200,6 +210,8 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) @@ -209,42 +221,42 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenEnteringHomeNonEditingStateThenTextIsCleared() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.clearTextOnStart) } func testWhenInHomeNonEditingStateThenEditingStartedTransitionsToEmptyEditingState() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenEditingStoppedMaintainsState() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenBrowsingStartedTransitionsToBrowsingNonEditingState() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenBrowsingStoppedTransitionsToHomeNonEditingState() { - let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowserEmptyEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -253,6 +265,8 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) @@ -262,7 +276,7 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenInBrowserEmptyEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -271,6 +285,8 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) @@ -280,42 +296,42 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenEnteringBrowserEmptyEditingStateThenTextIsCleared() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.clearTextOnStart) } func testWhenInBrowsingEmptyEditingStateThenEditingStartedMaintainsState() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenEditingStoppedTrainsitionsToBrowsingNonEditingState() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenClearingMaintainsState() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenBrowsingStartedMaintainsState() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenBrowsingStoppedTransitionsToHomeEmptyEditingState() { - let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertTrue(testee.showClear) @@ -324,6 +340,8 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) @@ -333,7 +351,7 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenInBrowsingTextEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertTrue(testee.showClear) @@ -342,6 +360,8 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) @@ -351,42 +371,42 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenEnteringBrowsingTextEditingStateThenTextIsMaintained() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.clearTextOnStart) } func testWhenInBrowsingTextEditingStateThenEditingStartedMaintainsState() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenEditingStoppedTrainsitionsToNonEditingState() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenEnteringTextMaintainstState() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenBrowsingStartedMaintainsState() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenBrowsingStoppedTransitionsToHomeTextEditingState() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenCorrectButtonsAreShown() { - let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.showBackground) XCTAssertTrue(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -394,7 +414,9 @@ class LargeOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showSettings) XCTAssertFalse(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) - + XCTAssertFalse(testee.showAbort) + XCTAssertTrue(testee.showRefresh) + XCTAssertTrue(testee.hasLargeWidth) XCTAssertTrue(testee.showBackButton) XCTAssertTrue(testee.showForwardButton) @@ -403,37 +425,37 @@ class LargeOmniBarStateTests: XCTestCase { } func testWhenEnteringBrowsingNonEditingStateThenTextIsMaintained() { - let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.clearTextOnStart) } func testWhenInBrowsingNonEditingStateThenEditingStartedTransitionsToTextEditingState() { - let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenEditingStoppedMaintainsState() { - let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, LargeOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, LargeOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenBrowsingStartedMaintainstState() { - let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenBrowsingStoppedTransitionsToHomeNonEditingState() { - let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = LargeOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, LargeOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } } diff --git a/DuckDuckGoTests/OmniBarLoadingStateBearerTests.swift b/DuckDuckGoTests/OmniBarLoadingStateBearerTests.swift new file mode 100644 index 0000000000..b8888ed716 --- /dev/null +++ b/DuckDuckGoTests/OmniBarLoadingStateBearerTests.swift @@ -0,0 +1,81 @@ +// +// OmniBarLoadingStateBearerTests.swift +// DuckDuckGo +// +// 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 +@testable import DuckDuckGo + +final class OmniBarLoadingStateBearerTests: XCTestCase { + + static let unaffectedByLoadingStates: [(OmniBarState & OmniBarLoadingBearerStateCreating).Type] = [ + SmallOmniBarState.BrowsingEmptyEditingState.self, + SmallOmniBarState.BrowsingTextEditingStartedState.self, + SmallOmniBarState.BrowsingTextEditingState.self, + SmallOmniBarState.HomeEmptyEditingState.self, + SmallOmniBarState.HomeNonEditingState.self, + SmallOmniBarState.HomeTextEditingState.self, + LargeOmniBarState.BrowsingEmptyEditingState.self, + LargeOmniBarState.BrowsingTextEditingState.self, + LargeOmniBarState.HomeEmptyEditingState.self, + LargeOmniBarState.HomeNonEditingState.self, + LargeOmniBarState.HomeTextEditingState.self + ] + + static let affectedByLoadingStates: [(OmniBarState & OmniBarLoadingBearerStateCreating).Type] = [ + SmallOmniBarState.BrowsingNonEditingState.self, + LargeOmniBarState.BrowsingNonEditingState.self + ] + + func testUnaffectedByLoadingStatesDoNotShowAbortButtonWhenLoading() { + for state in Self.unaffectedByLoadingStates { + let state = state.init(voiceSearchHelper: MockVoiceSearchHelper(isSpeechRecognizerAvailable: false), isLoading: true) + + XCTAssertFalse(state.showAbort) + } + } + + func testAffectedByLoadingStatesShowAbortInPlaceOfRefreshButtonWhenLoading() { + for state in Self.affectedByLoadingStates { + let state = state.init(voiceSearchHelper: MockVoiceSearchHelper(isSpeechRecognizerAvailable: false), isLoading: true) + + XCTAssertTrue(state.showAbort) + XCTAssertFalse(state.showRefresh) + } + } + + func testLoadingStateIsPreservedAcrossStates() { + let initialState = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: MockVoiceSearchHelper(isSpeechRecognizerAvailable: false), isLoading: false) + + let lastState = initialState + .withLoading() + .onBrowsingStartedState + .onBrowsingStoppedState + .onEditingSuspendedState + .onEnterPadState + .onBrowsingStartedState + .onEditingStoppedState + .onTextClearedState + .onTextEnteredState + .onEnterPhoneState + .onTextClearedState + .onTextEnteredState + + XCTAssertTrue(lastState.isLoading) + XCTAssertFalse(lastState.withoutLoading().isLoading) + } +} diff --git a/DuckDuckGoTests/QuerySubmittedTests.swift b/DuckDuckGoTests/QuerySubmittedTests.swift index da37da1e9f..1ece6508c2 100644 --- a/DuckDuckGoTests/QuerySubmittedTests.swift +++ b/DuckDuckGoTests/QuerySubmittedTests.swift @@ -125,6 +125,9 @@ final class MockOmniBarDelegate: OmniBarDelegate { // MARK: - Unused methods + func onAbortPressed() { + } + func onEditingEnd() -> OmniBarEditingEndResult { return .dismissed } diff --git a/DuckDuckGoTests/SmallOmniBarStateTests.swift b/DuckDuckGoTests/SmallOmniBarStateTests.swift index 93941a66a2..3cc7f5bf49 100644 --- a/DuckDuckGoTests/SmallOmniBarStateTests.swift +++ b/DuckDuckGoTests/SmallOmniBarStateTests.swift @@ -28,7 +28,7 @@ class SmallOmniBarStateTests: XCTestCase { let disabledVoiceSearchHelper = MockVoiceSearchHelper(isSpeechRecognizerAvailable: false) func testWhenInHomeEmptyEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) @@ -38,6 +38,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -47,7 +49,7 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenInHomeEmptyEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) @@ -57,6 +59,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -66,42 +70,42 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenEnteringHomeEmptyEditingStateThenTextIsCleared() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.clearTextOnStart) } func testWhenInHomeEmptyEditingStateThenEditingStartedMaintainsState() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenEditingStoppedTrainsitionsToNonEditingState() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenClearingTextMaintainsState() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenBrowsingStartedTransitionsToBrowsingNonEditingState() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeEmptyEditingStateThenBrowsingStoppedMaintainsState() { - let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertTrue(testee.showClear) @@ -110,6 +114,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -119,7 +125,7 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenInHomeTextEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertTrue(testee.showClear) @@ -128,6 +134,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -137,42 +145,42 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenEnteringHomeTextEditingStateThenTextIsNotCleared() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.clearTextOnStart) } func testWhenInHomeTextEditingStateThenEditingStartedMaintainsState() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenEditingStoppedTrainsitionsToNonEditingState() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenEnteringTextMaintainsState() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenBrowsingStartedTransitionsToBrowsingNonEditingState() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeTextEditingStateThenBrowsingStoppedTransitionsToHomeTextEditingState() { - let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -181,6 +189,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -190,7 +200,7 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenInHomeNonEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -199,6 +209,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -208,42 +220,42 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenEnteringHomeNonEditingStateThenTextIsCleared() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.clearTextOnStart) } func testWhenInHomeNonEditingStateThenEditingStartedTransitionsToEmptyEditingState() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenEditingStoppedMaintainsState() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.HomeTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenBrowsingStartedTransitionsToBrowsingNonEditingState() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInHomeNonEditingStateThenBrowsingStoppedTransitionsToHomeNonEditingState() { - let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowserEmptyEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -252,6 +264,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -261,7 +275,7 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenInBrowserEmptyEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -270,6 +284,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertTrue(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -279,42 +295,42 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenEnteringBrowserEmptyEditingStateThenTextIsCleared() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.clearTextOnStart) } func testWhenInBrowsingEmptyEditingStateThenEditingStartedMaintainsState() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenEditingStoppedTrainsitionsToBrowsingNonEditingState() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenClearingMaintainsState() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenBrowsingStartedMaintainsState() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEmptyEditingStateThenBrowsingStoppedTransitionsToHomeEmptyEditingState() { - let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateWithoutVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: disabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertTrue(testee.showClear) @@ -323,6 +339,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertTrue(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -332,7 +350,7 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenInBrowsingTextEditingStateWithVoiceSearchThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.showBackground) XCTAssertFalse(testee.showPrivacyIcon) XCTAssertTrue(testee.showClear) @@ -341,6 +359,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertTrue(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) XCTAssertFalse(testee.showVoiceSearch) + XCTAssertFalse(testee.showAbort) + XCTAssertFalse(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -350,42 +370,42 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenEnteringBrowsingTextEditingStateThenTextIsMaintained() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.clearTextOnStart) } func testWhenInBrowsingTextEditingStateThenEditingStartedMaintainsState() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenEditingStoppedTrainsitionsToNonEditingState() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenEnteringTextMaintainstState() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenBrowsingStartedMaintainsState() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingTextEditingStateThenBrowsingStoppedTransitionsToHomeTextEditingState() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenCorrectButtonsAreShown() { - let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertTrue(testee.showBackground) XCTAssertTrue(testee.showPrivacyIcon) XCTAssertFalse(testee.showClear) @@ -393,6 +413,8 @@ class SmallOmniBarStateTests: XCTestCase { XCTAssertFalse(testee.showSettings) XCTAssertFalse(testee.showCancel) XCTAssertFalse(testee.showSearchLoupe) + XCTAssertFalse(testee.showAbort) + XCTAssertTrue(testee.showRefresh) XCTAssertFalse(testee.hasLargeWidth) XCTAssertFalse(testee.showBackButton) @@ -402,42 +424,42 @@ class SmallOmniBarStateTests: XCTestCase { } func testWhenEnteringBrowsingNonEditingStateThenTextIsMaintained() { - let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper) + let testee = SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) XCTAssertFalse(testee.clearTextOnStart) } func testWhenInBrowsingNonEditingStateThenToBrowsingTextEditingStartedState() { - let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.BrowsingTextEditingStartedState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStartedState.name, SmallOmniBarState.BrowsingTextEditingStartedState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingEditingStartedStateThenEnteringTextTransitionsToTextEditingState() { - let testee = SmallOmniBarState.BrowsingTextEditingStartedState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingTextEditingStartedState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenEditingStoppedMaintainsState() { - let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onEditingStoppedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenEnteringTextTransitionsToTextEditingState() { - let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextEnteredState.name, SmallOmniBarState.BrowsingTextEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenClearingTextTransitionsToEmptyEditingState() { - let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onTextClearedState.name, SmallOmniBarState.BrowsingEmptyEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenBrowsingStartedMaintainstState() { - let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStartedState.name, SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } func testWhenInBrowsingNonEditingStateThenBrowsingStoppedTransitionsToHomeNonEditingState() { - let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper) - XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper).name) + let testee = SmallOmniBarState.BrowsingNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false) + XCTAssertEqual(testee.onBrowsingStoppedState.name, SmallOmniBarState.HomeNonEditingState(voiceSearchHelper: enabledVoiceSearchHelper, isLoading: false).name) } }