From bd398e4ed5b478a4dff1dbeb787eb4bd47b6fc74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20=C5=9Apiewak?= Date: Wed, 3 Jul 2024 17:57:52 +0200 Subject: [PATCH] Add pixels to measure baseline for New Tab Page sections (#3024) --- Core/PixelEvent.swift | 13 +++++ DuckDuckGo.xcodeproj/project.pbxproj | 8 ++++ DuckDuckGo/BookmarksViewController.swift | 1 + .../HomePageDisplayDailyPixelBucket.swift | 47 ++++++++++++++++++ DuckDuckGo/HomeViewController.swift | 13 +++++ ...bViewControllerBrowsingMenuExtension.swift | 2 + ...HomePageDisplayDailyPixelBucketTests.swift | 48 +++++++++++++++++++ 7 files changed, 132 insertions(+) create mode 100644 DuckDuckGo/HomePageDisplayDailyPixelBucket.swift create mode 100644 DuckDuckGoTests/HomePageDisplayDailyPixelBucketTests.swift diff --git a/Core/PixelEvent.swift b/Core/PixelEvent.swift index d8a87f3132..4e48109b4f 100644 --- a/Core/PixelEvent.swift +++ b/Core/PixelEvent.swift @@ -714,6 +714,12 @@ extension Pixel { case reportBrokenSiteSkipToggleStep case reportBrokenSiteToggleProtectionOff + // MARK: New Tab Page baseline engagement + case addFavoriteDaily + case addBookmarkDaily + case favoriteLaunchedNTPDaily + case bookmarkLaunchedDaily + case newTabPageDisplayedDaily } } @@ -1416,6 +1422,13 @@ extension Pixel.Event { case .reportBrokenSiteTogglePromptYes: return "m_report-broken-site_toggle-prompt-yes" case .reportBrokenSiteSkipToggleStep: return "m_report-broken-site_skip-toggle-step" case .reportBrokenSiteToggleProtectionOff: return "m_report-broken-site_toggle-protection-off" + + // MARK: New Tab Page baseline engagement + case .addFavoriteDaily: return "m_add_favorite_daily" + case .addBookmarkDaily: return "m_add_bookmark_daily" + case .favoriteLaunchedNTPDaily: return "m_favorite_launched_ntp_daily" + case .bookmarkLaunchedDaily: return "m_bookmark_launched_daily" + case .newTabPageDisplayedDaily: return "m_new_tab_page_displayed_daily" } } } diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 08f90a0826..5c1fc64349 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -256,6 +256,8 @@ 6F03CB052C32EFCC004179A8 /* MockPixelFiring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F03CB032C32EFA8004179A8 /* MockPixelFiring.swift */; }; 6F03CB072C32F173004179A8 /* PixelFiring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F03CB062C32F173004179A8 /* PixelFiring.swift */; }; 6F03CB092C32F331004179A8 /* PixelFiringAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F03CB082C32F331004179A8 /* PixelFiringAsync.swift */; }; + 6F40D15B2C34423800BF22F0 /* HomePageDisplayDailyPixelBucket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F40D15A2C34423800BF22F0 /* HomePageDisplayDailyPixelBucket.swift */; }; + 6F40D15E2C34436500BF22F0 /* HomePageDisplayDailyPixelBucketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F40D15C2C34436200BF22F0 /* HomePageDisplayDailyPixelBucketTests.swift */; }; 6F5CC0812C2AFFE400AFC840 /* ToggleExpandButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5CC0802C2AFFE400AFC840 /* ToggleExpandButtonView.swift */; }; 6F655BE22BAB289E00AC3597 /* DefaultTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F655BE12BAB289E00AC3597 /* DefaultTheme.swift */; }; 6F8496412BC3D8EE00ADA54E /* OnboardingButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8496402BC3D8EE00ADA54E /* OnboardingButtonsView.swift */; }; @@ -1368,6 +1370,8 @@ 6F03CB032C32EFA8004179A8 /* MockPixelFiring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPixelFiring.swift; sourceTree = ""; }; 6F03CB062C32F173004179A8 /* PixelFiring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelFiring.swift; sourceTree = ""; }; 6F03CB082C32F331004179A8 /* PixelFiringAsync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelFiringAsync.swift; sourceTree = ""; }; + 6F40D15A2C34423800BF22F0 /* HomePageDisplayDailyPixelBucket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomePageDisplayDailyPixelBucket.swift; sourceTree = ""; }; + 6F40D15C2C34436200BF22F0 /* HomePageDisplayDailyPixelBucketTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomePageDisplayDailyPixelBucketTests.swift; sourceTree = ""; }; 6F5CC0802C2AFFE400AFC840 /* ToggleExpandButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleExpandButtonView.swift; sourceTree = ""; }; 6F655BE12BAB289E00AC3597 /* DefaultTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTheme.swift; sourceTree = ""; }; 6F8496402BC3D8EE00ADA54E /* OnboardingButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingButtonsView.swift; sourceTree = ""; }; @@ -3405,6 +3409,7 @@ isa = PBXGroup; children = ( 6F03CB002C32ED42004179A8 /* NewTabPageMessagesModelTests.swift */, + 6F40D15C2C34436200BF22F0 /* HomePageDisplayDailyPixelBucketTests.swift */, ); name = NewTabPage; sourceTree = ""; @@ -5004,6 +5009,7 @@ 85058365219AE9EA00ED4EDB /* HomePageConfiguration.swift */, 6F03CAFD2C32DD08004179A8 /* HomePageMessagesConfiguration.swift */, F16390811E648B7A005B4550 /* HomeViewController.swift */, + 6F40D15A2C34423800BF22F0 /* HomePageDisplayDailyPixelBucket.swift */, 85058367219C49E000ED4EDB /* HomeViewSectionRenderers.swift */, 85C861E528FF1B5F00189466 /* HomeViewSectionRenderersExtension.swift */, 85B9CB8321AEBD72009001F1 /* Cells */, @@ -6714,6 +6720,7 @@ 857EEB752095FFAC008A005C /* HomeRowInstructionsViewController.swift in Sources */, D63FF8952C1B67E9006DE24D /* YoutubePlayerUserScript.swift in Sources */, 4BF3E4AF2C06A85200ED5D57 /* VPNRedditSessionWorkaround.swift in Sources */, + 6F40D15B2C34423800BF22F0 /* HomePageDisplayDailyPixelBucket.swift in Sources */, 311BD1AF2836BB4200AEF6C1 /* AutofillItemsLockedView.swift in Sources */, 85DE681A2B6A8BB000DED4FE /* MainViewCoordinator.swift in Sources */, F1617C151E57336D00DEDCAF /* TabManager.swift in Sources */, @@ -7092,6 +7099,7 @@ 569437242BDD405400C0881B /* SyncBookmarksAdapterTests.swift in Sources */, 858479CD2B87964500D156C1 /* HistoryManagerTests.swift in Sources */, CBCCF96828885DEE006F4A71 /* AppPrivacyConfigurationTests.swift in Sources */, + 6F40D15E2C34436500BF22F0 /* HomePageDisplayDailyPixelBucketTests.swift in Sources */, 310742AB2848E6FD0012660B /* BackForwardMenuHistoryItemURLSanitizerTests.swift in Sources */, 22CB1ED8203DDD2C00D2C724 /* AppDeepLinksTests.swift in Sources */, 9847C00527A41A0A00DB07AA /* WebViewTestHelper.swift in Sources */, diff --git a/DuckDuckGo/BookmarksViewController.swift b/DuckDuckGo/BookmarksViewController.swift index 38a9ebafc8..7ec78e8881 100644 --- a/DuckDuckGo/BookmarksViewController.swift +++ b/DuckDuckGo/BookmarksViewController.swift @@ -830,6 +830,7 @@ class BookmarksViewController: UIViewController, UITableViewDelegate { guard let url = bookmark.urlObject else { return } dismiss() Pixel.fire(pixel: .bookmarkLaunchList) + DailyPixel.fire(pixel: .bookmarkLaunchedDaily) delegate?.bookmarksDidSelect(url: url) } diff --git a/DuckDuckGo/HomePageDisplayDailyPixelBucket.swift b/DuckDuckGo/HomePageDisplayDailyPixelBucket.swift new file mode 100644 index 0000000000..04b74f2482 --- /dev/null +++ b/DuckDuckGo/HomePageDisplayDailyPixelBucket.swift @@ -0,0 +1,47 @@ +// +// HomePageDisplayDailyPixelBucket.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 Foundation + +struct HomePageDisplayDailyPixelBucket { + + let value: String + + init(favoritesCount: Int) { + + switch favoritesCount { + case 0: + value = "0" + case 1: + value = "1" + case 2...3: + value = "2-3" + case 4...5: + value = "4-5" + case 6...10: + value = "6-10" + case 11...15: + value = "11-15" + case 16...25: + value = "16-25" + default: + value = ">25" + } + } +} diff --git a/DuckDuckGo/HomeViewController.swift b/DuckDuckGo/HomeViewController.swift index cc2e72cdcc..ffe182474e 100644 --- a/DuckDuckGo/HomeViewController.swift +++ b/DuckDuckGo/HomeViewController.swift @@ -211,6 +211,8 @@ class HomeViewController: UIViewController, NewTabPage { guard presentedViewController?.isBeingDismissed ?? true else { return } Pixel.fire(pixel: .homeScreenShown) + sendDailyDisplayPixel() + showNextDaxDialog() collectionView.didAppear() @@ -319,11 +321,22 @@ class HomeViewController: UIViewController, NewTabPage { .init(syncService: syncService, syncBookmarksAdapter: syncDataProviders.bookmarksAdapter) } +private extension HomeViewController { + func sendDailyDisplayPixel() { + + let favoritesCount = favoritesViewModel.favorites.count + let bucket = HomePageDisplayDailyPixelBucket(favoritesCount: favoritesCount) + + DailyPixel.fire(pixel: .newTabPageDisplayedDaily, withAdditionalParameters: ["FavoriteCount": bucket.value]) + } +} + extension HomeViewController: FavoritesHomeViewSectionRendererDelegate { func favoritesRenderer(_ renderer: FavoritesHomeViewSectionRenderer, didSelect favorite: BookmarkEntity) { guard let url = favorite.urlObject else { return } Pixel.fire(pixel: .favoriteLaunchedNTP) + DailyPixel.fire(pixel: .favoriteLaunchedNTPDaily) Favicons.shared.loadFavicon(forDomain: url.host, intoCache: .fireproof, fromCache: .tabs) delegate?.home(self, didRequestUrl: url) } diff --git a/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift b/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift index c9cb80dd49..daeb8fd5de 100644 --- a/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift +++ b/DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift @@ -220,6 +220,7 @@ extension TabViewController { private func performSaveBookmarkAction(for link: Link, with bookmarksInterface: MenuBookmarksInteracting) { Pixel.fire(pixel: .browsingMenuAddToBookmarks) + DailyPixel.fire(pixel: .addBookmarkDaily) bookmarksInterface.createBookmark(title: link.title ?? "", url: link.url) favicons.loadFavicon(forDomain: link.url.host, intoCache: .fireproof, fromCache: .tabs) syncService.scheduler.notifyDataChanged() @@ -261,6 +262,7 @@ extension TabViewController { image: UIImage(named: "Favorite-16")!, action: { [weak self] in Pixel.fire(pixel: addToFavoriteFlow ? .browsingMenuAddToFavoritesAddFavoriteFlow : .browsingMenuAddToFavorites) + DailyPixel.fire(pixel: .addFavoriteDaily) self?.performAddFavoriteAction(for: link, with: bookmarksInterface) }) return entry diff --git a/DuckDuckGoTests/HomePageDisplayDailyPixelBucketTests.swift b/DuckDuckGoTests/HomePageDisplayDailyPixelBucketTests.swift new file mode 100644 index 0000000000..fb86adbcdf --- /dev/null +++ b/DuckDuckGoTests/HomePageDisplayDailyPixelBucketTests.swift @@ -0,0 +1,48 @@ +// +// HomePageDisplayDailyPixelBucketTests.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 HomePageDisplayDailyPixelBucketTests: XCTestCase { + func testBucketValues() { + let ranges = [ + 0...0: "0", + 1...1: "1", + 2...3: "2-3", + 4...5: "4-5", + 6...10: "6-10", + 11...15: "11-15", + 16...25: "16-25" + ] + + for range in ranges { + for count in range.key { + let bucket = HomePageDisplayDailyPixelBucket(favoritesCount: count) + + XCTAssertEqual(bucket.value, range.value) + } + } + + let bucket = HomePageDisplayDailyPixelBucket(favoritesCount: 60) + + XCTAssertEqual(bucket.value, ">25") + } +}