/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /** * 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: "resource:///modules/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.promiseNewSearchEngine({ url: getRootDirectory(gTestPath) + "urlbarTelemetrySearchSuggestions.xml", }); let previousEngine = await Services.search.getDefault(); await Services.search.setDefault( suggestionEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); try { await taskFn(suggestionEngine); } finally { await Services.search.setDefault( previousEngine, Ci.nsISearchService.CHANGE_REASON_UNKNOWN ); await Services.search.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 = Services.search.getEngineByName("MozSearch"); await Services.search.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; // Enable event recording for the events tested here. Services.telemetry.setEventRecordingEnabled("navigation", 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]], }); // 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(); Services.telemetry.setEventRecordingEnabled("navigation", false); }); }); add_task(async function test_simpleQuery() { Services.telemetry.clearScalars(); Services.telemetry.clearEvents(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); let search_hist = TelemetryTestUtils.getAndClearKeyedHistogram("SEARCH_COUNTS"); 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." ); // SEARCH_COUNTS should be incremented, but only the urlbar source since an // internal @search keyword was not used. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 1 ); TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.alias", undefined ); // Also check events. TelemetryTestUtils.assertEvents( [ [ "navigation", "search", "urlbar", "enter", { engine: "other-MozSearch" }, ], ], { category: "navigation", method: "search" } ); TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.enter, 1 ); BrowserTestUtils.removeTab(tab); }); add_task(async function test_searchMode_enter() { Services.telemetry.clearScalars(); Services.telemetry.clearEvents(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); 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." ); // Also check events. TelemetryTestUtils.assertEvents( [ [ "navigation", "search", "urlbar_searchmode", "enter", { engine: "other-MozSearch" }, ], ], { category: "navigation", method: "search" } ); TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.enter, 1 ); 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(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); let search_hist = TelemetryTestUtils.getAndClearKeyedHistogram("SEARCH_COUNTS"); 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." ); // SEARCH_COUNTS should be incremented, but only the urlbar-searchmode source // since aliases aren't counted separately in search mode. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar-searchmode", 1 ); TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.alias", undefined ); // Also check events. TelemetryTestUtils.assertEvents( [ [ "navigation", "search", "urlbar_searchmode", "enter", { engine: "other-MozSearch" }, ], ], { category: "navigation", method: "search" } ); TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.enter, 1 ); BrowserTestUtils.removeTab(tab); }); // Performs a search using the second result, a one-off button, and the Return // (Enter) key. This only tests the FX_URLBAR_SELECTED_RESULT_METHOD histogram // since test_oneOff_enter covers everything else. add_task(async function test_oneOff_enterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); await withNewSearchEngine(async function () { await SpecialPowers.pushPrefEnv({ set: [["browser.urlbar.maxHistoricalSearchSuggestions", 1]], }); 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( "Select the second result, press 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_ArrowDown"); EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.arrowEnterSelection, 1 ); await SpecialPowers.popPrefEnv(); BrowserTestUtils.removeTab(tab); }); }); // Performs a search using a click on a one-off button. This only tests the // FX_URLBAR_SELECTED_RESULT_METHOD histogram since test_oneOff_enter covers // everything else. add_task(async function test_oneOff_click() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); let tab = await BrowserTestUtils.openNewForegroundTab( gBrowser, "about:blank" ); info("Type a query."); let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); await searchInAwesomebar("query"); info("Click the first one-off button."); let searchPromise = UrlbarTestUtils.promiseSearchComplete(window); let oneOffButton = UrlbarTestUtils.getOneOffSearchButtons(window).getSelectableButtons( false )[0]; oneOffButton.click(); await searchPromise; await UrlbarTestUtils.assertSearchMode(window, { engineName: oneOffButton.engine.name, entry: "oneoff", }); // Now that we're in search mode, execute the search. let element = await UrlbarTestUtils.waitForAutocompleteResultAt(window, 0); Assert.ok(element, "Found result after entering search mode."); EventUtils.synthesizeMouseAtCenter(element, {}); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.click, 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(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); let search_hist = TelemetryTestUtils.getAndClearKeyedHistogram("SEARCH_COUNTS"); 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." ); // SEARCH_COUNTS should be incremented. let searchEngineId = "other-" + engine.name; TelemetryTestUtils.assertKeyedHistogramSum( search_hist, searchEngineId + ".urlbar", 1 ); // Also check events. TelemetryTestUtils.assertEvents( [ [ "navigation", "search", "urlbar", "suggestion", { engine: searchEngineId }, ], ], { category: "navigation", method: "search" } ); TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.click, 1 ); BrowserTestUtils.removeTab(tab); }); }); // Selects and presses the Return (Enter) key on the first suggestion offered by // the test search engine. This only tests the FX_URLBAR_SELECTED_RESULT_METHOD // histogram since test_suggestion_click covers everything else. add_task(async function test_suggestion_arrowEnterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); await withNewSearchEngine(async function () { 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("Select the second result and press Return."); EventUtils.synthesizeKey("KEY_ArrowDown"); EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.arrowEnterSelection, 1 ); BrowserTestUtils.removeTab(tab); }); }); // Selects through tab and presses the Return (Enter) key on the first // suggestion offered by the test search engine. add_task(async function test_suggestion_tabEnterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); await withNewSearchEngine(async function () { 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("Select the second result and press Return."); EventUtils.synthesizeKey("KEY_Tab"); EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.tabEnterSelection, 1 ); BrowserTestUtils.removeTab(tab); }); }); // Selects through code and presses the Return (Enter) key on the first // suggestion offered by the test search engine. add_task(async function test_suggestion_enterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); await withNewSearchEngine(async function () { 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("Select the second result and press Return."); UrlbarTestUtils.setSelectedRowIndex(window, 1); EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.enterSelection, 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(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); let search_hist = TelemetryTestUtils.getAndClearKeyedHistogram("SEARCH_COUNTS"); 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." ); // SEARCH_COUNTS should be incremented. let searchEngineId = "other-" + engine.name; TelemetryTestUtils.assertKeyedHistogramSum( search_hist, searchEngineId + ".urlbar-searchmode", 1 ); // Also check events. TelemetryTestUtils.assertEvents( [ [ "navigation", "search", "urlbar_searchmode", "suggestion", { engine: searchEngineId }, ], ], { category: "navigation", method: "search" } ); TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.click, 1 ); BrowserTestUtils.removeTab(tab); }); }); // Selects and presses the Return (Enter) key on the first suggestion offered by // the test search engine in search mode. This only tests the // FX_URLBAR_SELECTED_RESULT_METHOD histogram since // test_searchmode_suggestion_click covers everything else. add_task(async function test_searchmode_suggestion_arrowEnterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); 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"); await UrlbarTestUtils.enterSearchMode(window, { engineName: engine.name, }); info("Select the second result and press Return."); EventUtils.synthesizeKey("KEY_ArrowDown"); EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.arrowEnterSelection, 1 ); BrowserTestUtils.removeTab(tab); }); }); // Selects through tab and presses the Return (Enter) key on the first // suggestion offered by the test search engine in search mode. add_task(async function test_suggestion_tabEnterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); 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"); await UrlbarTestUtils.enterSearchMode(window, { engineName: engine.name, }); info("Select the second result and press Return."); EventUtils.synthesizeKey("KEY_Tab"); EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.tabEnterSelection, 1 ); BrowserTestUtils.removeTab(tab); }); }); // Selects through code and presses the Return (Enter) key on the first // suggestion offered by the test search engine in search mode. add_task(async function test_suggestion_enterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); 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"); await UrlbarTestUtils.enterSearchMode(window, { engineName: engine.name, }); info("Select the second result and press Return."); UrlbarTestUtils.setSelectedRowIndex(window, 1); EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.enterSelection, 1 ); BrowserTestUtils.removeTab(tab); }); }); // Clicks a form history result. add_task(async function test_formHistory_click() { Services.telemetry.clearScalars(); Services.telemetry.clearEvents(); await UrlbarTestUtils.formHistory.clear(); await UrlbarTestUtils.formHistory.add(["foobar"]); await SpecialPowers.pushPrefEnv({ set: [["browser.urlbar.maxHistoricalSearchSuggestions", 1]], }); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); let search_hist = TelemetryTestUtils.getAndClearKeyedHistogram("SEARCH_COUNTS"); 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." ); // SEARCH_COUNTS should be incremented. let searchEngineId = "other-" + engine.name; TelemetryTestUtils.assertKeyedHistogramSum( search_hist, searchEngineId + ".urlbar", 1 ); // Also check events. TelemetryTestUtils.assertEvents( [ [ "navigation", "search", "urlbar", "formhistory", { engine: searchEngineId }, ], ], { category: "navigation", method: "search" } ); TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.click, 1 ); BrowserTestUtils.removeTab(tab); await UrlbarTestUtils.formHistory.clear(); await SpecialPowers.popPrefEnv(); }); }); // Selects and presses the Return (Enter) key on a form history result. This // only tests the FX_URLBAR_SELECTED_RESULT_METHOD histogram since // test_formHistory_click covers everything else. add_task(async function test_formHistory_arrowEnterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); await UrlbarTestUtils.formHistory.clear(); await UrlbarTestUtils.formHistory.add(["foobar"]); await SpecialPowers.pushPrefEnv({ set: [["browser.urlbar.maxHistoricalSearchSuggestions", 1]], }); await withNewSearchEngine(async function () { 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("Select the form history result and press Return."); while (gURLBar.untrimmedValue != "foobar") { EventUtils.synthesizeKey("KEY_ArrowDown"); } EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.arrowEnterSelection, 1 ); BrowserTestUtils.removeTab(tab); await UrlbarTestUtils.formHistory.clear(); await SpecialPowers.popPrefEnv(); }); }); // Selects through tab and presses the Return (Enter) key on a form history // result. add_task(async function test_formHistory_tabEnterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); await UrlbarTestUtils.formHistory.clear(); await UrlbarTestUtils.formHistory.add(["foobar"]); await SpecialPowers.pushPrefEnv({ set: [["browser.urlbar.maxHistoricalSearchSuggestions", 1]], }); await withNewSearchEngine(async function () { 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("Select the form history result and press Return."); while (gURLBar.untrimmedValue != "foobar") { EventUtils.synthesizeKey("KEY_Tab"); } EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.tabEnterSelection, 1 ); BrowserTestUtils.removeTab(tab); await UrlbarTestUtils.formHistory.clear(); await SpecialPowers.popPrefEnv(); }); }); // Selects through code and presses the Return (Enter) key on a form history // result. add_task(async function test_formHistory_enterSelection() { Services.telemetry.clearScalars(); let resultMethodHist = TelemetryTestUtils.getAndClearHistogram( "FX_URLBAR_SELECTED_RESULT_METHOD" ); await UrlbarTestUtils.formHistory.clear(); await UrlbarTestUtils.formHistory.add(["foobar"]); await SpecialPowers.pushPrefEnv({ set: [["browser.urlbar.maxHistoricalSearchSuggestions", 1]], }); await withNewSearchEngine(async function () { 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("Select the second result and press Return."); let index = 1; while (gURLBar.untrimmedValue != "foobar") { UrlbarTestUtils.setSelectedRowIndex(window, index++); } EventUtils.synthesizeKey("KEY_Enter"); await p; TelemetryTestUtils.assertHistogram( resultMethodHist, UrlbarTestUtils.SELECTED_RESULT_METHODS.enterSelection, 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 SEARCH_COUNTs telemetry for our test engine. SearchSERPTelemetry.overrideSearchTelemetryForTests([ { telemetryId: "example", searchPageRegexp: "^https://example\\.com/", queryParamName: "q", }, ]); let search_hist = TelemetryTestUtils.getAndClearKeyedHistogram("SEARCH_COUNTS"); // 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; // SEARCH_COUNTS should be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 1 ); let scalars = TelemetryTestUtils.getProcessScalars("parent", true); console.log(scalars); 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; // SEARCH_COUNTS should *not* be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 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; // SEARCH_COUNTS should be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 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; // SEARCH_COUNTS should be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 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; // SEARCH_COUNTS should be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 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; // SEARCH_COUNTS should be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 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; // SEARCH_COUNTS should be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 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; // SEARCH_COUNTS should be incremented. TelemetryTestUtils.assertKeyedHistogramSum( search_hist, "other-MozSearch.urlbar", 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(); });