For #23399: Add tabs tray multi-select telemetry.

upstream-sync
mcarare 2 years ago committed by mergify[bot]
parent fe0e4e9215
commit 597cc84a76

@ -3821,6 +3821,106 @@ tabs_tray:
notification_emails:
- android-probes@mozilla.com
expires: 107
enter_multiselect_mode:
type: event
description: |
User has entered multiselect mode.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/23399
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/23964#issuecomment-1051128057
data_sensitivity:
- interaction
notification_emails:
- android-probes@mozilla.com
expires: 107
metadata:
tags:
- Tabs
extra_keys:
tab_selected:
description: If a tab was selected when entering multi select.
type: boolean
share_selected_tabs:
type: event
description: |
User has chosen to share selected tabs.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/23399
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/23964#issuecomment-1051128057
data_sensitivity:
- interaction
notification_emails:
- android-probes@mozilla.com
expires: 107
metadata:
tags:
- Tabs
extra_keys:
tab_count:
description: The number of selected tabs shared.
type: quantity
bookmark_selected_tabs:
type: event
description: |
User has chosen to bookmark selected tabs.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/23399
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/23964#issuecomment-1051128057
data_sensitivity:
- interaction
notification_emails:
- android-probes@mozilla.com
expires: 107
metadata:
tags:
- Tabs
extra_keys:
tab_count:
description: The number of selected tabs bookmarked.
type: quantity
close_selected_tabs:
type: event
description: |
User has chosen to close selected tabs.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/23399
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/23964#issuecomment-1051128057
data_sensitivity:
- interaction
notification_emails:
- android-probes@mozilla.com
expires: 107
metadata:
tags:
- Tabs
extra_keys:
tab_count:
description: The number of selected tabs closed.
type: quantity
selected_tabs_to_collection:
type: event
description: |
User has chosen to save selected tabs to a collection.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/23399
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/23964#issuecomment-1051128057
data_sensitivity:
- interaction
notification_emails:
- android-probes@mozilla.com
expires: 107
metadata:
tags:
- Tabs
extra_keys:
tab_count:
description: The number of selected tabs added to colelction.
type: quantity
collections:
renamed:

