Bug 1833669 - Add telemetry for open tabs r=fxview-reviewers,kcochrane

* Add events to new context menu items and open tab clicks

Differential Revision: https://phabricator.services.mozilla.com/D188962
This commit is contained in:
Sarah Clements 2023-09-26 12:40:46 +00:00
Родитель f1cb7e564b
Коммит 746e764f2c
5 изменённых файлов: 133 добавлений и 179 удалений

Просмотреть файл

@ -333,19 +333,22 @@ class OpenTabsInViewCard extends ViewPage {
this.recordContextMenuTelemetry("close-tab", e);
}
moveTabsToStart() {
moveTabsToStart(e) {
const tab = this.triggerNode.tabElement;
tab?.ownerGlobal.gBrowser.moveTabsToStart(tab);
this.recordContextMenuTelemetry("move-tab-start", e);
}
moveTabsToEnd() {
moveTabsToEnd(e) {
const tab = this.triggerNode.tabElement;
tab?.ownerGlobal.gBrowser.moveTabsToEnd(tab);
this.recordContextMenuTelemetry("move-tab-end", e);
}
moveTabsToWindow() {
moveTabsToWindow(e) {
const tab = this.triggerNode.tabElement;
tab?.ownerGlobal.gBrowser.replaceTabsWithWindow(tab);
this.recordContextMenuTelemetry("move-tab-window", e);
}
moveMenuTemplate() {
@ -383,6 +386,8 @@ class OpenTabsInViewCard extends ViewPage {
let deviceId = e.target.getAttribute("device-id");
let device = this.devices.find(dev => dev.id == deviceId);
this.recordContextMenuTelemetry("send-tab-device", e);
if (device && this.triggerNode) {
await this.getWindow().gSync.sendTabToDevice(
this.triggerNode.url,
@ -462,6 +467,24 @@ class OpenTabsInViewCard extends ViewPage {
}
}
onTabListRowClick(event) {
const tab = event.originalTarget.tabElement;
const browserWindow = tab.ownerGlobal;
browserWindow.focus();
browserWindow.gBrowser.selectedTab = tab;
Services.telemetry.recordEvent(
"firefoxview_next",
"open_tab",
"tabs",
null,
{
page: this.recentBrowsing ? "recentbrowsing" : "opentabs",
window: this.title || "Window 1 (Current)",
}
);
}
render() {
return html`
<link
@ -484,7 +507,7 @@ class OpenTabsInViewCard extends ViewPage {
class="with-context-menu"
.hasPopup=${"menu"}
?compactRows=${this.classList.contains("width-limited")}
@fxview-tab-list-primary-action=${onTabListRowClick}
@fxview-tab-list-primary-action=${this.onTabListRowClick}
@fxview-tab-list-secondary-action=${this.openContextMenu}
.maxTabsLength=${this.getMaxTabsLength()}
.tabItems=${getTabListItems(this.tabs)}
@ -537,10 +560,3 @@ function getTabListItems(tabs) {
url: tab.linkedBrowser?.currentURI?.spec,
}));
}
function onTabListRowClick(event) {
const tab = event.originalTarget.tabElement;
const browserWindow = tab.ownerGlobal;
browserWindow.focus();
browserWindow.gBrowser.selectedTab = tab;
}

Просмотреть файл

@ -11,111 +11,6 @@ const CARD_EXPANDED_EVENT = [
["firefoxview_next", "card_expanded", "card_container", undefined],
];
async function cardCollapsedTelemetry() {
await TestUtils.waitForCondition(
() => {
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
).parent;
return events && events.length >= 1;
},
"Waiting for card_collapsed firefoxview_next telemetry event.",
200,
100
);
TelemetryTestUtils.assertEvents(
CARD_COLLAPSED_EVENT,
{ category: "firefoxview_next" },
{ clear: true, process: "parent" }
);
}
async function cardExpandedTelemetry() {
await TestUtils.waitForCondition(
() => {
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
).parent;
return events && events.length >= 1;
},
"Waiting for card_expanded firefoxview_next telemetry event.",
200,
100
);
TelemetryTestUtils.assertEvents(
CARD_EXPANDED_EVENT,
{ category: "firefoxview_next" },
{ clear: true, process: "parent" }
);
}
async function navigationTelemetry(changePageEvent) {
await TestUtils.waitForCondition(
() => {
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
).parent;
return events && events.length >= 1;
},
"Waiting for change_page firefoxview_next telemetry event.",
200,
100
);
TelemetryTestUtils.assertEvents(
changePageEvent,
{ category: "firefoxview_next" },
{ clear: true, process: "parent" }
);
}
async function contextMenuTelemetry(contextMenuEvent) {
await TestUtils.waitForCondition(
() => {
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
).parent;
return events && events.length >= 1;
},
"Waiting for context_menu firefoxview_next telemetry event.",
200,
100
);
TelemetryTestUtils.assertEvents(
contextMenuEvent,
{ category: "firefoxview_next" },
{ clear: true, process: "parent" }
);
}
async function enteredTelemetry(enteredEvent) {
await TestUtils.waitForCondition(
() => {
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
).parent;
return events && events.length >= 1;
},
"Waiting for entered firefoxview_next telemetry event.",
200,
100
);
TelemetryTestUtils.assertEvents(
enteredEvent,
{ category: "firefoxview_next" },
{ clear: true, process: "parent" }
);
}
add_setup(async () => {
await SpecialPowers.pushPrefEnv({ set: [[FXVIEW_NEXT_ENABLED_PREF, true]] });
registerCleanupFunction(async () => {
@ -151,7 +46,7 @@ add_task(async function test_collapse_and_expand_card() {
false,
"The card-container is collapsed"
);
await cardCollapsedTelemetry();
await telemetryEvent(CARD_COLLAPSED_EVENT);
// Click the summary again to expand the details disclosure
await EventUtils.synthesizeMouseAtCenter(
cardContainer.summaryEl,
@ -163,7 +58,7 @@ add_task(async function test_collapse_and_expand_card() {
true,
"The card-container is expanded"
);
await cardExpandedTelemetry();
await telemetryEvent(CARD_EXPANDED_EVENT);
});
});
@ -182,7 +77,7 @@ add_task(async function test_change_page_telemetry() {
];
await clearAllParentTelemetryEvents();
navigateToCategory(document, "recentlyclosed");
await navigationTelemetry(changePageEvent);
await telemetryEvent(changePageEvent);
navigateToCategory(document, "recentbrowsing");
let openTabsComponent = document.querySelector(
@ -202,7 +97,7 @@ add_task(async function test_change_page_telemetry() {
];
await clearAllParentTelemetryEvents();
await EventUtils.synthesizeMouseAtCenter(viewAllLink, {}, content);
await navigationTelemetry(changePageEvent);
await telemetryEvent(changePageEvent);
});
});
@ -216,64 +111,13 @@ add_task(async function test_context_menu_telemetry() {
const { document } = browser.contentWindow;
is(document.location.href, "about:firefoxview-next");
// Test open tabs telemetry
let openTabsComponent = document.querySelector(
"view-opentabs[slot=opentabs]"
);
let tabList =
openTabsComponent.shadowRoot.querySelector("view-opentabs-card").tabList;
let firstItem = tabList.rowEls[0];
let panelList =
openTabsComponent.shadowRoot.querySelector(
"view-opentabs-card"
).panelList;
await EventUtils.synthesizeMouseAtCenter(firstItem.buttonEl, {}, content);
await BrowserTestUtils.waitForEvent(panelList, "shown");
await clearAllParentTelemetryEvents();
let copyLinkOption = panelList.querySelector(
"panel-item[data-l10n-id=fxviewtabrow-copy-link]"
);
ok(copyLinkOption, "Copy link panel item exists");
let contextMenuEvent = [
[
"firefoxview_next",
"context_menu",
"tabs",
undefined,
{ menu_action: "copy-link", data_type: "opentabs" },
],
];
await EventUtils.synthesizeMouseAtCenter(copyLinkOption, {}, content);
await contextMenuTelemetry(contextMenuEvent);
// Open new tab to test 'Close tab' menu option
window.openTrustedLinkIn("about:robots", "tab");
await switchToFxViewTab(browser.ownerGlobal);
firstItem = tabList.rowEls[0];
await EventUtils.synthesizeMouseAtCenter(firstItem.buttonEl, {}, content);
await BrowserTestUtils.waitForEvent(panelList, "shown");
await clearAllParentTelemetryEvents();
let closeTabOption = panelList.children[0];
contextMenuEvent = [
[
"firefoxview_next",
"context_menu",
"tabs",
undefined,
{ menu_action: "close-tab", data_type: "opentabs" },
],
];
await EventUtils.synthesizeMouseAtCenter(closeTabOption, {}, content);
await contextMenuTelemetry(contextMenuEvent);
// Test history context menu options
navigateToCategory(document, "history");
let historyComponent = document.querySelector("view-history");
await TestUtils.waitForCondition(() => historyComponent.fullyUpdated);
let firstTabList = historyComponent.lists[0];
firstItem = firstTabList.rowEls[0];
panelList = historyComponent.panelList;
let firstItem = firstTabList.rowEls[0];
let panelList = historyComponent.panelList;
await EventUtils.synthesizeMouseAtCenter(firstItem.buttonEl, {}, content);
await BrowserTestUtils.waitForEvent(panelList, "shown");
await clearAllParentTelemetryEvents();
@ -281,7 +125,7 @@ add_task(async function test_context_menu_telemetry() {
panelItem => panelItem.nodeName === "PANEL-ITEM"
);
let openInNewWindowOption = panelItems[1];
contextMenuEvent = [
let contextMenuEvent = [
[
"firefoxview_next",
"context_menu",
@ -299,7 +143,7 @@ add_task(async function test_context_menu_telemetry() {
content
);
let win = await newWindowPromise;
await contextMenuTelemetry(contextMenuEvent);
await telemetryEvent(contextMenuEvent);
await BrowserTestUtils.closeWindow(win);
await EventUtils.synthesizeMouseAtCenter(firstItem.buttonEl, {}, content);
@ -324,7 +168,7 @@ add_task(async function test_context_menu_telemetry() {
content
);
win = await newWindowPromise;
await contextMenuTelemetry(contextMenuEvent);
await telemetryEvent(contextMenuEvent);
ok(
PrivateBrowsingUtils.isWindowPrivate(win),
"Should have opened a private window."
@ -349,7 +193,7 @@ add_task(async function test_context_menu_telemetry() {
{},
content
);
await contextMenuTelemetry(contextMenuEvent);
await telemetryEvent(contextMenuEvent);
// clean up extra tabs
while (gBrowser.tabs.length > 1) {
@ -373,7 +217,7 @@ add_task(async function firefox_view_entered_telemetry() {
{ page: "recentbrowsing" },
],
];
await enteredTelemetry(enteredEvent);
await telemetryEvent(enteredEvent);
enteredEvent = [
[
@ -394,7 +238,7 @@ add_task(async function firefox_view_entered_telemetry() {
"The selected tab is about:robots"
);
await switchToFxViewTab(browser.ownerGlobal);
await enteredTelemetry(enteredEvent);
await telemetryEvent(enteredEvent);
await SpecialPowers.popPrefEnv();
// clean up extra tabs
while (gBrowser.tabs.length > 1) {

Просмотреть файл

@ -96,9 +96,22 @@ add_task(async function test_more_menus() {
);
ok(panelItem, "Close Tab panel item exists");
await clearAllParentTelemetryEvents();
let contextMenuEvent = [
[
"firefoxview_next",
"context_menu",
"tabs",
undefined,
{ menu_action: "close-tab", data_type: "opentabs" },
],
];
// close a tab via the menu
panelItem.click();
await telemetryEvent(contextMenuEvent);
let visibleTabs = gBrowser.visibleTabs;
is(visibleTabs.length, 2, "Expected to now have 2 open tabs");
await cards[0].getUpdateComplete();
@ -140,9 +153,21 @@ add_task(async function test_more_menus() {
EventUtils.synthesizeKey("KEY_ArrowRight", {});
await shown;
await clearAllParentTelemetryEvents();
contextMenuEvent = [
[
"firefoxview_next",
"context_menu",
"tabs",
null,
{ menu_action: "move-tab-end", data_type: "opentabs" },
],
];
// click on the first option, which should be "Move to the end" since
// this is the first tab
EventUtils.synthesizeKey("KEY_Enter", {});
await telemetryEvent(contextMenuEvent);
visibleTabs = gBrowser.visibleTabs;
is(
@ -179,7 +204,20 @@ add_task(async function test_more_menus() {
"panel-item[data-l10n-id=fxviewtabrow-copy-link]"
);
ok(panelItem, "Copy link panel item exists");
await clearAllParentTelemetryEvents();
contextMenuEvent = [
[
"firefoxview_next",
"context_menu",
"tabs",
null,
{ menu_action: "copy-link", data_type: "opentabs" },
],
];
panelItem.click();
await telemetryEvent(contextMenuEvent);
let copiedText = SpecialPowers.getClipboardData(
"text/plain",
@ -261,9 +299,22 @@ add_task(async function test_send_device_submenu() {
)
.returns(true);
await clearAllParentTelemetryEvents();
let contextMenuEvent = [
[
"firefoxview_next",
"context_menu",
"tabs",
null,
{ menu_action: "send-tab-device", data_type: "opentabs" },
],
];
// click on the first device and verify it was "sent"
EventUtils.synthesizeKey("KEY_Enter", {});
expectation.verify();
await telemetryEvent(contextMenuEvent);
sandbox.restore();
TabsSetupFlowManager.resetInternalState();

Просмотреть файл

@ -627,3 +627,29 @@ async function clickFirefoxViewButton(win) {
win.browsingContext
);
}
/**
* Wait for and assert telemetry events.
*
* @param {Array} Nested array of event details
*/
async function telemetryEvent(eventDetails) {
await TestUtils.waitForCondition(
() => {
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
false
).parent;
return events && events.length >= 1;
},
"Waiting for firefoxview_next telemetry event.",
200,
100
);
TelemetryTestUtils.assertEvents(
eventDetails,
{ category: "firefoxview_next" },
{ clear: true, process: "parent" }
);
}

Просмотреть файл

@ -4161,6 +4161,23 @@ firefoxview_next:
- 1833674
expiry_version: "never"
release_channel_collection: opt-out
open_tab:
objects: ["tabs"]
description: Recorded when an open tab is clicked
extra_keys:
page: The short page name where the open tab was clicked
window: The window the open tab belongs to
notification_emails:
- firefoxview@mozilla.com
products:
- "firefox"
record_in_processes:
- main
bug_numbers:
- 1833669
expiry_version: "never"
release_channel_collection: opt-out
search:
engine: