Bug 1954500: Fix tab group telemetry to be in line with spec r=sthompson,tabbrowser-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D241830
This commit is contained in:
@@ -79,91 +79,6 @@ browser.engagement:
|
||||
type: quantity
|
||||
expires: never
|
||||
|
||||
tab_group_create:
|
||||
type: event
|
||||
description: >
|
||||
Recorded when the user creates a new tab group via
|
||||
the tab context menu or through drag and drop.
|
||||
notification_emails:
|
||||
- dao@mozilla.com
|
||||
- jswinarton@mozilla.com
|
||||
bugs:
|
||||
- https://bugzil.la/1938423
|
||||
data_reviews:
|
||||
- https://bugzil.la/1938423
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
extra_keys:
|
||||
source:
|
||||
description: The means by which the tab group was created
|
||||
type: string
|
||||
tabs:
|
||||
description: The number of tabs in the group when it was created
|
||||
type: quantity
|
||||
layout:
|
||||
description: The layout of the tab strip when the group was created (either "horizontal" or "vertical")
|
||||
type: string
|
||||
id:
|
||||
description: The ID of the created tab group
|
||||
type: string
|
||||
expires: never
|
||||
|
||||
tab_group_expand_or_collapse:
|
||||
type: event
|
||||
description: >
|
||||
Recorded when a tab group is expanded or collapsed.
|
||||
notification_emails:
|
||||
- dao@mozilla.com
|
||||
- jswinarton@mozilla.com
|
||||
bugs:
|
||||
- https://bugzil.la/1938397
|
||||
data_reviews:
|
||||
- https://bugzil.la/1938397
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
extra_keys:
|
||||
total_collapsed:
|
||||
description: The total number of active groups in all windows that are collapsed
|
||||
type: quantity
|
||||
total_expanded:
|
||||
description: The total number of active groups in all windows that are expanded
|
||||
type: quantity
|
||||
expires: never
|
||||
|
||||
tab_group_modify:
|
||||
type: event
|
||||
description: >
|
||||
Recorded when the number of tabs in a tab group are modified.
|
||||
notification_emails:
|
||||
- dao@mozilla.com
|
||||
- jswinarton@mozilla.com
|
||||
bugs:
|
||||
- https://bugzil.la/1938397
|
||||
data_reviews:
|
||||
- https://bugzil.la/1938397
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
extra_keys:
|
||||
tabs_per_active_group_max:
|
||||
description: The number of open tabs in the largest tab group in any window
|
||||
type: quantity
|
||||
tabs_per_active_group_min:
|
||||
description: The number of open tabs in the smallest tab group in any window
|
||||
type: quantity
|
||||
tabs_per_active_group_median:
|
||||
description: The median number of open tabs in tab groups in all windows
|
||||
type: quantity
|
||||
tabs_per_active_group_average:
|
||||
description: The average number of open tabs in tab groups in all windows
|
||||
type: quantity
|
||||
tabs_inside_groups:
|
||||
description: The total number of tabs within tab groups in all windows
|
||||
type: quantity
|
||||
tabs_outside_groups:
|
||||
description: The total number of tabs not in groups in all windows
|
||||
type: quantity
|
||||
expires: never
|
||||
|
||||
browser.ui.interaction:
|
||||
all_tabs_panel_dragstart_tab_event_count:
|
||||
type: counter
|
||||
@@ -288,3 +203,94 @@ browser.ml.interaction:
|
||||
expires: never
|
||||
no_lint:
|
||||
- COMMON_PREFIX
|
||||
|
||||
tabgroup:
|
||||
create_group:
|
||||
type: event
|
||||
description: >
|
||||
Recorded when the user creates a new tab group via
|
||||
the tab context menu or through drag and drop.
|
||||
notification_emails:
|
||||
- dao@mozilla.com
|
||||
- jswinarton@mozilla.com
|
||||
bugs:
|
||||
- https://bugzil.la/1938423
|
||||
- https://bugzil.la/1954500
|
||||
data_reviews:
|
||||
- https://bugzil.la/1938423
|
||||
- https://bugzil.la/1954500
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
extra_keys:
|
||||
source:
|
||||
description: The means by which the tab group was created
|
||||
type: string
|
||||
tabs:
|
||||
description: The number of tabs in the group when it was created
|
||||
type: quantity
|
||||
layout:
|
||||
description: The layout of the tab strip when the group was created (either "horizontal" or "vertical")
|
||||
type: string
|
||||
id:
|
||||
description: The ID of the created tab group
|
||||
type: string
|
||||
expires: never
|
||||
|
||||
active_groups:
|
||||
type: labeled_quantity
|
||||
description: >
|
||||
Records the number of groups present in the tab bar, split by expanded or collapsed.
|
||||
notification_emails:
|
||||
- dao@mozilla.com
|
||||
- jswinarton@mozilla.com
|
||||
bugs:
|
||||
- https://bugzil.la/1938397
|
||||
- https://bugzil.la/1954500
|
||||
data_reviews:
|
||||
- https://bugzil.la/1938397
|
||||
- https://bugzil.la/1954500
|
||||
expires: never
|
||||
unit: tab groups
|
||||
labels:
|
||||
- expanded
|
||||
- collapsed
|
||||
|
||||
tabs_per_active_group:
|
||||
type: labeled_quantity
|
||||
description: >
|
||||
Records statistics about the number of tabs per active group: max, median, average and min.
|
||||
notification_emails:
|
||||
- dao@mozilla.com
|
||||
- jswinarton@mozilla.com
|
||||
bugs:
|
||||
- https://bugzil.la/1938397
|
||||
- https://bugzil.la/1954500
|
||||
data_reviews:
|
||||
- https://bugzil.la/1938397
|
||||
- https://bugzil.la/1954500
|
||||
expires: never
|
||||
unit: tabs
|
||||
labels:
|
||||
- max
|
||||
- median
|
||||
- average
|
||||
- min
|
||||
|
||||
tab_count_in_groups:
|
||||
type: labeled_quantity
|
||||
description: >
|
||||
Records the latest number of tabs in the tab bar, split by being inside a group or outside.
|
||||
notification_emails:
|
||||
- dao@mozilla.com
|
||||
- jswinarton@mozilla.com
|
||||
bugs:
|
||||
- https://bugzil.la/1938397
|
||||
- https://bugzil.la/1954500
|
||||
data_reviews:
|
||||
- https://bugzil.la/1938397
|
||||
- https://bugzil.la/1954500
|
||||
expires: never
|
||||
unit: tabs
|
||||
labels:
|
||||
- inside
|
||||
- outside
|
||||
|
||||
@@ -10,9 +10,7 @@ let resetTelemetry = async () => {
|
||||
add_task(async function test_tabGroupTelemetry() {
|
||||
await resetTelemetry();
|
||||
|
||||
let tabGroupCreateTelemetry,
|
||||
tabGroupModifyTelemetry,
|
||||
tabGroupCollapseTelemetry;
|
||||
let tabGroupCreateTelemetry;
|
||||
|
||||
let group1tab = BrowserTestUtils.addTab(gBrowser, "https://example.com");
|
||||
await BrowserTestUtils.browserLoaded(group1tab.linkedBrowser);
|
||||
@@ -24,15 +22,13 @@ add_task(async function test_tabGroupTelemetry() {
|
||||
gBrowser.tabGroupMenu.close();
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
tabGroupCreateTelemetry =
|
||||
Glean.browserEngagement.tabGroupCreate.testGetValue();
|
||||
tabGroupModifyTelemetry =
|
||||
Glean.browserEngagement.tabGroupModify.testGetValue();
|
||||
tabGroupCreateTelemetry = Glean.tabgroup.createGroup.testGetValue();
|
||||
return (
|
||||
tabGroupCreateTelemetry?.length == 1 &&
|
||||
tabGroupModifyTelemetry?.length == 1
|
||||
Glean.tabgroup.tabCountInGroups.inside.testGetValue() !== null &&
|
||||
Glean.tabgroup.tabsPerActiveGroup.average.testGetValue() !== null
|
||||
);
|
||||
}, "Wait for tabGroupCreate and tabGroupModify events after creating a single tab group");
|
||||
}, "Wait for createGroup and at least one metric from the tabCountInGroups and tabsPerActiveGroup to be set");
|
||||
|
||||
Assert.deepEqual(
|
||||
tabGroupCreateTelemetry[0].extra,
|
||||
@@ -44,17 +40,36 @@ add_task(async function test_tabGroupTelemetry() {
|
||||
},
|
||||
"tabGroupCreate event extra_keys has correct values after tab group create"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
tabGroupModifyTelemetry[0].extra,
|
||||
{
|
||||
tabs_per_active_group_min: "1",
|
||||
tabs_per_active_group_max: "1",
|
||||
tabs_inside_groups: "1",
|
||||
tabs_per_active_group_median: "1",
|
||||
tabs_outside_groups: "1",
|
||||
tabs_per_active_group_average: "1",
|
||||
},
|
||||
"tabGroupModify event extra_keys has correct values after tab group create"
|
||||
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabCountInGroups.inside.testGetValue(),
|
||||
1,
|
||||
"tabCountInGroups.inside has correct value"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabCountInGroups.outside.testGetValue(),
|
||||
1,
|
||||
"tabCountInGroups.outside has correct value"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.median.testGetValue(),
|
||||
1,
|
||||
"tabsPerActiveGroup.median has correct value"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.average.testGetValue(),
|
||||
1,
|
||||
"tabsPerActiveGroup.average has correct value"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.max.testGetValue(),
|
||||
1,
|
||||
"tabsPerActiveGroup.max has correct value"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.min.testGetValue(),
|
||||
1,
|
||||
"tabsPerActiveGroup.min has correct value"
|
||||
);
|
||||
|
||||
await resetTelemetry();
|
||||
@@ -75,23 +90,43 @@ add_task(async function test_tabGroupTelemetry() {
|
||||
gBrowser.tabGroupMenu.close();
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
tabGroupModifyTelemetry =
|
||||
Glean.browserEngagement.tabGroupModify.testGetValue();
|
||||
return tabGroupModifyTelemetry?.length == 1;
|
||||
}, "Wait for tabGroupModify event after adding a new tab group");
|
||||
return (
|
||||
Glean.tabgroup.tabCountInGroups.inside.testGetValue() !== null &&
|
||||
Glean.tabgroup.tabsPerActiveGroup.average.testGetValue() !== null
|
||||
);
|
||||
}, "Wait for at least one metric from the tabCountInGroups and tabsPerActiveGroup to be set after adding a new tab group");
|
||||
|
||||
Assert.deepEqual(
|
||||
tabGroupModifyTelemetry[0].extra,
|
||||
{
|
||||
tabs_per_active_group_max: "3",
|
||||
tabs_per_active_group_min: "1",
|
||||
tabs_per_active_group_median: "2",
|
||||
tabs_per_active_group_average: "2",
|
||||
tabs_inside_groups: "4",
|
||||
tabs_outside_groups: "1",
|
||||
},
|
||||
"tabGroupModify event extra_keys has correct values after adding a new tab group"
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabCountInGroups.inside.testGetValue(),
|
||||
4,
|
||||
"tabCountInGroups.inside has correct value after adding a new tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabCountInGroups.outside.testGetValue(),
|
||||
1,
|
||||
"tabCountInGroups.outside has correct value after adding a new tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.median.testGetValue(),
|
||||
2,
|
||||
"tabsPerActiveGroup.median has correct value after adding a new tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.average.testGetValue(),
|
||||
2,
|
||||
"tabsPerActiveGroup.average has correct value after adding a new tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.max.testGetValue(),
|
||||
3,
|
||||
"tabsPerActiveGroup.max has correct value after adding a new tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.min.testGetValue(),
|
||||
1,
|
||||
"tabsPerActiveGroup.min has correct value after adding a new tab group"
|
||||
);
|
||||
|
||||
await resetTelemetry();
|
||||
|
||||
let newTabInGroup2 = BrowserTestUtils.addTab(gBrowser, "https://example.com");
|
||||
@@ -100,42 +135,62 @@ add_task(async function test_tabGroupTelemetry() {
|
||||
group2.addTabs([newTabInGroup2]);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
tabGroupModifyTelemetry =
|
||||
Glean.browserEngagement.tabGroupModify.testGetValue();
|
||||
return tabGroupModifyTelemetry?.length == 1;
|
||||
}, "Wait for tabGroupModify event after modifying a tab group");
|
||||
return (
|
||||
Glean.tabgroup.tabCountInGroups.inside.testGetValue() !== null &&
|
||||
Glean.tabgroup.tabsPerActiveGroup.average.testGetValue() !== null
|
||||
);
|
||||
}, "Wait for at least one metric from the tabCountInGroups and tabsPerActiveGroup to be set after modifying a tab group");
|
||||
|
||||
Assert.deepEqual(
|
||||
tabGroupModifyTelemetry[0].extra,
|
||||
{
|
||||
tabs_per_active_group_max: "4",
|
||||
tabs_per_active_group_min: "1",
|
||||
tabs_per_active_group_median: "2.5",
|
||||
tabs_per_active_group_average: "2.5",
|
||||
tabs_inside_groups: "5",
|
||||
tabs_outside_groups: "1",
|
||||
},
|
||||
"tabGroupModify event extra_keys has correct values after changing the number of tabs in groups"
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabCountInGroups.inside.testGetValue(),
|
||||
5,
|
||||
"tabCountInGroups.inside has correct value after modifying a tab group"
|
||||
);
|
||||
await Services.fog.testFlushAllChildren();
|
||||
Services.fog.testResetFOG();
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabCountInGroups.outside.testGetValue(),
|
||||
1,
|
||||
"tabCountInGroups.outside has correct value after modifying a tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.median.testGetValue(),
|
||||
2,
|
||||
"tabsPerActiveGroup.median has correct value after modifying a tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.average.testGetValue(),
|
||||
2,
|
||||
"tabsPerActiveGroup.average has correct value after modifying a tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.max.testGetValue(),
|
||||
4,
|
||||
"tabsPerActiveGroup.max has correct value after modifying a tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.tabsPerActiveGroup.min.testGetValue(),
|
||||
1,
|
||||
"tabsPerActiveGroup.min has correct value after modifying a tab group"
|
||||
);
|
||||
|
||||
await resetTelemetry();
|
||||
|
||||
group2.collapsed = true;
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
tabGroupCollapseTelemetry =
|
||||
Glean.browserEngagement.tabGroupExpandOrCollapse.testGetValue();
|
||||
return tabGroupCollapseTelemetry?.length;
|
||||
}, "Wait for tabGroupExpandOrCollapseEvent after tab group collapse");
|
||||
return Glean.tabgroup.activeGroups.collapsed.testGetValue() !== null;
|
||||
}, "Wait for the activeGroups metric to be set after collapsing a tab group");
|
||||
|
||||
Assert.deepEqual(
|
||||
tabGroupCollapseTelemetry[0].extra,
|
||||
{
|
||||
total_collapsed: "1",
|
||||
total_expanded: "1",
|
||||
},
|
||||
"tabGroupExpandOrCollapse event extra_keys has correct values"
|
||||
Assert.equal(
|
||||
Glean.tabgroup.activeGroups.collapsed.testGetValue(),
|
||||
1,
|
||||
"activeGroups.collapsed has correct value after collapsing a tab group"
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.tabgroup.activeGroups.expanded.testGetValue(),
|
||||
1,
|
||||
"activeGroups.collapsed has correct value after collapsing a tab group"
|
||||
);
|
||||
|
||||
await resetTelemetry();
|
||||
|
||||
await removeTabGroup(group1);
|
||||
|
||||
@@ -588,7 +588,6 @@ export let BrowserUsageTelemetry = {
|
||||
break;
|
||||
case "TabGroupCreate":
|
||||
this._onTabGroupCreate(event);
|
||||
this._onTabGroupChange();
|
||||
break;
|
||||
case "TabGrouped":
|
||||
case "TabUngrouped":
|
||||
@@ -1220,7 +1219,7 @@ export let BrowserUsageTelemetry = {
|
||||
|
||||
_onTabGroupCreate(event) {
|
||||
if (event.detail.isUserCreated) {
|
||||
Glean.browserEngagement.tabGroupCreate.record({
|
||||
Glean.tabgroup.createGroup.record({
|
||||
id: event.target.id,
|
||||
layout: lazy.sidebarVerticalTabs ? "vertical" : "horizontal",
|
||||
source: event.detail.telemetryUserCreateSource,
|
||||
@@ -1240,6 +1239,10 @@ export let BrowserUsageTelemetry = {
|
||||
_doOnTabGroupChange() {
|
||||
let totalTabs = 0;
|
||||
let totalTabsInGroups = 0;
|
||||
let max = 0;
|
||||
let min = 0;
|
||||
let average = 0;
|
||||
let median = 0;
|
||||
|
||||
// Used for calculation of average and median
|
||||
let tabGroupLengths = [];
|
||||
@@ -1253,29 +1256,27 @@ export let BrowserUsageTelemetry = {
|
||||
}
|
||||
|
||||
const tabGroupCount = tabGroupLengths.length;
|
||||
if (!tabGroupCount) {
|
||||
// If this event was fired because the last tab group was closed, do not
|
||||
// fire a metric.
|
||||
return;
|
||||
}
|
||||
if (tabGroupCount) {
|
||||
tabGroupLengths.sort((a, b) => a - b);
|
||||
const middleIndex = Math.floor(tabGroupCount / 2);
|
||||
|
||||
tabGroupLengths.sort((a, b) => a - b);
|
||||
const middleIndex = Math.floor(tabGroupCount / 2);
|
||||
|
||||
const data = {
|
||||
tabs_per_active_group_median:
|
||||
max = Math.max(...tabGroupLengths);
|
||||
min = Math.min(...tabGroupLengths);
|
||||
median =
|
||||
tabGroupCount % 2 == 0
|
||||
? (tabGroupLengths[middleIndex - 1] + tabGroupLengths[middleIndex]) /
|
||||
2
|
||||
: tabGroupLengths[middleIndex],
|
||||
tabs_per_active_group_average:
|
||||
tabGroupLengths.reduce((a, b) => a + b, 0) / tabGroupCount,
|
||||
tabs_per_active_group_min: Math.min(...tabGroupLengths),
|
||||
tabs_per_active_group_max: Math.max(...tabGroupLengths),
|
||||
tabs_inside_groups: totalTabsInGroups,
|
||||
tabs_outside_groups: totalTabs - totalTabsInGroups,
|
||||
};
|
||||
Glean.browserEngagement.tabGroupModify.record(data);
|
||||
: tabGroupLengths[middleIndex];
|
||||
average = tabGroupLengths.reduce((a, b) => a + b, 0) / tabGroupCount;
|
||||
}
|
||||
|
||||
Glean.tabgroup.tabCountInGroups.inside.set(totalTabsInGroups);
|
||||
Glean.tabgroup.tabCountInGroups.outside.set(totalTabs - totalTabsInGroups);
|
||||
|
||||
Glean.tabgroup.tabsPerActiveGroup.median.set(median);
|
||||
Glean.tabgroup.tabsPerActiveGroup.average.set(average);
|
||||
Glean.tabgroup.tabsPerActiveGroup.max.set(max);
|
||||
Glean.tabgroup.tabsPerActiveGroup.min.set(min);
|
||||
},
|
||||
|
||||
_onTabGroupExpandOrCollapse() {
|
||||
@@ -1297,10 +1298,8 @@ export let BrowserUsageTelemetry = {
|
||||
}
|
||||
}
|
||||
|
||||
Glean.browserEngagement.tabGroupExpandOrCollapse.record({
|
||||
total_collapsed: collapsed,
|
||||
total_expanded: expanded,
|
||||
});
|
||||
Glean.tabgroup.activeGroups.collapsed.set(collapsed);
|
||||
Glean.tabgroup.activeGroups.expanded.set(expanded);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user