@ -16,6 +16,7 @@ import mozilla.components.browser.storage.sync.Tab as SyncTab
import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.service.fxa.manager.FxaAccountManager
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.collections.CollectionsDialog
import org.mozilla.fenix.collections.show
@ -146,6 +147,8 @@ class DefaultNavigationInteractor(
}
override fun onShareTabs(tabs: Collection<TabSessionState>) {
TabsTray.shareSelectedTabs.record(TabsTray.ShareSelectedTabsExtra(tabCount = tabs.size))
val data = tabs.map {
ShareData(url = it.content.url, title = it.content.title)
}
@ -194,6 +197,8 @@ class DefaultNavigationInteractor(
}
override fun onSaveToCollections(tabs: Collection<TabSessionState>) {
TabsTray.selectedTabsToCollection.record(TabsTray.SelectedTabsToCollectionExtra(tabCount = tabs.size))
metrics.track(Event.TabsTraySaveToCollectionPressed)
tabsTrayStore.dispatch(TabsTrayAction.ExitSelectMode)
@ -219,6 +224,8 @@ class DefaultNavigationInteractor(
}
override fun onSaveToBookmarks(tabs: Collection<TabSessionState>) {
TabsTray.bookmarkSelectedTabs.record(TabsTray.BookmarkSelectedTabsExtra(tabCount = tabs.size))
tabs.forEach { tab ->
// We don't combine the context with lifecycleScope so that our jobs are not cancelled
// if we leave the fragment, i.e. we still want the bookmarks to be added if the

@ -15,6 +15,7 @@ import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.base.profiler.Profiler
import mozilla.components.feature.tabs.TabsUseCases
import mozilla.components.lib.state.DelicateAction
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
@ -200,6 +201,8 @@ class DefaultTabsTrayController(
* This method has no effect for tabs that do not exist.
*/
override fun handleMultipleTabsDeletion(tabs: Collection<TabSessionState>) {
TabsTray.closeSelectedTabs.record(TabsTray.CloseSelectedTabsExtra(tabCount = tabs.size))
val isPrivate = tabs.any { it.content.private }
// If user closes all the tabs from selected tabs page dismiss tray and navigate home.

@ -7,6 +7,7 @@ package org.mozilla.fenix.tabstray
import androidx.annotation.VisibleForTesting
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
@ -54,6 +55,15 @@ class TabsTrayMiddleware(
}
}
}
is TabsTrayAction.EnterSelectMode -> {
TabsTray.enterMultiselectMode.record(TabsTray.EnterMultiselectModeExtra(false))
}
is TabsTrayAction.AddSelectTab -> {
TabsTray.enterMultiselectMode.record(TabsTray.EnterMultiselectModeExtra(true))
}
else -> {
// no-op
}
}
}

@ -24,11 +24,16 @@ import mozilla.components.browser.state.state.createTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.base.profiler.Profiler
import mozilla.components.feature.tabs.TabsUseCases
import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.metrics.Event
@ -36,7 +41,9 @@ import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.home.HomeFragment
import org.mozilla.fenix.ext.maxActiveTime
import org.mozilla.fenix.ext.potentialInactiveTabs
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class) // for gleanTestRule
class DefaultTabsTrayControllerTest {
@MockK(relaxed = true)
private lateinit var trayStore: TabsTrayStore
@ -62,6 +69,9 @@ class DefaultTabsTrayControllerTest {
@MockK(relaxed = true)
private lateinit var tabsUseCases: TabsUseCases
@get:Rule
val gleanTestRule = GleanTestRule(testContext)
@Before
fun setup() {
MockKAnnotations.init(this)
@ -327,6 +337,11 @@ class DefaultTabsTrayControllerTest {
controller.handleMultipleTabsDeletion(listOf(privateTab, mockk()))
assertTrue(TabsTray.closeSelectedTabs.testHasValue())
val snapshot = TabsTray.closeSelectedTabs.testGetValue()
assertEquals(1, snapshot.size)
assertEquals("2", snapshot.single().extra?.getValue("tab_count"))
verify { controller.dismissTabsTrayAndNavigateHome(HomeFragment.ALL_PRIVATE_TABS) }
assertTrue(showUndoSnackbarForTabInvoked)
verify(exactly = 0) { tabsUseCases.removeTabs(any()) }
@ -356,6 +371,11 @@ class DefaultTabsTrayControllerTest {
controller.handleMultipleTabsDeletion(listOf(normalTab, normalTab))
assertTrue(TabsTray.closeSelectedTabs.testHasValue())
val snapshot = TabsTray.closeSelectedTabs.testGetValue()
assertEquals(1, snapshot.size)
assertEquals("2", snapshot.single().extra?.getValue("tab_count"))
verify { controller.dismissTabsTrayAndNavigateHome(HomeFragment.ALL_NORMAL_TABS) }
verify(exactly = 0) { tabsUseCases.removeTabs(any()) }
assertTrue(showUndoSnackbarForTabInvoked)
@ -377,6 +397,11 @@ class DefaultTabsTrayControllerTest {
controller.handleMultipleTabsDeletion(listOf(privateTab))
assertTrue(TabsTray.closeSelectedTabs.testHasValue())
val snapshot = TabsTray.closeSelectedTabs.testGetValue()
assertEquals(1, snapshot.size)
assertEquals("1", snapshot.single().extra?.getValue("tab_count"))
verify { tabsUseCases.removeTabs(listOf("42")) }
verify(exactly = 0) { controller.dismissTabsTrayAndNavigateHome(any()) }
assertTrue(showUndoSnackbarForTabInvoked)
@ -398,6 +423,11 @@ class DefaultTabsTrayControllerTest {
controller.handleMultipleTabsDeletion(listOf(privateTab))
assertTrue(TabsTray.closeSelectedTabs.testHasValue())
val snapshot = TabsTray.closeSelectedTabs.testGetValue()
assertEquals(1, snapshot.size)
assertEquals("1", snapshot.single().extra?.getValue("tab_count"))
verify { tabsUseCases.removeTabs(listOf("24")) }
verify(exactly = 0) { controller.dismissTabsTrayAndNavigateHome(any()) }
assertTrue(showUndoSnackbarForTabInvoked)

@ -24,12 +24,18 @@ import mozilla.components.browser.state.state.content.DownloadState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.storage.sync.TabEntry
import mozilla.components.service.fxa.manager.FxaAccountManager
import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.Assert
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.runner.RunWith
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.collections.CollectionsDialog
import org.mozilla.fenix.collections.show
@ -37,9 +43,11 @@ import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import mozilla.components.browser.state.state.createTab as createStateTab
import mozilla.components.browser.storage.sync.Tab as SyncTab
@RunWith(FenixRobolectricTestRunner::class) // for gleanTestRule
class NavigationInteractorTest {
private lateinit var store: BrowserStore
private lateinit var tabsTrayStore: TabsTrayStore
@ -52,8 +60,12 @@ class NavigationInteractorTest {
private val accountManager: FxaAccountManager = mockk(relaxed = true)
private val activity: HomeActivity = mockk(relaxed = true)
val coroutinesTestRule: MainCoroutineRule = MainCoroutineRule()
val gleanTestRule = GleanTestRule(testContext)
@get:Rule
val coroutinesTestRule = MainCoroutineRule()
val chain: RuleChain = RuleChain.outerRule(coroutinesTestRule).around(gleanTestRule)
private val testDispatcher = coroutinesTestRule.testDispatcher
@Before
@ -162,8 +174,15 @@ class NavigationInteractorTest {
@Test
fun `onShareTabs calls navigation on DefaultNavigationInteractor`() {
createInteractor().onShareTabs(emptyList())
createInteractor().onShareTabs(listOf(testTab))
verify(exactly = 1) { navController.navigate(any<NavDirections>()) }
assertTrue(TabsTray.shareSelectedTabs.testHasValue())
val snapshot = TabsTray.shareSelectedTabs.testGetValue()
Assert.assertEquals(1, snapshot.size)
Assert.assertEquals("1", snapshot.single().extra?.getValue("tab_count"))
}
@Test
@ -171,7 +190,7 @@ class NavigationInteractorTest {
mockkStatic("org.mozilla.fenix.collections.CollectionsDialogKt")
every { any<CollectionsDialog>().show(any()) } answers { }
createInteractor().onSaveToCollections(emptyList())
createInteractor().onSaveToCollections(listOf(testTab))
verify(exactly = 1) { metrics.track(Event.TabsTraySaveToCollectionPressed) }
unmockkStatic("org.mozilla.fenix.collections.CollectionsDialogKt")
@ -188,6 +207,11 @@ class NavigationInteractorTest {
coVerify(exactly = 1) { bookmarksUseCase.addBookmark(any(), any(), any()) }
assertTrue(showBookmarkSnackbarInvoked)
assertTrue(TabsTray.bookmarkSelectedTabs.testHasValue())
val snapshot = TabsTray.bookmarkSelectedTabs.testGetValue()
Assert.assertEquals(1, snapshot.size)
Assert.assertEquals("1", snapshot.single().extra?.getValue("tab_count"))
}
@Test

@ -9,19 +9,30 @@ import io.mockk.mockk
import io.mockk.verify
import mozilla.components.browser.state.state.TabGroup
import mozilla.components.browser.state.state.TabPartition
import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.libstate.ext.waitUntilIdle
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class) // for gleanTestRule
class TabsTrayMiddlewareTest {
private lateinit var store: TabsTrayStore
private lateinit var tabsTrayMiddleware: TabsTrayMiddleware
private lateinit var metrics: MetricController
@get:Rule
val gleanTestRule = GleanTestRule(testContext)
@Before
fun setUp() {
metrics = mockk(relaxed = true)
@ -80,6 +91,28 @@ class TabsTrayMiddlewareTest {
assertEquals(4L, tabsTrayMiddleware.generateTabGroupSizeMappedValue(50))
}
@Test
fun `WHEN multi select mode from menu is entered THEN relevant metrics are collected`() {
store.dispatch(TabsTrayAction.EnterSelectMode)
store.waitUntilIdle()
assertTrue(TabsTray.enterMultiselectMode.testHasValue())
val snapshot = TabsTray.enterMultiselectMode.testGetValue()
assertEquals(1, snapshot.size)
assertEquals("false", snapshot.single().extra?.getValue("tab_selected"))
}
@Test
fun `WHEN multi select mode by long press is entered THEN relevant metrics are collected`() {
store.dispatch(TabsTrayAction.AddSelectTab(mockk()))
store.waitUntilIdle()
assertTrue(TabsTray.enterMultiselectMode.testHasValue())
val snapshot = TabsTray.enterMultiselectMode.testGetValue()
assertEquals(1, snapshot.size)
assertEquals("true", snapshot.single().extra?.getValue("tab_selected"))
}
private fun generateSearchTermTabGroupsForAverage(): TabPartition {
val group1 = TabGroup("", "", mockk(relaxed = true))
val group2 = TabGroup("", "", mockk(relaxed = true))

Loading…
Cancel
Save