From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- .../urlbar/tests/UrlbarTestUtils.sys.mjs | 17 +- .../urlbar/tests/browser-tips/browser_picks.js | 10 +- .../tests/browser-tips/browser_searchTips.js | 2 +- .../browser-tips/browser_searchTips_interaction.js | 2 +- .../components/urlbar/tests/browser/browser.toml | 14 +- .../tests/browser/browser_UrlbarInput_overflow.js | 2 +- .../tests/browser/browser_aboutHomeLoading.js | 4 +- .../browser_acknowledgeFeedbackAndDismissal.js | 4 +- .../tests/browser/browser_copy_during_load.js | 2 +- .../urlbar/tests/browser/browser_dynamicResults.js | 4 +- .../urlbar/tests/browser/browser_engagement.js | 29 +- .../browser_less_common_selection_manipulations.js | 288 ++++++++++++++ .../tests/browser/browser_locationBarCommand.js | 2 +- .../browser_primary_selection_safe_on_new_tab.js | 2 +- .../urlbar/tests/browser/browser_raceWithTabs.js | 4 +- .../urlbar/tests/browser/browser_result_menu.js | 12 +- .../urlbar/tests/browser/browser_stop_pending.js | 4 +- .../browser_urlbar_telemetry_tabtosearch.js | 4 +- .../tests/engagementTelemetry/browser/browser.toml | 8 +- .../browser_glean_telemetry_abandonment_type.js | 8 +- .../browser_glean_telemetry_engagement_tips.js | 2 +- .../browser_glean_telemetry_engagement_type.js | 48 ++- .../browser/browser_glean_telemetry_exposure.js | 2 +- .../browser_glean_telemetry_potential_exposure.js | 438 +++++++++++++++++++++ .../browser/browser_glean_telemetry_reenter.js | 79 ++++ .../tests/engagementTelemetry/browser/head.js | 8 +- .../quicksuggest/QuickSuggestTestUtils.sys.mjs | 17 +- .../quicksuggest/browser/browser_quicksuggest.js | 37 ++ .../browser/browser_quicksuggest_addons.js | 7 +- .../browser/browser_quicksuggest_block.js | 5 - .../browser/browser_quicksuggest_mdn.js | 68 ++-- .../browser/browser_quicksuggest_pocket.js | 20 +- .../browser/browser_quicksuggest_yelp.js | 5 + .../browser/browser_telemetry_dynamicWikipedia.js | 5 - .../browser/browser_telemetry_gleanEmptyStrings.js | 5 - .../browser_telemetry_impressionEdgeCases.js | 11 +- .../browser/browser_telemetry_nonsponsored.js | 5 - .../browser/browser_telemetry_sponsored.js | 5 - .../urlbar/tests/quicksuggest/browser/head.js | 41 +- .../urlbar/tests/quicksuggest/unit/head.js | 10 +- .../unit/test_quicksuggest_impressionCaps.js | 2 +- .../unit/test_quicksuggest_merinoSessions.js | 2 +- .../urlbar/tests/quicksuggest/unit/test_weather.js | 2 +- .../components/urlbar/tests/unit/test_exposure.js | 11 +- .../components/urlbar/tests/unit/test_l10nCache.js | 2 +- 45 files changed, 1082 insertions(+), 177 deletions(-) create mode 100644 browser/components/urlbar/tests/browser/browser_less_common_selection_manipulations.js create mode 100644 browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_potential_exposure.js create mode 100644 browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_reenter.js (limited to 'browser/components/urlbar/tests') diff --git a/browser/components/urlbar/tests/UrlbarTestUtils.sys.mjs b/browser/components/urlbar/tests/UrlbarTestUtils.sys.mjs index cfc9ecb3d8..f576f4ca19 100644 --- a/browser/components/urlbar/tests/UrlbarTestUtils.sys.mjs +++ b/browser/components/urlbar/tests/UrlbarTestUtils.sys.mjs @@ -158,7 +158,7 @@ export var UrlbarTestUtils = { lazy.UrlbarPrefs.get("trimURLs") && value != lazy.BrowserUIUtils.trimURL(value) ) { - window.gURLBar._setValue(value, false); + window.gURLBar._setValue(value); fireInputEvent = true; } else { window.gURLBar.value = value; @@ -1315,10 +1315,7 @@ export var UrlbarTestUtils = { // Set most of the string directly instead of going through sendString, // so that we don't make life unnecessarily hard for consumers by // possibly starting multiple searches. - win.gURLBar._setValue( - text.substr(0, text.length - 1), - false /* allowTrim = */ - ); + win.gURLBar._setValue(text.substr(0, text.length - 1)); } this.EventUtils.sendString(text.substr(-1, 1), win); }, @@ -1490,7 +1487,7 @@ class TestProvider extends UrlbarProvider { * @param {Function} [options.onSelection] * If given, a function that will be called when * {@link UrlbarView.#selectElement} method is called. - * @param {Function} [options.onEngagement] + * @param {Function} [options.onLegacyEngagement] * If given, a function that will be called when engagement. * @param {Function} [options.delayResultsPromise] * If given, we'll await on this before returning results. @@ -1503,7 +1500,7 @@ class TestProvider extends UrlbarProvider { addTimeout = 0, onCancel = null, onSelection = null, - onEngagement = null, + onLegacyEngagement = null, delayResultsPromise = null, } = {}) { if (delayResultsPromise && addTimeout) { @@ -1520,7 +1517,7 @@ class TestProvider extends UrlbarProvider { this._type = type; this._onCancel = onCancel; this._onSelection = onSelection; - this._onEngagement = onEngagement; + this._onLegacyEngagement = onLegacyEngagement; // As this has been a common source of mistakes, auto-upgrade the provider // type to heuristic if any result is heuristic. @@ -1574,8 +1571,8 @@ class TestProvider extends UrlbarProvider { this._onSelection?.(result, element); } - onEngagement(state, queryContext, details, controller) { - this._onEngagement?.(state, queryContext, details, controller); + onLegacyEngagement(state, queryContext, details, controller) { + this._onLegacyEngagement?.(state, queryContext, details, controller); } } diff --git a/browser/components/urlbar/tests/browser-tips/browser_picks.js b/browser/components/urlbar/tests/browser-tips/browser_picks.js index ba0ff69357..c9d725dfb5 100644 --- a/browser/components/urlbar/tests/browser-tips/browser_picks.js +++ b/browser/components/urlbar/tests/browser-tips/browser_picks.js @@ -117,8 +117,8 @@ async function doTest({ click, buttonUrl = undefined, helpUrl = undefined }) { }); UrlbarProvidersManager.registerProvider(provider); - let onEngagementPromise = new Promise( - resolve => (provider.onEngagement = resolve) + let onLegacyEngagementPromise = new Promise( + resolve => (provider.onLegacyEngagement = resolve) ); // Do a search to show our tip result. @@ -142,8 +142,8 @@ async function doTest({ click, buttonUrl = undefined, helpUrl = undefined }) { ); } - // Now pick the target and wait for provider.onEngagement to be called and - // the URL to load if necessary. + // Now pick the target and wait for provider.onLegacyEngagement to be called + // and the URL to load if necessary. let loadPromise; if (buttonUrl || helpUrl) { loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); @@ -160,7 +160,7 @@ async function doTest({ click, buttonUrl = undefined, helpUrl = undefined }) { EventUtils.synthesizeKey("KEY_Enter"); } }); - await onEngagementPromise; + await onLegacyEngagementPromise; await loadPromise; // Check telemetry. diff --git a/browser/components/urlbar/tests/browser-tips/browser_searchTips.js b/browser/components/urlbar/tests/browser-tips/browser_searchTips.js index a82a2d658b..8c98e27993 100644 --- a/browser/components/urlbar/tests/browser-tips/browser_searchTips.js +++ b/browser/components/urlbar/tests/browser-tips/browser_searchTips.js @@ -18,7 +18,7 @@ ChromeUtils.defineESModuleGetters(this, { "resource:///modules/UrlbarProviderSearchTips.sys.mjs", }); -// These should match the same consts in UrlbarProviderSearchTips.jsm. +// These should match the same consts in UrlbarProviderSearchTips.sys.mjs. const MAX_SHOWN_COUNT = 4; const LAST_UPDATE_THRESHOLD_MS = 24 * 60 * 60 * 1000; diff --git a/browser/components/urlbar/tests/browser-tips/browser_searchTips_interaction.js b/browser/components/urlbar/tests/browser-tips/browser_searchTips_interaction.js index 72d05cf632..6c0550a2df 100644 --- a/browser/components/urlbar/tests/browser-tips/browser_searchTips_interaction.js +++ b/browser/components/urlbar/tests/browser-tips/browser_searchTips_interaction.js @@ -25,7 +25,7 @@ XPCOMUtils.defineLazyServiceGetter( "nsIClipboardHelper" ); -// These should match the same consts in UrlbarProviderSearchTips.jsm. +// These should match the same consts in UrlbarProviderSearchTips.sys.mjs. const MAX_SHOWN_COUNT = 4; const LAST_UPDATE_THRESHOLD_MS = 24 * 60 * 60 * 1000; diff --git a/browser/components/urlbar/tests/browser/browser.toml b/browser/components/urlbar/tests/browser/browser.toml index b9934aa838..44b964e5ca 100644 --- a/browser/components/urlbar/tests/browser/browser.toml +++ b/browser/components/urlbar/tests/browser/browser.toml @@ -4,7 +4,11 @@ support-files = [ "head.js", "head-common.js", ] - +skip-if = [ + "os == 'linux' && os_version == '18.04' && asan", # long running manifest + "os == 'linux' && os_version == '18.04' && tsan", # long running manifest + "win11_2009 && asan", # long running manifest +] prefs = [ "browser.bookmarks.testing.skipDefaultBookmarksImport=true", "browser.urlbar.trending.featureGate=false", @@ -280,6 +284,8 @@ support-files = [ ["browser_keyword_select_and_type.js"] +["browser_less_common_selection_manipulations.js"] + ["browser_loadRace.js"] ["browser_locationBarCommand.js"] @@ -398,9 +404,6 @@ https_first_disabled = true ["browser_revert.js"] -["browser_search_continuation.js"] -support-files = ["search-engines", "../../../search/test/browser/trendingSuggestionEngine.sjs"] - ["browser_searchFunction.js"] ["browser_searchHistoryLimit.js"] @@ -490,6 +493,9 @@ support-files = [ ["browser_search_bookmarks_from_bookmarks_menu.js"] +["browser_search_continuation.js"] +support-files = ["search-engines", "../../../search/test/browser/trendingSuggestionEngine.sjs"] + ["browser_search_history_from_history_panel.js"] ["browser_selectStaleResults.js"] diff --git a/browser/components/urlbar/tests/browser/browser_UrlbarInput_overflow.js b/browser/components/urlbar/tests/browser/browser_UrlbarInput_overflow.js index f191cae321..d01734959a 100644 --- a/browser/components/urlbar/tests/browser/browser_UrlbarInput_overflow.js +++ b/browser/components/urlbar/tests/browser/browser_UrlbarInput_overflow.js @@ -2,7 +2,7 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -async function testVal(aExpected, overflowSide = "") { +async function testVal(aExpected, overflowSide = null) { info(`Testing ${aExpected}`); try { gURLBar.setURI(makeURI(aExpected)); diff --git a/browser/components/urlbar/tests/browser/browser_aboutHomeLoading.js b/browser/components/urlbar/tests/browser/browser_aboutHomeLoading.js index 427a7419c8..bb710c7065 100644 --- a/browser/components/urlbar/tests/browser/browser_aboutHomeLoading.js +++ b/browser/components/urlbar/tests/browser/browser_aboutHomeLoading.js @@ -98,7 +98,7 @@ add_task(async function clearURLBarAfterManuallyLoadingAboutHome() { () => {} ); // This opens about:newtab: - BrowserOpenTab(); + BrowserCommands.openTab(); let tab = await promiseTabOpenedAndSwitchedTo; is(gURLBar.value, "", "URL bar should be empty"); is(tab.linkedBrowser.userTypedValue, null, "userTypedValue should be null"); @@ -132,7 +132,7 @@ add_task(async function dontTemporarilyShowAboutHome() { let win = OpenBrowserWindow(); await windowOpenedPromise; let promiseTabSwitch = BrowserTestUtils.switchTab(win.gBrowser, () => {}); - win.BrowserOpenTab(); + win.BrowserCommands.openTab(); await promiseTabSwitch; currentBrowser = win.gBrowser.selectedBrowser; is(win.gBrowser.visibleTabs.length, 2, "2 tabs opened"); diff --git a/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js b/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js index 8c4b05501e..54f40a85ee 100644 --- a/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js +++ b/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js @@ -389,11 +389,11 @@ class TestProvider extends UrlbarTestUtils.TestProvider { ]; } - onEngagement(state, queryContext, details, controller) { + onLegacyEngagement(state, queryContext, details, controller) { if (details.result?.providerName == this.name) { let { selType } = details; - info(`onEngagement called, selType=` + selType); + info(`onLegacyEngagement called, selType=` + selType); if (!this.commandCount.hasOwnProperty(selType)) { this.commandCount[selType] = 0; diff --git a/browser/components/urlbar/tests/browser/browser_copy_during_load.js b/browser/components/urlbar/tests/browser/browser_copy_during_load.js index 3eaa53bcda..e1d352a171 100644 --- a/browser/components/urlbar/tests/browser/browser_copy_during_load.js +++ b/browser/components/urlbar/tests/browser/browser_copy_during_load.js @@ -45,7 +45,7 @@ add_task(async function () { null, true ); - BrowserStop(); + BrowserCommands.stop(); await browserStoppedPromise; }); }); diff --git a/browser/components/urlbar/tests/browser/browser_dynamicResults.js b/browser/components/urlbar/tests/browser/browser_dynamicResults.js index aad15e0145..2ba1b7ab5f 100644 --- a/browser/components/urlbar/tests/browser/browser_dynamicResults.js +++ b/browser/components/urlbar/tests/browser/browser_dynamicResults.js @@ -511,7 +511,7 @@ add_task(async function shouldNavigate() { await UrlbarTestUtils.promisePopupClose(window, () => EventUtils.synthesizeKey("KEY_Enter") ); - // Verify that onEngagement was still called. + // Verify that onLegacyEngagement was still called. let [result, pickedElement] = await pickPromise; Assert.equal(result, row.result, "Picked result"); Assert.equal(pickedElement, element, "Picked element"); @@ -904,7 +904,7 @@ class TestProvider extends UrlbarTestUtils.TestProvider { }; } - onEngagement(state, queryContext, details, _controller) { + onLegacyEngagement(state, queryContext, details, _controller) { if (this._pickPromiseResolve) { let { result, element } = details; this._pickPromiseResolve([result, element]); diff --git a/browser/components/urlbar/tests/browser/browser_engagement.js b/browser/components/urlbar/tests/browser/browser_engagement.js index b1998b6f55..fbc321e322 100644 --- a/browser/components/urlbar/tests/browser/browser_engagement.js +++ b/browser/components/urlbar/tests/browser/browser_engagement.js @@ -1,7 +1,7 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -// Tests the UrlbarProvider.onEngagement() method. +// Tests the UrlbarProvider.onLegacyEngagement() method. "use strict"; @@ -110,32 +110,21 @@ async function doTest({ let provider = new TestProvider(); UrlbarProvidersManager.registerProvider(provider); - let startPromise = provider.promiseEngagement(); await UrlbarTestUtils.promiseAutocompleteResultPopup({ window: win, value: "test", fireInputEvent: true, }); - let [state, queryContext, details, controller] = await startPromise; - Assert.equal( - controller.input.isPrivate, - expectedIsPrivate, - "Start isPrivate" - ); - Assert.equal(state, "start", "Start state"); - - // `queryContext` isn't always defined for `start`, and `onEngagement` - // shouldn't rely on it being defined on start, but there's no good reason to - // assert that it's not defined here. - - // Similarly, `details` is never defined for `start`, but there's no good - // reason to assert that it's not defined. - let endPromise = provider.promiseEngagement(); let { result, element } = (await endEngagement()) ?? {}; - [state, queryContext, details, controller] = await endPromise; + let [state, queryContext, details, controller] = await endPromise; + + Assert.ok( + ["engagement", "abandonment"].includes(state), + "State should be either 'engagement' or 'abandonment'" + ); Assert.equal(controller.input.isPrivate, expectedIsPrivate, "End isPrivate"); Assert.equal(state, expectedEndState, "End state"); Assert.ok(queryContext, "End queryContext"); @@ -179,7 +168,7 @@ async function doTest({ } /** - * Test provider that resolves promises when onEngagement is called. + * Test provider that resolves promises when onLegacyEngagement is called. */ class TestProvider extends UrlbarTestUtils.TestProvider { _resolves = []; @@ -197,7 +186,7 @@ class TestProvider extends UrlbarTestUtils.TestProvider { }); } - onEngagement(...args) { + onLegacyEngagement(...args) { let resolve = this._resolves.shift(); if (resolve) { resolve(args); diff --git a/browser/components/urlbar/tests/browser/browser_less_common_selection_manipulations.js b/browser/components/urlbar/tests/browser/browser_less_common_selection_manipulations.js new file mode 100644 index 0000000000..2ad6ee0e07 --- /dev/null +++ b/browser/components/urlbar/tests/browser/browser_less_common_selection_manipulations.js @@ -0,0 +1,288 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests less common mouse/keyboard manipulations of the address bar input + * field selection, for example: + * - Home/Del + * - Shift+Right/Left + * - Drag selection + * - Double-click on word + * + * All the tests set up some initial conditions, and check it. Then optionally + * they can manipulate the selection further, and check the results again. + * We want to ensure the final selection is the expected one, even if in the + * future we change our trimming strategy for the input field value. + */ + +const tests = [ + { + description: "Test HOME starting from full selection", + openPanel() { + EventUtils.synthesizeKey("l", { accelKey: true }); + }, + get selection() { + return [0, gURLBar.value.length]; + }, + manipulate() { + // Cursor must move to the first visible character, regardless of any + // "untrimming" we could be doing. + this._visibleValue = gURLBar.value; + if (AppConstants.platform == "macosx") { + EventUtils.synthesizeKey("KEY_ArrowLeft", { metaKey: true }); + } else { + EventUtils.synthesizeKey("KEY_Home"); + } + }, + get modifiedSelection() { + let start = gURLBar.value.indexOf(this._visibleValue); + return [start, start]; + }, + }, + { + description: "Test END starting from full selection", + openPanel() { + EventUtils.synthesizeKey("l", { accelKey: true }); + }, + get selection() { + return [0, gURLBar.value.length]; + }, + manipulate() { + if (AppConstants.platform == "macosx") { + EventUtils.synthesizeKey("KEY_ArrowRight", { metaKey: true }); + } else { + EventUtils.synthesizeKey("KEY_End", {}); + } + }, + get modifiedSelection() { + return [gURLBar.value.length, gURLBar.value.length]; + }, + }, + { + description: "Test SHIFT+LEFT starting from full selection", + openPanel() { + EventUtils.synthesizeKey("l", { accelKey: true }); + }, + get selection() { + return [0, gURLBar.value.length]; + }, + manipulate() { + EventUtils.synthesizeKey("KEY_ArrowLeft", { shiftKey: true }); + }, + get modifiedSelection() { + return [0, gURLBar.value.length - 1]; + }, + }, + { + description: "Test SHIFT+RIGHT starting from full selection", + openPanel() { + EventUtils.synthesizeKey("l", { accelKey: true }); + }, + get selection() { + return [0, gURLBar.value.length]; + }, + manipulate() { + EventUtils.synthesizeKey("KEY_ArrowRight", { shiftKey: true }); + }, + get modifiedSelection() { + return [0, gURLBar.value.length]; + }, + }, + { + description: "Test Drag Selection from the first character", + async openPanel() { + this._expectedSelectedText = gURLBar.value.substring(0, 5); + await selectWithMouseDrag( + getTextWidth(gURLBar.value[0]) / 2 - 1, + getTextWidth(gURLBar.value.substring(0, 5)) + ); + }, + get selection() { + return [ + 0, + gURLBar.value.indexOf(this._expectedSelectedText) + + this._expectedSelectedText.length, + ]; + }, + }, + { + description: "Test Drag Selection from the last character", + async openPanel() { + this._expectedSelectedText = gURLBar.value.substring(-5); + await selectWithMouseDrag( + getTextWidth(gURLBar.value) + 1, + getTextWidth(this._expectedSelectedText) + ); + }, + get selection() { + return [ + gURLBar.value.indexOf(this._expectedSelectedText), + gURLBar.value.length, + ]; + }, + }, + { + description: "Test Drag Selection in the middle of the string", + async openPanel() { + this._expectedSelectedText = gURLBar.value.substring(5, 10); + await selectWithMouseDrag( + getTextWidth(gURLBar.value.substring(0, 5)), + getTextWidth(gURLBar.value.substring(0, 10)) + ); + }, + get selection() { + let start = gURLBar.value.indexOf(this._expectedSelectedText); + return [start, start + this._expectedSelectedText.length]; + }, + }, + { + description: "Test Double-click on word", + async openPanel() { + let wordBoundaryIndex = gURLBar.value.search(/\btest/); + this._expectedSelectedText = "test"; + await selectWithDoubleClick( + getTextWidth(gURLBar.value.substring(0, wordBoundaryIndex)) + ); + }, + get selection() { + let start = gURLBar.value.indexOf(this._expectedSelectedText); + return [start, start + this._expectedSelectedText.length]; + }, + }, + { + description: "Click at the right of the text", + openPanel() { + EventUtils.synthesizeKey("l", { accelKey: true }); + }, + get selection() { + return [0, gURLBar.value.length]; + }, + manipulate() { + let rect = gURLBar.inputField.getBoundingClientRect(); + EventUtils.synthesizeMouse( + gURLBar.inputField, + getTextWidth(gURLBar.value) + 10, + rect.height / 2, + {} + ); + }, + get modifiedSelection() { + return [gURLBar.value.length, gURLBar.value.length]; + }, + }, +]; + +add_setup(async function () { + gURLBar.inputField.style.font = "14px monospace"; + registerCleanupFunction(() => { + gURLBar.inputField.style.font = null; + }); +}); + +add_task(async function https() { + await doTest("https://example.com/test/some/page.htm"); +}); + +add_task(async function http() { + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + await doTest("http://example.com/test/other/page.htm"); +}); + +async function doTest(url) { + await BrowserTestUtils.withNewTab(url, async () => { + for (let test of tests) { + gURLBar.blur(); + info(test.description); + await UrlbarTestUtils.promisePopupOpen(window, async () => { + await test.openPanel(); + }); + info( + `Selected text is <${gURLBar.value.substring( + gURLBar.selectionStart, + gURLBar.selectionEnd + )}>` + ); + Assert.deepEqual( + test.selection, + [gURLBar.selectionStart, gURLBar.selectionEnd], + "Check selection" + ); + + if (test.manipulate) { + await test.manipulate(); + info( + `Selected text is <${gURLBar.value.substring( + gURLBar.selectionStart, + gURLBar.selectionEnd + )}>` + ); + Assert.deepEqual( + test.modifiedSelection, + [gURLBar.selectionStart, gURLBar.selectionEnd], + "Check selection after manipulation" + ); + } + } + }); +} + +function getTextWidth(inputText) { + const canvas = + getTextWidth.canvas || + (getTextWidth.canvas = document.createElement("canvas")); + let context = canvas.getContext("2d"); + context.font = window + .getComputedStyle(gURLBar.inputField) + .getPropertyValue("font"); + return context.measureText(inputText).width; +} + +function selectWithMouseDrag(fromX, toX) { + let target = gURLBar.inputField; + let rect = target.getBoundingClientRect(); + let promise = BrowserTestUtils.waitForEvent(target, "mouseup"); + EventUtils.synthesizeMouse( + target, + fromX, + rect.height / 2, + { type: "mousemove" }, + target.ownerGlobal + ); + EventUtils.synthesizeMouse( + target, + fromX, + rect.height / 2, + { type: "mousedown" }, + target.ownerGlobal + ); + EventUtils.synthesizeMouse( + target, + toX, + rect.height / 2, + { type: "mousemove" }, + target.ownerGlobal + ); + EventUtils.synthesizeMouse( + target, + toX, + rect.height / 2, + { type: "mouseup" }, + target.ownerGlobal + ); + return promise; +} + +function selectWithDoubleClick(offsetX) { + let target = gURLBar.inputField; + let rect = target.getBoundingClientRect(); + let promise = BrowserTestUtils.waitForEvent(target, "dblclick"); + EventUtils.synthesizeMouse(target, offsetX, rect.height / 2, { + clickCount: 1, + }); + EventUtils.synthesizeMouse(target, offsetX, rect.height / 2, { + clickCount: 2, + }); + return promise; +} diff --git a/browser/components/urlbar/tests/browser/browser_locationBarCommand.js b/browser/components/urlbar/tests/browser/browser_locationBarCommand.js index 84c45e586a..92409f979f 100644 --- a/browser/components/urlbar/tests/browser/browser_locationBarCommand.js +++ b/browser/components/urlbar/tests/browser/browser_locationBarCommand.js @@ -276,7 +276,7 @@ async function typeAndCommand(eventType, details = {}) { async function triggerCommand(eventType, details = {}) { Assert.equal( await UrlbarTestUtils.promiseUserContextId(window), - gBrowser.selectedTab.getAttribute("usercontextid"), + gBrowser.selectedTab.getAttribute("usercontextid") || "", "userContextId must be the same as the originating tab" ); diff --git a/browser/components/urlbar/tests/browser/browser_primary_selection_safe_on_new_tab.js b/browser/components/urlbar/tests/browser/browser_primary_selection_safe_on_new_tab.js index 2f8e871bfe..66a8ed3a41 100644 --- a/browser/components/urlbar/tests/browser/browser_primary_selection_safe_on_new_tab.js +++ b/browser/components/urlbar/tests/browser/browser_primary_selection_safe_on_new_tab.js @@ -42,7 +42,7 @@ add_task(async function () { // tab button. let userInput = window.windowUtils.setHandlingUserInput(true); try { - BrowserOpenTab(); + BrowserCommands.openTab(); } finally { userInput.destruct(); } diff --git a/browser/components/urlbar/tests/browser/browser_raceWithTabs.js b/browser/components/urlbar/tests/browser/browser_raceWithTabs.js index 17560ea101..821aa0f0ee 100644 --- a/browser/components/urlbar/tests/browser/browser_raceWithTabs.js +++ b/browser/components/urlbar/tests/browser/browser_raceWithTabs.js @@ -41,7 +41,7 @@ add_task(async function hitEnterLoadInRightTab() { gBrowser.tabContainer, "TabOpen" ); - BrowserOpenTab(); + BrowserCommands.openTab(); let oldTab = (await oldTabOpenPromise).target; let oldTabLoadedPromise = BrowserTestUtils.browserLoaded( oldTab.linkedBrowser, @@ -60,7 +60,7 @@ add_task(async function hitEnterLoadInRightTab() { EventUtils.sendKey("return"); info("Immediately open a second tab"); - BrowserOpenTab(); + BrowserCommands.openTab(); let newTab = (await tabOpenPromise).target; info("Created new tab; waiting for tabs to load"); diff --git a/browser/components/urlbar/tests/browser/browser_result_menu.js b/browser/components/urlbar/tests/browser/browser_result_menu.js index ccbe247598..f00b92fa63 100644 --- a/browser/components/urlbar/tests/browser/browser_result_menu.js +++ b/browser/components/urlbar/tests/browser/browser_result_menu.js @@ -201,10 +201,10 @@ add_task(async function firefoxSuggest() { ], }); - // Implement the provider's `onEngagement()` so it removes the result. - let onEngagementCallCount = 0; - provider.onEngagement = (state, queryContext, details, controller) => { - onEngagementCallCount++; + // Implement the provider's `onLegacyEngagement()` so it removes the result. + let onLegacyEngagementCallCount = 0; + provider.onLegacyEngagement = (state, queryContext, details, controller) => { + onLegacyEngagementCallCount++; controller.removeResult(details.result); }; @@ -245,9 +245,9 @@ add_task(async function firefoxSuggest() { }); Assert.greater( - onEngagementCallCount, + onLegacyEngagementCallCount, 0, - "onEngagement() should have been called" + "onLegacyEngagement() should have been called" ); Assert.equal( UrlbarTestUtils.getResultCount(window), diff --git a/browser/components/urlbar/tests/browser/browser_stop_pending.js b/browser/components/urlbar/tests/browser/browser_stop_pending.js index 50f5dfdeec..938a57dc28 100644 --- a/browser/components/urlbar/tests/browser/browser_stop_pending.js +++ b/browser/components/urlbar/tests/browser/browser_stop_pending.js @@ -125,7 +125,7 @@ add_task(async function () { null, true ); - BrowserStop(); + BrowserCommands.stop(); await browserStoppedPromise; is( @@ -207,7 +207,7 @@ add_task(async function () { null, true ); - BrowserStop(); + BrowserCommands.stop(); await browserStoppedPromise; is( diff --git a/browser/components/urlbar/tests/browser/browser_urlbar_telemetry_tabtosearch.js b/browser/components/urlbar/tests/browser/browser_urlbar_telemetry_tabtosearch.js index 318b29ad19..b2591a0c14 100644 --- a/browser/components/urlbar/tests/browser/browser_urlbar_telemetry_tabtosearch.js +++ b/browser/components/urlbar/tests/browser/browser_urlbar_telemetry_tabtosearch.js @@ -344,8 +344,8 @@ async function impressions_test(isOnboarding) { 5 ); - // See javadoc for UrlbarProviderTabToSearch.onEngagement for discussion - // about retained results. + // See javadoc for UrlbarProviderTabToSearch.onLegacyEngagement for + // discussion about retained results. info("Reopen the result set with retained results. Record impression."); await UrlbarTestUtils.promisePopupOpen(window, () => { EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {}); diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser.toml b/browser/components/urlbar/tests/engagementTelemetry/browser/browser.toml index cf6bc80318..a72f2d9b8d 100644 --- a/browser/components/urlbar/tests/engagementTelemetry/browser/browser.toml +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser.toml @@ -26,8 +26,6 @@ prefs = ["browser.bookmarks.testing.skipDefaultBookmarksImport=true"] ["browser_glean_telemetry_abandonment_n_chars_n_words.js"] -["browser_glean_telemetry_abandonment_type.js"] - ["browser_glean_telemetry_abandonment_sap.js"] ["browser_glean_telemetry_abandonment_search_engine_default_id.js"] @@ -36,6 +34,8 @@ prefs = ["browser.bookmarks.testing.skipDefaultBookmarksImport=true"] ["browser_glean_telemetry_abandonment_tips.js"] +["browser_glean_telemetry_abandonment_type.js"] + ["browser_glean_telemetry_engagement_edge_cases.js"] ["browser_glean_telemetry_engagement_groups.js"] @@ -66,4 +66,8 @@ skip-if = ["verify"] # Bug 1852375 - MerinoTestUtils.initWeather() doesn't play ["browser_glean_telemetry_exposure_edge_cases.js"] +["browser_glean_telemetry_potential_exposure.js"] + ["browser_glean_telemetry_record_preferences.js"] + +["browser_glean_telemetry_reenter.js"] diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_abandonment_type.js b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_abandonment_type.js index 99145d7cc3..b8a16bd10c 100644 --- a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_abandonment_type.js +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_abandonment_type.js @@ -19,7 +19,7 @@ function checkUrlbarFocus(win, focusState) { // URL bar records the correct abandonment telemetry with abandonment type // "tab_swtich". add_task(async function tabSwitchFocusedToFocused() { - await doTest(async browser => { + await doTest(async () => { await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "test search", @@ -45,7 +45,7 @@ add_task(async function tabSwitchFocusedToFocused() { // URL bar loses focus logs abandonment telemetry with abandonment type // "blur". add_task(async function tabSwitchFocusedToUnfocused() { - await doTest(async browser => { + await doTest(async () => { await UrlbarTestUtils.promiseAutocompleteResultPopup({ window, value: "test search", @@ -65,7 +65,7 @@ add_task(async function tabSwitchFocusedToUnfocused() { // the URL bar gains focus does not record any abandonment telemetry, reflecting // no change in focus state relevant to abandonment. add_task(async function tabSwitchUnFocusedToFocused() { - await doTest(async browser => { + await doTest(async () => { checkUrlbarFocus(window, false); let promiseTabOpened = BrowserTestUtils.waitForEvent( @@ -91,7 +91,7 @@ add_task(async function tabSwitchUnFocusedToFocused() { // Checks that switching between two tabs, both with unfocused URL bars, does // not trigger any abandonment telmetry. add_task(async function tabSwitchUnFocusedToUnFocused() { - await doTest(async browser => { + await doTest(async () => { checkUrlbarFocus(window, false); let tab2 = await BrowserTestUtils.openNewForegroundTab(window.gBrowser); diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_tips.js b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_tips.js index ff31bdc52a..053d307088 100644 --- a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_tips.js +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_tips.js @@ -63,7 +63,7 @@ add_task(async function selected_result_tip() { ), ], priority: 1, - onEngagement: () => { + onLegacyEngagement: () => { deferred.resolve(); }, }); diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_type.js b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_type.js index 6b1dedbce2..59c4460e52 100644 --- a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_type.js +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_engagement_type.js @@ -101,11 +101,32 @@ add_task(async function engagement_type_dismiss() { }); add_task(async function engagement_type_help() { - const cleanupQuickSuggest = await ensureQuickSuggestInit(); + const url = "https://example.com/"; + const helpUrl = "https://example.com/help"; + let provider = new UrlbarTestUtils.TestProvider({ + priority: Infinity, + results: [ + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, + { + url, + isBlockable: true, + blockL10n: { id: "urlbar-result-menu-dismiss-firefox-suggest" }, + helpUrl, + helpL10n: { + id: "urlbar-result-menu-learn-more-about-firefox-suggest", + }, + } + ), + ], + }); + UrlbarProvidersManager.registerProvider(provider); await doTest(async () => { - await openPopup("sponsored"); - await selectRowByURL("https://example.com/sponsored"); + await openPopup("test"); + await selectRowByURL(url); + const onTabOpened = BrowserTestUtils.waitForNewTab(gBrowser); UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "L"); const tab = await onTabOpened; @@ -114,5 +135,26 @@ add_task(async function engagement_type_help() { assertEngagementTelemetry([{ engagement_type: "help" }]); }); + UrlbarProvidersManager.unregisterProvider(provider); +}); + +add_task(async function engagement_type_manage() { + const cleanupQuickSuggest = await ensureQuickSuggestInit(); + + await doTest(async () => { + await openPopup("sponsored"); + await selectRowByURL("https://example.com/sponsored"); + + const onManagePageLoaded = BrowserTestUtils.browserLoaded( + browser, + false, + "about:preferences#search" + ); + UrlbarTestUtils.openResultMenuAndPressAccesskey(window, "M"); + await onManagePageLoaded; + + assertEngagementTelemetry([{ engagement_type: "manage" }]); + }); + await cleanupQuickSuggest(); }); diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure.js b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure.js index 07e8b9b360..ef2ec623bc 100644 --- a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure.js +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure.js @@ -11,7 +11,7 @@ add_setup(async function () { await initExposureTest(); }); -add_task(async function exposureSponsoredOnEngagement() { +add_task(async function exposureSponsoredOnLegacyEngagement() { await doExposureTest({ prefs: [ ["browser.urlbar.exposureResults", suggestResultType("adm_sponsored")], diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_potential_exposure.js b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_potential_exposure.js new file mode 100644 index 0000000000..275e3968eb --- /dev/null +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_potential_exposure.js @@ -0,0 +1,438 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Tests the `urlbar-potential-exposure` ping. + +const WAIT_FOR_PING_TIMEOUT_MS = 1000; + +// Avoid timeouts in verify mode, especially on Mac. +requestLongerTimeout(3); + +add_setup(async function test_setup() { + Services.fog.testResetFOG(); + + // Add a mock engine so we don't hit the network. + await SearchTestUtils.installSearchExtension({}, { setAsDefault: true }); + + registerCleanupFunction(() => { + Services.fog.testResetFOG(); + }); +}); + +add_task(async function oneKeyword_noMatch_1() { + await doTest({ + keywords: ["example"], + searchStrings: ["exam"], + expectedEvents: [], + }); +}); + +add_task(async function oneKeyword_noMatch_2() { + await doTest({ + keywords: ["exam"], + searchStrings: ["example"], + expectedEvents: [], + }); +}); + +add_task(async function oneKeyword_oneMatch_terminal_1() { + await doTest({ + keywords: ["example"], + searchStrings: ["example"], + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); +}); + +add_task(async function oneKeyword_oneMatch_terminal_2() { + await doTest({ + keywords: ["example"], + searchStrings: ["exam", "example"], + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); +}); + +add_task(async function oneKeyword_oneMatch_nonterminal_1() { + await doTest({ + keywords: ["example"], + searchStrings: ["example", "exam"], + expectedEvents: [{ extra: { keyword: "example", terminal: false } }], + }); +}); + +add_task(async function oneKeyword_oneMatch_nonterminal_2() { + await doTest({ + keywords: ["example"], + searchStrings: ["ex", "example", "exam"], + expectedEvents: [{ extra: { keyword: "example", terminal: false } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_terminal_1() { + await doTest({ + keywords: ["example"], + searchStrings: ["example", "example"], + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_terminal_2() { + await doTest({ + keywords: ["example"], + searchStrings: ["example", "exampl", "example"], + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_terminal_3() { + await doTest({ + keywords: ["example"], + searchStrings: ["exam", "example", "example"], + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_terminal_4() { + await doTest({ + keywords: ["example"], + searchStrings: ["exam", "example", "exampl", "example"], + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_nonterminal_1() { + await doTest({ + keywords: ["example"], + searchStrings: ["example", "example", "exampl"], + expectedEvents: [{ extra: { keyword: "example", terminal: false } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_nonterminal_2() { + await doTest({ + keywords: ["example"], + searchStrings: ["exam", "example", "example", "exampl"], + expectedEvents: [{ extra: { keyword: "example", terminal: false } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_nonterminal_3() { + await doTest({ + keywords: ["example"], + searchStrings: ["example", "exam", "example", "exampl"], + expectedEvents: [{ extra: { keyword: "example", terminal: false } }], + }); +}); + +add_task(async function oneKeyword_dupeMatches_nonterminal_4() { + await doTest({ + keywords: ["example"], + searchStrings: ["exam", "example", "exampl", "example", "exampl"], + expectedEvents: [{ extra: { keyword: "example", terminal: false } }], + }); +}); + +add_task(async function manyKeywords_noMatch() { + await doTest({ + keywords: ["foo", "bar", "baz"], + searchStrings: ["example"], + expectedEvents: [], + }); +}); + +add_task(async function manyKeywords_oneMatch_terminal_1() { + await doTest({ + keywords: ["foo", "bar", "baz"], + searchStrings: ["bar"], + expectedEvents: [{ extra: { keyword: "bar", terminal: true } }], + }); +}); + +add_task(async function manyKeywords_oneMatch_terminal_2() { + await doTest({ + keywords: ["foo", "bar", "baz"], + searchStrings: ["example", "bar"], + expectedEvents: [{ extra: { keyword: "bar", terminal: true } }], + }); +}); + +add_task(async function manyKeywords_oneMatch_nonterminal_1() { + await doTest({ + keywords: ["foo", "bar", "baz"], + searchStrings: ["bar", "example"], + expectedEvents: [{ extra: { keyword: "bar", terminal: false } }], + }); +}); + +add_task(async function manyKeywords_oneMatch_nonterminal_2() { + await doTest({ + keywords: ["foo", "bar", "baz"], + searchStrings: ["exam", "bar", "example"], + expectedEvents: [{ extra: { keyword: "bar", terminal: false } }], + }); +}); + +add_task(async function manyKeywords_manyMatches_terminal_1() { + let keywords = ["foo", "bar", "baz"]; + await doTest({ + keywords, + searchStrings: keywords, + expectedEvents: keywords.map((keyword, i) => ({ + extra: { keyword, terminal: i == keywords.length - 1 }, + })), + }); +}); + +add_task(async function manyKeywords_manyMatches_terminal_2() { + let keywords = ["foo", "bar", "baz"]; + await doTest({ + keywords, + searchStrings: ["exam", "foo", "exampl", "bar", "example", "baz"], + expectedEvents: keywords.map((keyword, i) => ({ + extra: { keyword, terminal: i == keywords.length - 1 }, + })), + }); +}); + +add_task(async function manyKeywords_manyMatches_nonterminal_1() { + let keywords = ["foo", "bar", "baz"]; + await doTest({ + keywords, + searchStrings: ["foo", "bar", "baz", "example"], + expectedEvents: keywords.map(keyword => ({ + extra: { keyword, terminal: false }, + })), + }); +}); + +add_task(async function manyKeywords_manyMatches_nonterminal_2() { + let keywords = ["foo", "bar", "baz"]; + await doTest({ + keywords, + searchStrings: ["exam", "foo", "exampl", "bar", "example", "baz", "exam"], + expectedEvents: keywords.map(keyword => ({ + extra: { keyword, terminal: false }, + })), + }); +}); + +add_task(async function manyKeywords_dupeMatches_terminal() { + let keywords = ["foo", "bar", "baz"]; + let searchStrings = [...keywords, ...keywords]; + await doTest({ + keywords, + searchStrings, + expectedEvents: keywords.map((keyword, i) => ({ + extra: { keyword, terminal: i == keywords.length - 1 }, + })), + }); +}); + +add_task(async function manyKeywords_dupeMatches_nonterminal() { + let keywords = ["foo", "bar", "baz"]; + let searchStrings = [...keywords, ...keywords, "example"]; + await doTest({ + keywords, + searchStrings, + expectedEvents: keywords.map(keyword => ({ + extra: { keyword, terminal: false }, + })), + }); +}); + +add_task(async function searchStringNormalization_terminal() { + await doTest({ + keywords: ["example"], + searchStrings: [" ExaMPLe "], + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); +}); + +add_task(async function searchStringNormalization_nonterminal() { + await doTest({ + keywords: ["example"], + searchStrings: [" ExaMPLe ", "foo"], + expectedEvents: [{ extra: { keyword: "example", terminal: false } }], + }); +}); + +add_task(async function multiWordKeyword() { + await doTest({ + keywords: ["this has multiple words"], + searchStrings: ["this has multiple words"], + expectedEvents: [ + { extra: { keyword: "this has multiple words", terminal: true } }, + ], + }); +}); + +// Smoke test that ends a session with an engagement instead of an abandonment +// as other tasks in this file do. +add_task(async function engagement() { + await BrowserTestUtils.withNewTab("about:blank", async () => { + await doTest({ + keywords: ["example"], + searchStrings: ["example"], + endSession: () => + // Hit the Enter key on the heuristic search result. + UrlbarTestUtils.promisePopupClose(window, () => + EventUtils.synthesizeKey("KEY_Enter") + ), + expectedEvents: [{ extra: { keyword: "example", terminal: true } }], + }); + }); +}); + +// Smoke test that uses Nimbus to set keywords instead of a pref as other tasks +// in this file do. +add_task(async function nimbus() { + let keywords = ["foo", "bar", "baz"]; + await doTest({ + useNimbus: true, + keywords, + searchStrings: keywords, + expectedEvents: keywords.map((keyword, i) => ({ + extra: { keyword, terminal: i == keywords.length - 1 }, + })), + }); +}); + +// The ping should not be submitted for sessions in private windows. +add_task(async function privateWindow() { + let privateWin = await BrowserTestUtils.openNewBrowserWindow({ + private: true, + }); + await doTest({ + win: privateWin, + keywords: ["example"], + searchStrings: ["example"], + expectedEvents: [], + }); + await BrowserTestUtils.closeWindow(privateWin); +}); + +add_task(async function invalidPotentialExposureKeywords_pref() { + await doTest({ + keywords: "not an array of keywords", + searchStrings: ["example", "not an array of keywords"], + expectedEvents: [], + }); +}); + +add_task(async function invalidPotentialExposureKeywords_nimbus() { + await doTest({ + useNimbus: true, + keywords: "not an array of keywords", + searchStrings: ["example", "not an array of keywords"], + expectedEvents: [], + }); +}); + +async function doTest({ + keywords, + searchStrings, + expectedEvents, + endSession = null, + useNimbus = false, + win = window, +}) { + endSession ||= () => + UrlbarTestUtils.promisePopupClose(win, () => win.gURLBar.blur()); + + let nimbusCleanup; + let keywordsJson = JSON.stringify(keywords); + if (useNimbus) { + nimbusCleanup = await UrlbarTestUtils.initNimbusFeature({ + potentialExposureKeywords: keywordsJson, + }); + } else { + await SpecialPowers.pushPrefEnv({ + set: [["browser.urlbar.potentialExposureKeywords", keywordsJson]], + }); + } + + let pingPromise = waitForPing(); + + for (let value of searchStrings) { + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + value, + window: win, + }); + } + await endSession(); + + // Wait `WAIT_FOR_PING_TIMEOUT_MS` for the ping to be submitted before + // reporting a timeout. Note that some tasks do not expect a ping to be + // submitted, and they rely on this timeout behavior. + info("Awaiting ping promise"); + let events = null; + events = await Promise.race([ + pingPromise, + new Promise(resolve => + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(() => { + if (!events) { + info("Timed out waiting for ping"); + } + resolve([]); + }, WAIT_FOR_PING_TIMEOUT_MS) + ), + ]); + + assertEvents(events, expectedEvents); + + if (nimbusCleanup) { + await nimbusCleanup(); + } else { + await SpecialPowers.popPrefEnv(); + } + Services.fog.testResetFOG(); +} + +function waitForPing() { + return new Promise(resolve => { + GleanPings.urlbarPotentialExposure.testBeforeNextSubmit(() => { + let events = Glean.urlbar.potentialExposure.testGetValue(); + info("testBeforeNextSubmit got events: " + JSON.stringify(events)); + resolve(events); + }); + }); +} + +function assertEvents(actual, expected) { + info("Comparing events: " + JSON.stringify({ actual, expected })); + + // Add some expected boilerplate properties to the expected events so that + // callers don't have to but so that we still check them. + expected = expected.map(e => ({ + category: "urlbar", + name: "potential_exposure", + // `testGetValue()` stringifies booleans for some reason. Let callers + // specify booleans since booleans are correct, and stringify them here. + ...stringifyBooleans(e), + })); + + // Filter out properties from the actual events that aren't defined in the + // expected events. Ignore unimportant properties like timestamps. + actual = actual.map((a, i) => + Object.fromEntries( + Object.entries(a).filter(([key]) => expected[i]?.hasOwnProperty(key)) + ) + ); + + Assert.deepEqual(actual, expected, "Checking expected Glean events"); +} + +function stringifyBooleans(obj) { + let newObj = {}; + for (let [key, value] of Object.entries(obj)) { + if (value && typeof value == "object") { + newObj[key] = stringifyBooleans(value); + } else if (typeof value == "boolean") { + newObj[key] = String(value); + } else { + newObj[key] = value; + } + } + return newObj; +} diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_reenter.js b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_reenter.js new file mode 100644 index 0000000000..51bdc84870 --- /dev/null +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_reenter.js @@ -0,0 +1,79 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test we don't re-enter record() (and record both an engagement and an +// abandonment) when handling an engagement blurs the input field. + +const TEST_URL = "https://example.com/"; + +add_task(async function () { + await setup(); + let deferred = Promise.withResolvers(); + const provider = new UrlbarTestUtils.TestProvider({ + results: [ + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, + { + url: TEST_URL, + helpUrl: "https://example.com/help", + helpL10n: { + id: "urlbar-result-menu-tip-get-help", + }, + } + ), + ], + priority: 999, + onLegacyEngagement: () => { + info("Blur the address bar during the onLegacyEngagement notification"); + gURLBar.blur(); + // Run at the next tick to be sure spurious events would have happened. + TestUtils.waitForTick().then(() => { + deferred.resolve(); + }); + }, + }); + UrlbarProvidersManager.registerProvider(provider); + // This should cover at least engagement and abandonment. + let engagementSpy = sinon.spy(provider, "onLegacyEngagement"); + + let beforeRecordCall = false, + recordReentered = false; + let recordStub = sinon + .stub(gURLBar.controller.engagementEvent, "record") + .callsFake((...args) => { + recordReentered = beforeRecordCall; + beforeRecordCall = true; + recordStub.wrappedMethod.apply(gURLBar.controller.engagementEvent, args); + beforeRecordCall = false; + }); + + registerCleanupFunction(() => { + sinon.restore(); + UrlbarProvidersManager.unregisterProvider(provider); + }); + + await doTest(async () => { + await openPopup("example"); + await selectRowByURL(TEST_URL); + EventUtils.synthesizeKey("VK_RETURN"); + await deferred.promise; + + assertEngagementTelemetry([{ engagement_type: "enter" }]); + assertAbandonmentTelemetry([]); + + Assert.ok(recordReentered, "`record()` was re-entered"); + Assert.equal( + engagementSpy.callCount, + 1, + "`onLegacyEngagement` was invoked twice" + ); + Assert.equal( + engagementSpy.args[0][0], + "engagement", + "`engagement` notified" + ); + }); +}); diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/head.js b/browser/components/urlbar/tests/engagementTelemetry/browser/head.js index 4317a50930..1373cc7e27 100644 --- a/browser/components/urlbar/tests/engagementTelemetry/browser/head.js +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/head.js @@ -10,6 +10,7 @@ Services.scriptloader.loadSubScript( ChromeUtils.defineESModuleGetters(this, { QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs", + sinon: "resource://testing-common/Sinon.sys.mjs", }); const lazy = {}; @@ -210,12 +211,7 @@ async function doTest(testFn) { await QuickSuggest.blockedSuggestions.clear(); await QuickSuggest.blockedSuggestions._test_readyPromise; await updateTopSites(() => true); - - try { - await BrowserTestUtils.withNewTab(gBrowser, testFn); - } catch (e) { - console.error(e); - } + await BrowserTestUtils.withNewTab(gBrowser, testFn); } async function initGroupTest() { diff --git a/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs b/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs index 2ba9dce8be..1002b4e231 100644 --- a/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs +++ b/browser/components/urlbar/tests/quicksuggest/QuickSuggestTestUtils.sys.mjs @@ -490,6 +490,8 @@ class _QuickSuggestTestUtils { * Whether the result is expected to be sponsored. * @param {boolean} [options.isBestMatch] * Whether the result is expected to be a best match. + * @param {boolean} [options.isManageable] + * Whether the result is expected to show Manage result menu item. * @returns {result} * The quick suggest result. */ @@ -500,6 +502,7 @@ class _QuickSuggestTestUtils { index = -1, isSponsored = true, isBestMatch = false, + isManageable = true, } = {}) { this.Assert.ok( url || originalUrl, @@ -574,11 +577,19 @@ class _QuickSuggestTestUtils { } this.Assert.equal( - result.payload.helpUrl, - lazy.QuickSuggest.HELP_URL, - "Result helpURL" + result.payload.isManageable, + isManageable, + "Result isManageable" ); + if (!isManageable) { + this.Assert.equal( + result.payload.helpUrl, + lazy.QuickSuggest.HELP_URL, + "Result helpURL" + ); + } + this.Assert.ok( row._buttons.get("menu"), "The menu button should be present" diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest.js index 130afe8c53..98f6ba6117 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest.js @@ -164,3 +164,40 @@ add_tasks_with_rust( await cleanUpNimbus(); } ); + +// Tests the "Manage" result menu for sponsored suggestion. +add_tasks_with_rust(async function resultMenu_manage_sponsored() { + await BrowserTestUtils.withNewTab({ gBrowser }, async browser => { + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "fra", + }); + + const managePage = "about:preferences#search"; + let onManagePageLoaded = BrowserTestUtils.browserLoaded( + browser, + false, + managePage + ); + // Click the command. + await UrlbarTestUtils.openResultMenuAndClickItem(window, "manage", { + resultIndex: 1, + }); + await onManagePageLoaded; + Assert.equal( + browser.currentURI.spec, + managePage, + "The manage page is loaded" + ); + + await UrlbarTestUtils.promisePopupClose(window); + }); +}); + +// Tests the "Manage" result menu for non-sponsored suggestion. +add_tasks_with_rust(async function resultMenu_manage_nonSponsored() { + await doManageTest({ + input: "nonspon", + index: 1, + }); +}); diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_addons.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_addons.js index b09345aa54..f34b479134 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_addons.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_addons.js @@ -245,10 +245,15 @@ add_task(async function resultMenu_notInterested() { }); // Tests the "Not relevant" result menu dismissal command. -add_task(async function notRelevant() { +add_task(async function resultMenu_notRelevant() { await doDismissTest("not_relevant", false); }); +// Tests the "Manage" result menu. +add_task(async function resultMenu_manage() { + await doManageTest({ input: "only match the Merino suggestion", index: 1 }); +}); + // Tests the row/group label. add_task(async function rowLabel() { await UrlbarTestUtils.promiseAutocompleteResultPopup({ diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_block.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_block.js index c400cf72f6..3fa91e5a32 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_block.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_block.js @@ -5,11 +5,6 @@ "use strict"; -ChromeUtils.defineESModuleGetters(this, { - CONTEXTUAL_SERVICES_PING_TYPES: - "resource:///modules/PartnerLinkAttribution.sys.mjs", -}); - const { TELEMETRY_SCALARS } = UrlbarProviderQuickSuggest; const { TIMESTAMP_TEMPLATE } = QuickSuggest; diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_mdn.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_mdn.js index b7da7533c4..33bd37703d 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_mdn.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_mdn.js @@ -21,6 +21,9 @@ const REMOTE_SETTINGS_DATA = [ }, ]; +// Avoid timeouts in verify mode. They're especially common on Mac. +requestLongerTimeout(5); + add_setup(async function () { await QuickSuggestTestUtils.ensureQuickSuggestInit({ remoteSettingsRecords: REMOTE_SETTINGS_DATA, @@ -28,35 +31,37 @@ add_setup(async function () { }); add_tasks_with_rust(async function basic() { - const suggestion = REMOTE_SETTINGS_DATA[0].attachment[0]; - await UrlbarTestUtils.promiseAutocompleteResultPopup({ - window, - value: suggestion.keywords[0], - }); - Assert.equal(UrlbarTestUtils.getResultCount(window), 2); - - const { element, result } = await UrlbarTestUtils.getDetailsOfResultAt( - window, - 1 - ); - Assert.equal( - result.providerName, - UrlbarProviderQuickSuggest.name, - "The result should be from the expected provider" - ); - Assert.equal( - result.payload.provider, - UrlbarPrefs.get("quickSuggestRustEnabled") ? "Mdn" : "MDNSuggestions" - ); + await BrowserTestUtils.withNewTab("about:blank", async () => { + const suggestion = REMOTE_SETTINGS_DATA[0].attachment[0]; + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: suggestion.keywords[0], + }); + Assert.equal(UrlbarTestUtils.getResultCount(window), 2); + + const { element, result } = await UrlbarTestUtils.getDetailsOfResultAt( + window, + 1 + ); + Assert.equal( + result.providerName, + UrlbarProviderQuickSuggest.name, + "The result should be from the expected provider" + ); + Assert.equal( + result.payload.provider, + UrlbarPrefs.get("quickSuggestRustEnabled") ? "Mdn" : "MDNSuggestions" + ); - const onLoad = BrowserTestUtils.browserLoaded( - gBrowser.selectedBrowser, - false, - result.payload.url - ); - EventUtils.synthesizeMouseAtCenter(element.row, {}); - await onLoad; - Assert.ok(true, "Expected page is loaded"); + const onLoad = BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + false, + result.payload.url + ); + EventUtils.synthesizeMouseAtCenter(element.row, {}); + await onLoad; + Assert.ok(true, "Expected page is loaded"); + }); await PlacesUtils.history.clear(); }); @@ -111,7 +116,7 @@ add_tasks_with_rust(async function resultMenu_notInterested() { }); // Tests the "Not relevant" result menu dismissal command. -add_tasks_with_rust(async function notRelevant() { +add_tasks_with_rust(async function resultMenu_notRelevant() { await doDismissTest("not_relevant"); Assert.equal(UrlbarPrefs.get("suggest.mdn"), true); @@ -123,6 +128,11 @@ add_tasks_with_rust(async function notRelevant() { await QuickSuggest.blockedSuggestions.clear(); }); +// Tests the "Manage" result menu. +add_tasks_with_rust(async function resultMenu_manage() { + await doManageTest({ input: "array", index: 1 }); +}); + async function doDismissTest(command) { const keyword = REMOTE_SETTINGS_DATA[0].attachment[0].keywords[0]; // Do a search. diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_pocket.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_pocket.js index 0064b6a297..a40a35893b 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_pocket.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_pocket.js @@ -4,12 +4,6 @@ "use strict"; // Browser tests for Pocket suggestions. -// -// TODO: Make this work with Rust enabled. Right now, running this test with -// Rust hits the following error on ingest, which prevents ingest from finishing -// successfully: -// -// 0:03.17 INFO Console message: [JavaScript Error: "1698289045697 urlbar ERROR QuickSuggest.SuggestBackendRust :: Ingest error: Error executing SQL: FOREIGN KEY constraint failed" {file: "resource://gre/modules/Log.sys.mjs" line: 722}] // The expected index of the Pocket suggestion. const EXPECTED_RESULT_INDEX = 1; @@ -30,6 +24,8 @@ const REMOTE_SETTINGS_DATA = [ }, ]; +requestLongerTimeout(5); + add_setup(async function () { await SpecialPowers.pushPrefEnv({ set: [ @@ -47,7 +43,7 @@ add_setup(async function () { }); }); -add_task(async function basic() { +add_tasks_with_rust(async function basic() { await BrowserTestUtils.withNewTab("about:blank", async () => { // Do a search. await UrlbarTestUtils.promiseAutocompleteResultPopup({ @@ -96,7 +92,7 @@ add_task(async function basic() { }); // Tests the "Show less frequently" command. -add_task(async function resultMenu_showLessFrequently() { +add_tasks_with_rust(async function resultMenu_showLessFrequently() { await SpecialPowers.pushPrefEnv({ set: [ ["browser.urlbar.pocket.featureGate", true], @@ -235,7 +231,7 @@ async function doShowLessFrequently({ input, expected, keepViewOpen = false }) { } // Tests the "Not interested" result menu dismissal command. -add_task(async function resultMenu_notInterested() { +add_tasks_with_rust(async function resultMenu_notInterested() { await doDismissTest("not_interested"); // Re-enable suggestions and wait until PocketSuggestions syncs them from @@ -245,7 +241,7 @@ add_task(async function resultMenu_notInterested() { }); // Tests the "Not relevant" result menu dismissal command. -add_task(async function notRelevant() { +add_tasks_with_rust(async function notRelevant() { await doDismissTest("not_relevant"); }); @@ -361,7 +357,7 @@ async function doDismissTest(command) { } // Tests row labels. -add_task(async function rowLabel() { +add_tasks_with_rust(async function rowLabel() { const testCases = [ // high confidence keyword best match { @@ -389,7 +385,7 @@ add_task(async function rowLabel() { }); // Tests visibility of "Show less frequently" menu. -add_task(async function showLessFrequentlyMenuVisibility() { +add_tasks_with_rust(async function showLessFrequentlyMenuVisibility() { const testCases = [ // high confidence keyword best match { diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js index b7c2bdc25c..7197946171 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_yelp.js @@ -401,6 +401,11 @@ async function doDismiss({ menu, assert }) { await UrlbarTestUtils.promisePopupClose(window); } +// Tests the "Manage" result menu. +add_task(async function resultMenu_manage() { + await doManageTest({ input: "ramen", index: 1 }); +}); + // Tests the row/group label. add_task(async function rowLabel() { let tests = [ diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_dynamicWikipedia.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_dynamicWikipedia.js index 001c54458c..71c289e0ef 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_dynamicWikipedia.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_dynamicWikipedia.js @@ -7,11 +7,6 @@ "use strict"; -ChromeUtils.defineESModuleGetters(this, { - CONTEXTUAL_SERVICES_PING_TYPES: - "resource:///modules/PartnerLinkAttribution.sys.mjs", -}); - const { TELEMETRY_SCALARS } = UrlbarProviderQuickSuggest; const MERINO_SUGGESTION = { diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_gleanEmptyStrings.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_gleanEmptyStrings.js index 00cbe6c4e1..2c75b63a71 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_gleanEmptyStrings.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_gleanEmptyStrings.js @@ -7,11 +7,6 @@ "use strict"; -ChromeUtils.defineESModuleGetters(this, { - CONTEXTUAL_SERVICES_PING_TYPES: - "resource:///modules/PartnerLinkAttribution.sys.mjs", -}); - const { TELEMETRY_SCALARS } = UrlbarProviderQuickSuggest; const MERINO_RESULT = { diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_impressionEdgeCases.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_impressionEdgeCases.js index 821c5cf470..eab48faaaf 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_impressionEdgeCases.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_impressionEdgeCases.js @@ -8,8 +8,6 @@ "use strict"; ChromeUtils.defineESModuleGetters(this, { - CONTEXTUAL_SERVICES_PING_TYPES: - "resource:///modules/PartnerLinkAttribution.sys.mjs", UrlbarView: "resource:///modules/UrlbarView.sys.mjs", sinon: "resource://testing-common/Sinon.sys.mjs", }); @@ -376,8 +374,11 @@ async function doEngagementWithoutAddingResultToView( let getPriorityStub = sandbox.stub(UrlbarProviderQuickSuggest, "getPriority"); getPriorityStub.returns(Infinity); - // Spy on `UrlbarProviderQuickSuggest.onEngagement()`. - let onEngagementSpy = sandbox.spy(UrlbarProviderQuickSuggest, "onEngagement"); + // Spy on `UrlbarProviderQuickSuggest.onLegacyEngagement()`. + let onLegacyEngagementSpy = sandbox.spy( + UrlbarProviderQuickSuggest, + "onLegacyEngagement" + ); let sandboxCleanup = () => { getPriorityStub?.restore(); @@ -454,7 +455,7 @@ async function doEngagementWithoutAddingResultToView( }); await loadPromise; - let engagementCalls = onEngagementSpy.getCalls().filter(call => { + let engagementCalls = onLegacyEngagementSpy.getCalls().filter(call => { let state = call.args[0]; return state == "engagement"; }); diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_nonsponsored.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_nonsponsored.js index 9a1aa06c02..f541801bae 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_nonsponsored.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_nonsponsored.js @@ -7,11 +7,6 @@ "use strict"; -ChromeUtils.defineESModuleGetters(this, { - CONTEXTUAL_SERVICES_PING_TYPES: - "resource:///modules/PartnerLinkAttribution.sys.mjs", -}); - const { TELEMETRY_SCALARS } = UrlbarProviderQuickSuggest; const REMOTE_SETTINGS_RESULT = { diff --git a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_sponsored.js b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_sponsored.js index 7c477e8af7..b11a491c92 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_sponsored.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/browser_telemetry_sponsored.js @@ -7,11 +7,6 @@ "use strict"; -ChromeUtils.defineESModuleGetters(this, { - CONTEXTUAL_SERVICES_PING_TYPES: - "resource:///modules/PartnerLinkAttribution.sys.mjs", -}); - const { TELEMETRY_SCALARS } = UrlbarProviderQuickSuggest; const REMOTE_SETTINGS_RESULT = { diff --git a/browser/components/urlbar/tests/quicksuggest/browser/head.js b/browser/components/urlbar/tests/quicksuggest/browser/head.js index cc5f449e94..a1bf0feabe 100644 --- a/browser/components/urlbar/tests/quicksuggest/browser/head.js +++ b/browser/components/urlbar/tests/quicksuggest/browser/head.js @@ -12,7 +12,7 @@ Services.scriptloader.loadSubScript( ChromeUtils.defineESModuleGetters(this, { CONTEXTUAL_SERVICES_PING_TYPES: - "resource:///modules/PartnerLinkAttribution.jsm", + "resource:///modules/PartnerLinkAttribution.sys.mjs", QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs", TelemetryTestUtils: "resource://testing-common/TelemetryTestUtils.sys.mjs", UrlbarProviderQuickSuggest: @@ -522,6 +522,45 @@ async function doCommandTest({ info("Finished command test: " + JSON.stringify({ commandOrArray })); } +/* + * Do test the "Manage" result menu item. + * + * @param {object} options + * Options + * @param {number} options.index + * The index of the suggestion that will be checked in the results list. + * @param {number} options.input + * The input value on the urlbar. + */ +async function doManageTest({ index, input }) { + await BrowserTestUtils.withNewTab({ gBrowser }, async browser => { + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: input, + }); + + const managePage = "about:preferences#search"; + let onManagePageLoaded = BrowserTestUtils.browserLoaded( + browser, + false, + managePage + ); + // Click the command. + await UrlbarTestUtils.openResultMenuAndClickItem(window, "manage", { + resultIndex: index, + }); + await onManagePageLoaded; + + Assert.equal( + browser.currentURI.spec, + managePage, + "The manage page is loaded" + ); + + await UrlbarTestUtils.promisePopupClose(window); + }); +} + /** * Gets a row in the view, which is assumed to be open, and asserts that it's a * particular quick suggest row. If it is, the row is returned. If it's not, diff --git a/browser/components/urlbar/tests/quicksuggest/unit/head.js b/browser/components/urlbar/tests/quicksuggest/unit/head.js index 73bedf468e..5808e06bdf 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/head.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/head.js @@ -182,14 +182,11 @@ function makeWikipediaResult({ qsSuggestion: keyword, sponsoredAdvertiser: "Wikipedia", sponsoredIabCategory: "5 - Education", - helpUrl: QuickSuggest.HELP_URL, - helpL10n: { - id: "urlbar-result-menu-learn-more-about-firefox-suggest", - }, isBlockable: true, blockL10n: { id: "urlbar-result-menu-dismiss-firefox-suggest", }, + isManageable: true, telemetryType: "adm_nonsponsored", }, }; @@ -256,14 +253,11 @@ function makeAmpResult({ sponsoredBlockId: blockId, sponsoredAdvertiser: advertiser, sponsoredIabCategory: iabCategory, - helpUrl: QuickSuggest.HELP_URL, - helpL10n: { - id: "urlbar-result-menu-learn-more-about-firefox-suggest", - }, isBlockable: true, blockL10n: { id: "urlbar-result-menu-dismiss-firefox-suggest", }, + isManageable: true, telemetryType: "adm_sponsored", descriptionL10n: { id: "urlbar-result-action-sponsored" }, }, diff --git a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js index 1c00cb5320..ecb7c3dd09 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js @@ -3884,7 +3884,7 @@ async function checkSearch({ name, searchString, expectedResults }) { removeResult() {}, }, }); - UrlbarProviderQuickSuggest.onEngagement( + UrlbarProviderQuickSuggest.onLegacyEngagement( "engagement", context, { diff --git a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_merinoSessions.js b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_merinoSessions.js index 61b1b9186f..c98fc5b6b4 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_merinoSessions.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_merinoSessions.js @@ -149,7 +149,7 @@ add_task(async function canceledQueries() { }); function endEngagement({ controller, context = null, state = "engagement" }) { - UrlbarProviderQuickSuggest.onEngagement( + UrlbarProviderQuickSuggest.onLegacyEngagement( state, context || createContext("endEngagement", { diff --git a/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js b/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js index cd794f435b..8479b97210 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/test_weather.js @@ -723,7 +723,7 @@ add_tasks_with_rust(async function block() { let result = context.results[0]; let provider = UrlbarProvidersManager.getProvider(result.providerName); Assert.ok(provider, "Sanity check: Result provider found"); - provider.onEngagement( + provider.onLegacyEngagement( "engagement", context, { diff --git a/browser/components/urlbar/tests/unit/test_exposure.js b/browser/components/urlbar/tests/unit/test_exposure.js index e3ce0b8479..3e63e668d7 100644 --- a/browser/components/urlbar/tests/unit/test_exposure.js +++ b/browser/components/urlbar/tests/unit/test_exposure.js @@ -3,7 +3,6 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ ChromeUtils.defineESModuleGetters(this, { - QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs", UrlbarProviderQuickSuggest: "resource:///modules/UrlbarProviderQuickSuggest.sys.mjs", }); @@ -177,14 +176,11 @@ function makeAmpResult({ sponsoredBlockId: blockId, sponsoredAdvertiser: advertiser, sponsoredIabCategory: iabCategory, - helpUrl: QuickSuggest.HELP_URL, - helpL10n: { - id: "urlbar-result-menu-learn-more-about-firefox-suggest", - }, isBlockable: true, blockL10n: { id: "urlbar-result-menu-dismiss-firefox-suggest", }, + isManageable: true, telemetryType: "adm_sponsored", descriptionL10n: { id: "urlbar-result-action-sponsored" }, }, @@ -240,14 +236,11 @@ function makeWikipediaResult({ qsSuggestion: keyword, sponsoredAdvertiser: "Wikipedia", sponsoredIabCategory: "5 - Education", - helpUrl: QuickSuggest.HELP_URL, - helpL10n: { - id: "urlbar-result-menu-learn-more-about-firefox-suggest", - }, isBlockable: true, blockL10n: { id: "urlbar-result-menu-dismiss-firefox-suggest", }, + isManageable: true, telemetryType: "adm_nonsponsored", }, }; diff --git a/browser/components/urlbar/tests/unit/test_l10nCache.js b/browser/components/urlbar/tests/unit/test_l10nCache.js index e92c75fa01..bd93cc50d6 100644 --- a/browser/components/urlbar/tests/unit/test_l10nCache.js +++ b/browser/components/urlbar/tests/unit/test_l10nCache.js @@ -1,7 +1,7 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -// Tests L10nCache in UrlbarUtils.jsm. +// Tests L10nCache in UrlbarUtils.sys.mjs. "use strict"; -- cgit v1.2.3