Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* Any copyright is dedicated to the Public Domain.
/**
* Tests the urlbar.autofill.input_context_menu_dismissal labeled counter,
* which records dismissals of adaptive autofill heuristic results via the
* urlbar input field's right-click context menu.
*/
"use strict";
const SEARCH_STRING = "exa";
const ADAPTIVE_INPUT = "exa";
const DISMISS_ID = "urlbar-input-dismiss-autofill";
const FORGET_ID = "urlbar-input-remove-from-history";
add_setup(async function () {
await PlacesUtils.history.clear();
await PlacesUtils.bookmarks.eraseEverything();
await SpecialPowers.pushPrefEnv({
set: [
["browser.urlbar.autoFill", true],
["browser.urlbar.autoFill.adaptiveHistory.enabled", true],
["browser.urlbar.autoFill.adaptiveHistory.minCharsThreshold", 0],
["browser.urlbar.autoFill.adaptiveHistory.useCountThreshold", 0],
["browser.urlbar.suggest.quicksuggest.sponsored", false],
["browser.urlbar.suggest.quicksuggest.nonsponsored", false],
],
});
registerCleanupFunction(async () => {
await PlacesUtils.history.clear();
await PlacesUtils.bookmarks.eraseEverything();
});
});
async function addAdaptiveHistoryEntry(url, input, useCount = 3) {
await PlacesTestUtils.addVisits({
uri: url,
transition: PlacesUtils.history.TRANSITIONS.TYPED,
});
for (let i = 0; i < useCount; i++) {
await UrlbarUtils.addToInputHistory(url, input);
}
}
async function showAutofillFor(win, value) {
await UrlbarTestUtils.promiseAutocompleteResultPopup({
window: win,
value,
fireInputEvent: true,
});
}
async function openAndCloseContextMenu(win) {
let textBox = win.gURLBar.querySelector("moz-input-box");
let cxmenu = textBox.menupopup;
let openPromise = BrowserTestUtils.waitForEvent(cxmenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(
win.gURLBar.inputField,
{ type: "contextmenu", button: 2 },
win
);
await openPromise;
await new Promise(win.requestAnimationFrame);
let closePromise = BrowserTestUtils.waitForEvent(cxmenu, "popuphidden");
cxmenu.hidePopup();
await closePromise;
}
// Wait for telemetry instead of instantly checking it because on some platforms
// when a context menu item is clicked it doesn't run immediately, a brief
// blink animation on the highlighted item will play. Polling gives the blink
// animation time to finish and the handler to run.
async function waitForLabel(label, expected, message) {
await TestUtils.waitForCondition(
() =>
Glean.urlbarAutofill.inputContextMenuDismissal[label].testGetValue() ===
expected,
message
);
}
// Dismissing an adaptive_url heuristic via the input context menu should
// increment the "dismiss" label exactly once.
add_task(async function dismiss_label_recorded_for_adaptive_url() {
Services.fog.testResetFOG();
await PlacesUtils.history.clear();
await addAdaptiveHistoryEntry(ADAPTIVE_URL, ADAPTIVE_INPUT);
await showAutofillFor(window, SEARCH_STRING);
await UrlbarTestUtils.activateContextMenuItem(window, DISMISS_ID);
await waitForLabel("dismiss", 1, "Dismiss label should be incremented once");
Assert.equal(
Glean.urlbarAutofill.inputContextMenuDismissal.forget.testGetValue(),
null,
"Forget label should not be incremented"
);
await UrlbarTestUtils.promisePopupClose(window);
await PlacesUtils.history.clear();
});
// Dismissing a plain origin autofill heuristic should also increment the
// "dismiss" label.
add_task(async function dismiss_label_recorded_for_origin_autofill() {
Services.fog.testResetFOG();
await PlacesUtils.history.clear();
await PlacesTestUtils.addVisits({
uri: ORIGIN_URL,
transition: PlacesUtils.history.TRANSITIONS.TYPED,
});
await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies();
await showAutofillFor(window, SEARCH_STRING);
await UrlbarTestUtils.activateContextMenuItem(window, DISMISS_ID);
await waitForLabel(
"dismiss",
1,
"Dismiss label should be incremented once for plain origin autofill"
);
Assert.equal(
Glean.urlbarAutofill.inputContextMenuDismissal.forget.testGetValue(),
null,
"Forget label should not be incremented"
);
await UrlbarTestUtils.promisePopupClose(window);
await PlacesUtils.history.clear();
});
// Forgetting an adaptive_url heuristic should increment the "forget" label
// and leave "dismiss" untouched.
add_task(async function forget_label_recorded_for_adaptive_url() {
Services.fog.testResetFOG();
await PlacesUtils.history.clear();
await addAdaptiveHistoryEntry(ADAPTIVE_URL, ADAPTIVE_INPUT);
await showAutofillFor(window, SEARCH_STRING);
await UrlbarTestUtils.activateContextMenuItem(window, FORGET_ID);
await waitForLabel("forget", 1, "Forget label should be incremented once");
Assert.equal(
Glean.urlbarAutofill.inputContextMenuDismissal.dismiss.testGetValue(),
null,
"Dismiss label should not be incremented"
);
await UrlbarTestUtils.promisePopupClose(window);
await PlacesUtils.history.clear();
});
// Repeated dismissals should accumulate on the same label.
add_task(async function dismiss_label_accumulates() {
Services.fog.testResetFOG();
await PlacesUtils.history.clear();
for (let i = 0; i < 3; i++) {
await addAdaptiveHistoryEntry(ADAPTIVE_URL, ADAPTIVE_INPUT);
await showAutofillFor(window, SEARCH_STRING);
await UrlbarTestUtils.activateContextMenuItem(window, DISMISS_ID);
await waitForLabel(
"dismiss",
i + 1,
`Dismiss label should be incremented to ${i + 1} after iteration ${i}`
);
await UrlbarTestUtils.promisePopupClose(window);
await PlacesUtils.history.clear();
}
Assert.equal(
Glean.urlbarAutofill.inputContextMenuDismissal.dismiss.testGetValue(),
3,
"Dismiss label should accumulate across multiple dismissals"
);
});
// Opening and closing the context menu without clicking Dismiss/Forget
// should not record telemetry.
add_task(async function no_telemetry_when_menu_not_activated() {
Services.fog.testResetFOG();
await PlacesUtils.history.clear();
await addAdaptiveHistoryEntry(ADAPTIVE_URL, ADAPTIVE_INPUT);
await showAutofillFor(window, SEARCH_STRING);
await openAndCloseContextMenu(window);
Assert.equal(
Glean.urlbarAutofill.inputContextMenuDismissal.dismiss.testGetValue(),
null,
"Dismiss label should not be recorded when the menu is dismissed"
);
Assert.equal(
Glean.urlbarAutofill.inputContextMenuDismissal.forget.testGetValue(),
null,
"Forget label should not be recorded when the menu is dismissed"
);
await UrlbarTestUtils.promisePopupClose(window);
await PlacesUtils.history.clear();
});
// In a private window, the Dismiss item is hidden, so no dismiss telemetry
// can be recorded from there.
add_task(async function no_dismiss_telemetry_in_private_window() {
Services.fog.testResetFOG();
await PlacesUtils.history.clear();
await addAdaptiveHistoryEntry(ADAPTIVE_URL, ADAPTIVE_INPUT);
let privateWin = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
await showAutofillFor(privateWin, SEARCH_STRING);
await openAndCloseContextMenu(privateWin);
Assert.equal(
Glean.urlbarAutofill.inputContextMenuDismissal.dismiss.testGetValue(),
null,
"Dismiss label should not be recorded in a private window"
);
await UrlbarTestUtils.promisePopupClose(privateWin);
await BrowserTestUtils.closeWindow(privateWin);
await PlacesUtils.history.clear();
});