Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
*/
/**
* This file tests urlbar telemetry with search related actions.
*/
"use strict";
const SCALAR_URLBAR = "browser.engagement.navigation.urlbar";
const SCALAR_SEARCHMODE = "browser.engagement.navigation.urlbar_searchmode";
// The preference to enable suggestions in the urlbar.
const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
ChromeUtils.defineESModuleGetters(this, {
SearchSERPTelemetry:
"moz-src:///browser/components/search/SearchSERPTelemetry.sys.mjs",
});
function searchInAwesomebar(value, win = window) {
return UrlbarTestUtils.promiseAutocompleteResultPopup({
window: win,
waitForFocus,
value,
fireInputEvent: true,
});
}
/**
* Click one of the entries in the urlbar suggestion popup.
*
* @param {string} resultTitle
* The title of the result to click on.
* @param {number} button [optional]
* which button to click.
* @returns {number}
* The index of the result that was clicked, or -1 if not found.
*/
async function clickURLBarSuggestion(resultTitle, button = 1) {
await UrlbarTestUtils.promiseSearchComplete(window);
const count = UrlbarTestUtils.getResultCount(window);
for (let i = 0; i < count; i++) {
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, i);
if (result.displayed.title == resultTitle) {
// This entry is the search suggestion we're looking for.
let element = await UrlbarTestUtils.waitForAutocompleteResultAt(
window,
i
);
if (button == 1) {
EventUtils.synthesizeMouseAtCenter(element, {});
} else if (button == 2) {
EventUtils.synthesizeMouseAtCenter(element, {
type: "mousedown",
button: 2,
});
}
return i;
}
}
return -1;
}
/**
* Create an engine to generate search suggestions and add it as default
* for this test.
*
* @param {Function} taskFn
* The function to run with the new search engine as default.
*/
async function withNewSearchEngine(taskFn) {
let suggestionEngine = await SearchTestUtils.installOpenSearchEngine({
url: getRootDirectory(gTestPath) + "urlbarTelemetrySearchSuggestions.xml",
});
let previousEngine = await SearchService.getDefault();
await SearchService.setDefault(
suggestionEngine,
SearchService.CHANGE_REASON.UNKNOWN
);
try {
await taskFn(suggestionEngine);
} finally {
await SearchService.setDefault(
previousEngine,
SearchService.CHANGE_REASON.UNKNOWN
);
await SearchService.removeEngine(suggestionEngine);
}
}
add_setup(async function () {
await SearchTestUtils.installSearchExtension(
{
name: "MozSearch",
keyword: "mozalias",
search_url: "https://example.com/",
},
{ setAsDefault: true }
);
// Make it the first one-off engine.
let engine = SearchService.getEngineByName("MozSearch");
await SearchService.moveEngine(engine, 0);
// Enable search suggestions in the urlbar.
let suggestionsEnabled = Services.prefs.getBoolPref(SUGGEST_URLBAR_PREF);
Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true);
// Enable local telemetry recording for the duration of the tests.
let oldCanRecord = Services.telemetry.canRecordExtended;
Services.telemetry.canRecordExtended = true;
// Clear history so that history added by previous tests doesn't mess up this
// test when it selects results in the urlbar.
await PlacesUtils.history.clear();
// Clear historical search suggestions to avoid interference from previous
// tests.
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.maxHistoricalSearchSuggestions", 0]],
});
// This test assumes that general results are shown before suggestions.
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.showSearchSuggestionsFirst", false]],
});
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.scotchBonnet.enableOverride", false]],
});
// Make sure to restore the engine once we're done.
registerCleanupFunction(async function () {
Services.telemetry.canRecordExtended = oldCanRecord;
Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, suggestionsEnabled);
await PlacesUtils.history.clear();
await UrlbarTestUtils.formHistory.clear();
});
});
add_task(async function test_simpleQuery() {
Services.telemetry.clearScalars();
Services.telemetry.clearEvents();
clearSAPTelemetry();
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
info("Simulate entering a simple search.");
let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await searchInAwesomebar("simple query");
EventUtils.synthesizeKey("KEY_Enter");
await p;
// Check if the scalars contain the expected values.
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, false);
TelemetryTestUtils.assertKeyedScalar(
scalars,
SCALAR_URLBAR,
"search_enter",
1
);
Assert.equal(
Object.keys(scalars[SCALAR_URLBAR]).length,
1,
"This search must only increment one entry in the scalar."
);
// SAP counts are incremented only for the urlbar source, since the internal
// @search keyword was not used.
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 1,
});
BrowserTestUtils.removeTab(tab);
});
add_task(async function test_searchMode_enter() {
Services.telemetry.clearScalars();
Services.telemetry.clearEvents();
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
info("Enter search mode using an alias and a query.");
let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await searchInAwesomebar("mozalias query");
EventUtils.synthesizeKey("KEY_Enter");
await p;
// Check if the scalars contain the expected values.
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, false);
TelemetryTestUtils.assertKeyedScalar(
scalars,
SCALAR_SEARCHMODE,
"search_enter",
1
);
Assert.equal(
Object.keys(scalars[SCALAR_SEARCHMODE]).length,
1,
"This search must only increment one entry in the scalar."
);
BrowserTestUtils.removeTab(tab);
});
// Performs a search using the first result, a one-off button, and the Return
// (Enter) key.
add_task(async function test_oneOff_enter() {
Services.telemetry.clearScalars();
Services.telemetry.clearEvents();
clearSAPTelemetry();
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
info("Perform a one-off search using the first engine.");
let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await searchInAwesomebar("query");
info("Pressing Alt+Down to take us to the first one-off engine.");
let searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
let engine =
UrlbarTestUtils.getOneOffSearchButtons(window).selectedButton.engine;
EventUtils.synthesizeKey("KEY_Enter");
await searchPromise;
await UrlbarTestUtils.assertSearchMode(window, {
engineName: engine.name,
entry: "oneoff",
});
// Now that we're in search mode, execute the search.
EventUtils.synthesizeKey("KEY_Enter");
await p;
// Check if the scalars contain the expected values.
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, false);
TelemetryTestUtils.assertKeyedScalar(
scalars,
SCALAR_SEARCHMODE,
"search_enter",
1
);
Assert.equal(
Object.keys(scalars[SCALAR_SEARCHMODE]).length,
1,
"This search must only increment one entry in the scalar."
);
// SAP counts should be incremented, but only the urlbar_searchmode source
// since aliases aren't counted separately in search mode.
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar_searchmode",
count: 1,
});
BrowserTestUtils.removeTab(tab);
});
// Clicks the first suggestion offered by the test search engine.
add_task(async function test_suggestion_click() {
Services.telemetry.clearScalars();
Services.telemetry.clearEvents();
await UrlbarTestUtils.formHistory.clear();
clearSAPTelemetry();
await withNewSearchEngine(async function (engine) {
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
info("Type a query. Suggestions should be generated by the test engine.");
let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await searchInAwesomebar("query");
info("Clicking the urlbar suggestion.");
await clickURLBarSuggestion("queryfoo");
await p;
// Check if the scalars contain the expected values.
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, false);
TelemetryTestUtils.assertKeyedScalar(
scalars,
SCALAR_URLBAR,
"search_suggestion",
1
);
Assert.equal(
Object.keys(scalars[SCALAR_URLBAR]).length,
1,
"This search must only increment one entry in the scalar."
);
await SearchUITestUtils.assertSAPTelemetry({
engineName: engine.name,
source: "urlbar",
count: 1,
});
BrowserTestUtils.removeTab(tab);
});
});
// Clicks the first suggestion offered by the test search engine when in search
// mode.
add_task(async function test_searchmode_suggestion_click() {
Services.telemetry.clearScalars();
Services.telemetry.clearEvents();
clearSAPTelemetry();
await withNewSearchEngine(async function (engine) {
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
info("Type a query. Suggestions should be generated by the test engine.");
await searchInAwesomebar("query");
await UrlbarTestUtils.enterSearchMode(window, {
engineName: engine.name,
});
info("Clicking the urlbar suggestion.");
let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await clickURLBarSuggestion("queryfoo");
await p;
// Check if the scalars contain the expected values.
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, false);
TelemetryTestUtils.assertKeyedScalar(
scalars,
SCALAR_SEARCHMODE,
"search_suggestion",
1
);
Assert.equal(
Object.keys(scalars[SCALAR_SEARCHMODE]).length,
1,
"This search must only increment one entry in the scalar."
);
await SearchUITestUtils.assertSAPTelemetry({
engineName: engine.name,
source: "urlbar_searchmode",
count: 1,
});
BrowserTestUtils.removeTab(tab);
});
});
// Clicks a form history result.
add_task(async function test_formHistory_click() {
Services.telemetry.clearScalars();
Services.telemetry.clearEvents();
clearSAPTelemetry();
await UrlbarTestUtils.formHistory.clear();
await UrlbarTestUtils.formHistory.add(["foobar"]);
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.maxHistoricalSearchSuggestions", 1]],
});
await withNewSearchEngine(async engine => {
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
info("Type a query. There should be form history.");
let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await searchInAwesomebar("foo");
info("Clicking the form history.");
await clickURLBarSuggestion("foobar");
await p;
// Check if the scalars contain the expected values.
const scalars = TelemetryTestUtils.getProcessScalars("parent", true, false);
TelemetryTestUtils.assertKeyedScalar(
scalars,
SCALAR_URLBAR,
"search_formhistory",
1
);
Assert.equal(
Object.keys(scalars[SCALAR_URLBAR]).length,
1,
"This search must only increment one entry in the scalar."
);
await SearchUITestUtils.assertSAPTelemetry({
engineName: engine.name,
source: "urlbar",
count: 1,
});
BrowserTestUtils.removeTab(tab);
await UrlbarTestUtils.formHistory.clear();
await SpecialPowers.popPrefEnv();
});
});
add_task(async function test_privateWindow() {
// This test assumes the showSearchTerms feature is not enabled,
// as multiple searches are made one after another, relying on
// urlbar as the keyed scalar SAP, not urlbar_persisted.
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.showSearchTerms.featureGate", false]],
});
// Override the search telemetry search provider info to
// count in-content SAP telemetry for our test engine.
SearchSERPTelemetry.overrideSearchTelemetryForTests([
{
telemetryId: "example",
searchPageRegexp: "^https://example\\.com/",
queryParamNames: ["q"],
},
]);
clearSAPTelemetry();
// First, do a bunch of searches in a private window.
let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
info("Search in a private window and the pref does not exist");
let p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 1,
});
let scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
1
);
info("Search again in a private window after setting the pref to true");
Services.prefs.setBoolPref("browser.engagement.search_counts.pbm", true);
p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("another query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
// SAP counts should not be incremented.
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 1,
});
scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
1
);
info("Search again in a private window after setting the pref to false");
Services.prefs.setBoolPref("browser.engagement.search_counts.pbm", false);
p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("another query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 2,
});
scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
2
);
info("Search again in a private window after clearing the pref");
Services.prefs.clearUserPref("browser.engagement.search_counts.pbm");
p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("another query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 3,
});
scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
3
);
await BrowserTestUtils.closeWindow(win);
// Now, do a bunch of searches in a non-private window. Telemetry should
// always be recorded regardless of the pref's value.
win = await BrowserTestUtils.openNewBrowserWindow();
info("Search in a non-private window and the pref does not exist");
p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 4,
});
scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
4
);
info("Search again in a non-private window after setting the pref to true");
Services.prefs.setBoolPref("browser.engagement.search_counts.pbm", true);
p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("another query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 5,
});
scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
5
);
info("Search again in a non-private window after setting the pref to false");
Services.prefs.setBoolPref("browser.engagement.search_counts.pbm", false);
p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("another query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 6,
});
scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
6
);
info("Search again in a non-private window after clearing the pref");
Services.prefs.clearUserPref("browser.engagement.search_counts.pbm");
p = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
await searchInAwesomebar("another query", win);
EventUtils.synthesizeKey("KEY_Enter", undefined, win);
await p;
await SearchUITestUtils.assertSAPTelemetry({
engineName: "MozSearch",
source: "urlbar",
count: 7,
});
scalars = TelemetryTestUtils.getProcessScalars("parent", true);
TelemetryTestUtils.assertKeyedScalar(
scalars,
"browser.search.content.urlbar",
"example:organic:none",
7
);
await BrowserTestUtils.closeWindow(win);
// Reset the search provider info.
SearchSERPTelemetry.overrideSearchTelemetryForTests();
await UrlbarTestUtils.formHistory.clear();
await SpecialPowers.popPrefEnv();
});