Bug 1938425 - add telemetry for reopening saved groups. r=dao,sessionstore-reviewers,tabbrowser-reviewers,urlbar-reviewers,sthompson

Differential Revision: https://phabricator.services.mozilla.com/D243737
This commit is contained in:
DJ
2025-04-10 03:02:30 +00:00
parent 72de1640b1
commit cdc29e0d0d
9 changed files with 262 additions and 26 deletions

View File

@@ -1686,19 +1686,19 @@ add_task(async function test_tabGroupCreatePanel() {
let tabgroupPanel = tabgroupEditor.panel;
let nameField = tabgroupPanel.querySelector("#tab-group-name");
let tab = BrowserTestUtils.addTab(gBrowser, "about:blank");
let group;
let openCreatePanel = async () => {
let panelShown = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "shown");
group = gBrowser.addTabGroup([tab], {
let group = gBrowser.addTabGroup([tab], {
color: "cyan",
label: "Food",
isUserTriggered: true,
});
await panelShown;
return group;
};
await openCreatePanel();
let group = await openCreatePanel();
Assert.equal(tabgroupPanel.state, "open", "Create panel is visible");
Assert.ok(tabgroupEditor.createMode, "Group editor is in create mode");
// Edit panel should be populated with correct group details
@@ -1725,14 +1725,14 @@ add_task(async function test_tabGroupCreatePanel() {
Assert.ok(!tab.group, "Tab is ungrouped after hitting Cancel");
info("New group should be removed after hitting Esc");
await openCreatePanel();
group = await openCreatePanel();
panelHidden = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "hidden");
EventUtils.synthesizeKey("KEY_Escape");
await panelHidden;
Assert.ok(!tab.group, "Tab is ungrouped after hitting Esc");
info("New group should remain when dismissing panel");
await openCreatePanel();
group = await openCreatePanel();
panelHidden = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "hidden");
tabgroupPanel.hidePopup();
await panelHidden;
@@ -1742,7 +1742,7 @@ add_task(async function test_tabGroupCreatePanel() {
group.ungroupTabs();
info("Panel inputs should work correctly");
await openCreatePanel();
group = await openCreatePanel();
nameField.focus();
nameField.value = "";
EventUtils.sendString("Shopping");
@@ -1819,7 +1819,7 @@ add_task(async function test_tabGroupCreatePanel() {
tabGroupCreatedTrigger.uninit();
});
async function createTabGroupAndOpenEditPanel(tabs = []) {
async function createTabGroupAndOpenEditPanel(tabs = [], label = "") {
let tabgroupEditor = document.getElementById("tab-group-editor");
let tabgroupPanel = tabgroupEditor.panel;
if (!tabs.length) {
@@ -1828,7 +1828,7 @@ async function createTabGroupAndOpenEditPanel(tabs = []) {
});
tabs = [tab];
}
let group = gBrowser.addTabGroup(tabs, { color: "cyan", label: "Food" });
let group = gBrowser.addTabGroup(tabs, { color: "cyan", label });
let panelShown = BrowserTestUtils.waitForPopupEvent(tabgroupPanel, "shown");
EventUtils.synthesizeMouseAtCenter(
@@ -1844,7 +1844,10 @@ async function createTabGroupAndOpenEditPanel(tabs = []) {
}
add_task(async function test_tabGroupPanelAddTab() {
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel();
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel(
[],
"test_tabGroupPanelAddTab"
);
let tabgroupPanel = tabgroupEditor.panel;
let addNewTabButton = tabgroupPanel.querySelector(
@@ -1858,13 +1861,14 @@ add_task(async function test_tabGroupPanelAddTab() {
Assert.ok(tabgroupPanel.state === "closed", "Group editor is closed");
Assert.equal(group.tabs.length, 2, "Group has 2 tabs");
for (let tab of group.tabs) {
BrowserTestUtils.removeTab(tab);
}
await removeTabGroup(group);
});
add_task(async function test_tabGroupPanelUngroupTabs() {
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel();
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel(
[],
"test_tabGroupPanelAddTab"
);
let tabgroupPanel = tabgroupEditor.panel;
let tab = group.tabs[0];
let ungroupTabsButton = tabgroupPanel.querySelector(
@@ -1914,7 +1918,10 @@ add_task(async function test_moveGroupToNewWindow() {
"about:mozilla is third"
);
};
let { group } = await createTabGroupAndOpenEditPanel(tabs);
let { group } = await createTabGroupAndOpenEditPanel(
tabs,
"test_moveGroupToNewWindow"
);
let newWindowOpened = BrowserTestUtils.waitForNewWindow();
document.getElementById("tabGroupEditor_moveGroupToNewWindow").click();
@@ -1964,7 +1971,7 @@ add_task(async function test_moveGroupToNewWindow() {
!moveGroupButton.disabled,
"Button is enabled again when additional tab present"
);
await removeTabGroup(movedGroup);
await BrowserTestUtils.closeWindow(newWin, { animate: false });
});
@@ -1973,7 +1980,10 @@ add_task(async function test_moveGroupToNewWindow() {
* group is not saveable.
*/
add_task(async function test_saveDisabledForUnimportantGroup() {
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel();
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel(
[],
"test_saveDisabledForUnimportantGroups"
);
let saveAndCloseGroupButton = tabgroupEditor.panel.querySelector(
"#tabGroupEditor_saveAndCloseGroup"
);
@@ -1987,7 +1997,7 @@ add_task(async function test_saveDisabledForUnimportantGroup() {
);
tabgroupEditor.panel.hidePopup();
await panelHidden;
await gBrowser.removeTabGroup(group);
await removeTabGroup(group);
});
add_task(async function test_saveAndCloseGroup() {
@@ -1997,7 +2007,10 @@ add_task(async function test_saveAndCloseGroup() {
tabGroupSavedTrigger.init(triggerHandler);
let tab = await addTab("about:mozilla");
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel([tab]);
let { tabgroupEditor, group } = await createTabGroupAndOpenEditPanel(
[tab],
"test_saveAndCloseGroup"
);
let tabgroupPanel = tabgroupEditor.panel;
await TabStateFlusher.flush(tab.linkedBrowser);
let saveAndCloseGroupButton = tabgroupPanel.querySelector(
@@ -2093,6 +2106,7 @@ add_task(async function test_pinningInteractionsWithTabGroups() {
);
moreTabs.concat(tabs).forEach(tab => BrowserTestUtils.removeTab(tab));
await removeTabGroup(group);
});
add_task(async function test_pinFirstGroupedTab() {
@@ -2120,6 +2134,7 @@ add_task(async function test_adoptTab() {
Assert.equal(adoptedTab._tPos, 1, "tab adopted into expected position");
Assert.equal(adoptedTab.group, group, "tab adopted into tab group");
await removeTabGroup(group);
await BrowserTestUtils.closeWindow(newWin, { animate: false });
});

View File

@@ -6,6 +6,10 @@ const { TabStateFlusher } = ChromeUtils.importESModule(
"resource:///modules/sessionstore/TabStateFlusher.sys.mjs"
);
const { UrlbarTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/UrlbarTestUtils.sys.mjs"
);
let resetTelemetry = async () => {
await Services.fog.testFlushAllChildren();
Services.fog.testResetFOG();
@@ -388,17 +392,31 @@ async function closeContextMenu(contextMenu) {
*
* @returns {Promise<MozTabbrowserTabGroup>}
*/
async function makeTabGroup() {
async function makeTabGroup(name = "") {
let tab = BrowserTestUtils.addTab(win.gBrowser, "https://example.com");
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await TabStateFlusher.flush(tab.linkedBrowser);
let group = win.gBrowser.addTabGroup([tab]);
let group = win.gBrowser.addTabGroup([tab], { label: name });
// Close the automatically-opened "create tab group" menu.
win.gBrowser.tabGroupMenu.close();
return group;
}
/**
* Returns a basic tab group from makeTabGroup and saves it.
*
* @returns {string} the ID of the saved group
*/
async function saveAndCloseGroup(group) {
let closedObjectsChanged = TestUtils.topicObserved(
"sessionstore-closed-objects-changed"
);
group.saveAndClose();
await closedObjectsChanged;
return group.id;
}
add_task(async function test_tabOverflowContextMenu_deleteOpenTabGroup() {
await resetTelemetry();
@@ -446,3 +464,128 @@ add_task(async function test_tabOverflowContextMenu_deleteOpenTabGroup() {
await resetTelemetry();
});
async function waitForReopenRecord() {
return BrowserTestUtils.waitForCondition(() => {
let tabGroupReopenTelemetry = Glean.tabgroup.reopen.testGetValue();
return tabGroupReopenTelemetry?.length > 0;
}, "Waiting for reopen telemetry to populate");
}
function assertReopenEvent({ id, source, layout, type }) {
let tabGroupReopenEvents = Glean.tabgroup.reopen.testGetValue();
Assert.equal(
tabGroupReopenEvents.length,
1,
"should have recorded one tabgroup.reopen event"
);
let [reopenEvent] = tabGroupReopenEvents;
Assert.deepEqual(
reopenEvent.extra,
{
id,
source,
layout,
type,
},
"should have recorded correct id, source, and layout for reopen event"
);
}
async function doReopenTests(useVerticalTabs) {
await BrowserTestUtils.waitForCondition(
() => !win.gBrowser.getAllTabGroups().length,
"waiting for an empty group list"
);
Assert.ok(!win.gBrowser.getAllTabGroups().length, "there are no tab groups");
Assert.ok(!win.SessionStore.savedGroups.length, "no saved groups");
let expectedLayout = useVerticalTabs ? "vertical" : "horizontal";
await SpecialPowers.pushPrefEnv({
set: [
["sidebar.revamp", true],
["sidebar.verticalTabs", useVerticalTabs],
],
});
let group = await makeTabGroup("reopen-test");
let groupId = await saveAndCloseGroup(group);
info("Restoring from overflow menu");
let menu = await openTabsMenu();
let groupItems = menu.querySelectorAll(
"#allTabsMenu-groupsView .all-tabs-group-action-button"
);
Assert.equal(groupItems.length, 1, "1 group in menu");
let groupButton = groupItems[0];
Assert.equal(
groupButton.getAttribute("data-tab-group-id"),
groupId,
"Correct group appears in menu"
);
groupButton.click();
await waitForReopenRecord();
assertReopenEvent({
id: groupId,
source: "tab_overflow",
layout: expectedLayout,
type: "saved",
});
await resetTelemetry();
await saveAndCloseGroup(win.gBrowser.getTabGroupById(groupId));
info("restoring saved group via undoClosetab");
undoCloseTab(undefined, win.__SSi);
await waitForReopenRecord();
assertReopenEvent({
id: groupId,
source: "recent",
layout: expectedLayout,
type: "saved",
});
await addTab("about:blank"); // removed by undoCloseTab
await saveAndCloseGroup(win.gBrowser.getTabGroupById(groupId));
await resetTelemetry();
await BrowserTestUtils.waitForCondition(
() => !win.gBrowser.getAllTabGroups().length,
"waiting for an empty group list"
);
info("restoring saved group from URLbar suggestion");
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window: win,
waitForFocus,
value: "reopen-test",
fireInputEvent: true,
reopenOnBlur: true,
});
let reopenGroupButton = win.gURLBar.panel.querySelector(
`[data-action^="tabgroup"]`
);
Assert.ok(!!reopenGroupButton, "Reopen group action is present in results");
let closedObjectsChanged = TestUtils.topicObserved(
"sessionstore-closed-objects-changed"
);
await UrlbarTestUtils.promisePopupClose(win, () => {
EventUtils.synthesizeKey("KEY_Tab", {}, win);
EventUtils.synthesizeKey("KEY_Enter", {}, win);
});
await closedObjectsChanged;
await waitForReopenRecord();
assertReopenEvent({
id: groupId,
source: "suggest",
layout: expectedLayout,
type: "saved",
});
await win.gBrowser.removeTabGroup(win.gBrowser.getTabGroupById(groupId));
await resetTelemetry();
await SpecialPowers.popPrefEnv();
}
add_task(async function test_reopenSavedGroupTelemetry() {
info("Perform reopen tests in horizontal tabs mode");
await doReopenTests(false);
info("Perform reopen tests in vertical tabs mode");
await doReopenTests(true);
});