From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../test/browser/browser_PartnerLinkAttribution.js | 428 +++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 browser/modules/test/browser/browser_PartnerLinkAttribution.js (limited to 'browser/modules/test/browser/browser_PartnerLinkAttribution.js') diff --git a/browser/modules/test/browser/browser_PartnerLinkAttribution.js b/browser/modules/test/browser/browser_PartnerLinkAttribution.js new file mode 100644 index 0000000000..08e393694d --- /dev/null +++ b/browser/modules/test/browser/browser_PartnerLinkAttribution.js @@ -0,0 +1,428 @@ +/* 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"; + +// The preference to enable suggestions in the urlbar. +const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches"; +// The name of the search engine used to generate suggestions. +const SUGGESTION_ENGINE_NAME = + "browser_UsageTelemetry usageTelemetrySearchSuggestions.xml"; + +ChromeUtils.defineESModuleGetters(this, { + CustomizableUITestUtils: + "resource://testing-common/CustomizableUITestUtils.sys.mjs", + + Region: "resource://gre/modules/Region.sys.mjs", + SearchTestUtils: "resource://testing-common/SearchTestUtils.sys.mjs", + UrlbarTestUtils: "resource://testing-common/UrlbarTestUtils.sys.mjs", +}); + +XPCOMUtils.defineLazyModuleGetters(this, { + HttpServer: "resource://testing-common/httpd.js", +}); + +let gCUITestUtils = new CustomizableUITestUtils(window); +SearchTestUtils.init(this); + +var gHttpServer = null; +var gRequests = []; + +function submitHandler(request, response) { + gRequests.push(request); + response.setStatusLine(request.httpVersion, 200, "Ok"); +} + +add_setup(async function () { + // Ensure the initial init is complete. + await Services.search.init(); + + // 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(); + + let searchExtensions = getChromeDir(getResolvedURI(gTestPath)); + searchExtensions.append("search-engines"); + + await SearchTestUtils.useMochitestEngines(searchExtensions); + + SearchTestUtils.useMockIdleService(); + let response = await fetch(`resource://search-extensions/engines.json`); + let json = await response.json(); + await SearchTestUtils.updateRemoteSettingsConfig(json.data); + + let topsitesAttribution = Services.prefs.getStringPref( + "browser.partnerlink.campaign.topsites" + ); + gHttpServer = new HttpServer(); + gHttpServer.registerPathHandler(`/cid/${topsitesAttribution}`, submitHandler); + gHttpServer.start(-1); + + await SpecialPowers.pushPrefEnv({ + set: [ + // Enable search suggestions in the urlbar. + [SUGGEST_URLBAR_PREF, true], + // Clear historical search suggestions to avoid interference from previous + // tests. + ["browser.urlbar.maxHistoricalSearchSuggestions", 0], + [ + "browser.partnerlink.attributionURL", + `http://localhost:${gHttpServer.identity.primaryPort}/cid/`, + ], + ], + }); + + await gCUITestUtils.addSearchBar(); + + // Make sure to restore the engine once we're done. + registerCleanupFunction(async function () { + let settingsWritten = SearchTestUtils.promiseSearchNotification( + "write-settings-to-disk-complete" + ); + await SearchTestUtils.updateRemoteSettingsConfig(); + await gHttpServer.stop(); + gHttpServer = null; + await PlacesUtils.history.clear(); + gCUITestUtils.removeSearchBar(); + await settingsWritten; + }); +}); + +function searchInAwesomebar(value, win = window) { + return UrlbarTestUtils.promiseAutocompleteResultPopup({ + window: win, + waitForFocus, + value, + fireInputEvent: true, + }); +} + +async function searchInSearchbar(inputText) { + let win = window; + await new Promise(r => waitForFocus(r, win)); + let sb = BrowserSearch.searchBar; + // Write the search query in the searchbar. + sb.focus(); + sb.value = inputText; + sb.textbox.controller.startSearch(inputText); + // Wait for the popup to be shown and built. + let popup = sb.textbox.popup; + await Promise.all([ + BrowserTestUtils.waitForEvent(popup, "popupshown"), + BrowserTestUtils.waitForEvent(popup.oneOffButtons, "rebuild"), + ]); + // And then for the search to complete. + await BrowserTestUtils.waitForCondition( + () => + sb.textbox.controller.searchStatus >= + Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH, + "The search in the searchbar must complete." + ); +} + +add_task(async function test_simpleQuery_no_attribution() { + await Services.search.setDefault( + Services.search.getEngineByName("Simple Engine"), + Ci.nsISearchService.CHANGE_REASON_UNKNOWN + ); + + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:blank" + ); + + info("Simulate entering a simple search."); + let promiseLoad = BrowserTestUtils.waitForDocLoadAndStopIt( + "https://example.com/?sourceId=Mozilla-search&search=simple+query", + tab + ); + await searchInAwesomebar("simple query"); + EventUtils.synthesizeKey("KEY_Enter"); + await promiseLoad; + + await new Promise(resolve => Services.tm.dispatchToMainThread(resolve)); + + Assert.equal(gRequests.length, 0, "Should not have submitted an attribution"); + + BrowserTestUtils.removeTab(tab); + + await Services.search.setDefault( + Services.search.getEngineByName("basic"), + Ci.nsISearchService.CHANGE_REASON_UNKNOWN + ); +}); + +async function checkAttributionRecorded(actionFn, cleanupFn) { + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "data:text/plain;charset=utf8,simple%20query" + ); + + let promiseLoad = BrowserTestUtils.waitForDocLoadAndStopIt( + "https://mochi.test:8888/browser/browser/components/search/test/browser/?search=simple+query&foo=1", + tab + ); + await actionFn(tab); + await promiseLoad; + + await BrowserTestUtils.waitForCondition( + () => gRequests.length == 1, + "Should have received an attribution submission" + ); + Assert.equal( + gRequests[0].getHeader("X-Region"), + Region.home, + "Should have set the region correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Source"), + "searchurl", + "Should have set the source correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Target-url"), + "https://mochi.test:8888/browser/browser/components/search/test/browser/?foo=1", + "Should have set the target url correctly and stripped the search terms" + ); + if (cleanupFn) { + await cleanupFn(); + } + BrowserTestUtils.removeTab(tab); + gRequests = []; +} + +add_task(async function test_urlbar() { + await checkAttributionRecorded(async tab => { + await searchInAwesomebar("simple query"); + EventUtils.synthesizeKey("KEY_Enter"); + }); +}); + +add_task(async function test_searchbar() { + await checkAttributionRecorded(async tab => { + let sb = BrowserSearch.searchBar; + // Write the search query in the searchbar. + sb.focus(); + sb.value = "simple query"; + sb.textbox.controller.startSearch("simple query"); + // Wait for the popup to show. + await BrowserTestUtils.waitForEvent(sb.textbox.popup, "popupshown"); + // And then for the search to complete. + await BrowserTestUtils.waitForCondition( + () => + sb.textbox.controller.searchStatus >= + Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH, + "The search in the searchbar must complete." + ); + EventUtils.synthesizeKey("KEY_Enter"); + }); +}); + +add_task(async function test_context_menu() { + let contextMenu; + await checkAttributionRecorded( + async tab => { + info("Select all the text in the page."); + await SpecialPowers.spawn(tab.linkedBrowser, [""], async function () { + return new Promise(resolve => { + content.document.addEventListener( + "selectionchange", + () => resolve(), + { + once: true, + } + ); + content.document + .getSelection() + .selectAllChildren(content.document.body); + }); + }); + + info("Open the context menu."); + contextMenu = document.getElementById("contentAreaContextMenu"); + let shownPromise = BrowserTestUtils.waitForEvent( + contextMenu, + "popupshown" + ); + BrowserTestUtils.synthesizeMouseAtCenter( + "body", + { type: "contextmenu", button: 2 }, + gBrowser.selectedBrowser + ); + await shownPromise; + + let hiddenPromise = BrowserTestUtils.waitForEvent( + contextMenu, + "popuphidden" + ); + + info("Click on search."); + let searchItem = contextMenu.querySelector("#context-searchselect"); + contextMenu.activateItem(searchItem); + await hiddenPromise; + }, + () => { + BrowserTestUtils.removeTab(gBrowser.selectedTab); + } + ); +}); + +add_task(async function test_about_newtab() { + await SpecialPowers.pushPrefEnv({ + set: [ + [ + "browser.newtabpage.activity-stream.improvesearch.handoffToAwesomebar", + false, + ], + ], + }); + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:newtab", + false + ); + await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { + await ContentTaskUtils.waitForCondition(() => !content.document.hidden); + }); + + info("Trigger a simple search, just text + enter."); + let promiseLoad = BrowserTestUtils.waitForDocLoadAndStopIt( + "https://mochi.test:8888/browser/browser/components/search/test/browser/?search=simple+query&foo=1", + tab + ); + await typeInSearchField( + tab.linkedBrowser, + "simple query", + "newtab-search-text" + ); + await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, tab.linkedBrowser); + await promiseLoad; + + await BrowserTestUtils.waitForCondition( + () => gRequests.length == 1, + "Should have received an attribution submission" + ); + Assert.equal( + gRequests[0].getHeader("X-Region"), + Region.home, + "Should have set the region correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Source"), + "searchurl", + "Should have set the source correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Target-url"), + "https://mochi.test:8888/browser/browser/components/search/test/browser/?foo=1", + "Should have set the target url correctly and stripped the search terms" + ); + + BrowserTestUtils.removeTab(tab); + await SpecialPowers.popPrefEnv(); + gRequests = []; +}); + +add_task(async function test_urlbar_oneOff_click() { + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:blank" + ); + + info("Type a query."); + let promiseLoad = BrowserTestUtils.waitForDocLoadAndStopIt( + "https://mochi.test:8888/browser/browser/components/search/test/browser/?search=query&foo=1", + tab + ); + await searchInAwesomebar("query"); + info("Click the first one-off button."); + UrlbarTestUtils.getOneOffSearchButtons(window) + .getSelectableButtons(false)[0] + .click(); + EventUtils.synthesizeKey("KEY_Enter"); + await promiseLoad; + + await BrowserTestUtils.waitForCondition( + () => gRequests.length == 1, + "Should have received an attribution submission" + ); + Assert.equal( + gRequests[0].getHeader("X-Region"), + Region.home, + "Should have set the region correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Source"), + "searchurl", + "Should have set the source correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Target-url"), + "https://mochi.test:8888/browser/browser/components/search/test/browser/?foo=1", + "Should have set the target url correctly and stripped the search terms" + ); + + BrowserTestUtils.removeTab(tab); + gRequests = []; +}); + +add_task(async function test_searchbar_oneOff_click() { + // For this test, set the other engine as default, so that we can select + // the attribution engine as the first one in the one-offs. + await Services.search.setDefault( + Services.search.getEngineByName("Simple Engine"), + Ci.nsISearchService.CHANGE_REASON_UNKNOWN + ); + + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:blank" + ); + + info("Type a query."); + let promiseLoad = BrowserTestUtils.waitForDocLoadAndStopIt( + "https://mochi.test:8888/browser/browser/components/search/test/browser/?search=searchbar&foo=1", + tab + ); + await searchInSearchbar("searchbar"); + info("Click the first one-off button."); + BrowserSearch.searchBar.textbox.popup.oneOffButtons + .getSelectableButtons(false)[0] + .click(); + await promiseLoad; + + await BrowserTestUtils.waitForCondition( + () => gRequests.length == 1, + "Should have received an attribution submission" + ); + Assert.equal( + gRequests[0].getHeader("X-Region"), + Region.home, + "Should have set the region correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Source"), + "searchurl", + "Should have set the source correctly" + ); + Assert.equal( + gRequests[0].getHeader("X-Target-url"), + "https://mochi.test:8888/browser/browser/components/search/test/browser/?foo=1", + "Should have set the target url correctly and stripped the search terms" + ); + + BrowserTestUtils.removeTab(tab); + // Set back the engine in case of other tests in this file. + await Services.search.setDefault( + Services.search.getEngineByName("basic"), + Ci.nsISearchService.CHANGE_REASON_UNKNOWN + ); + gRequests = []; +}); -- cgit v1.2.3