/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /** * These tests load SERPs and click on cacheable links. */ "use strict"; const { SearchSERPTelemetry, SearchSERPTelemetryUtils } = ChromeUtils.importESModule("resource:///modules/SearchSERPTelemetry.sys.mjs"); const TEST_PROVIDER_INFO = [ { telemetryId: "example", searchPageRegexp: /^https:\/\/example.org\/browser\/browser\/components\/search\/test\/browser\/searchTelemetryAd_/, queryParamName: "s", codeParamName: "abc", taggedCodes: ["ff"], adServerAttributes: ["mozAttr"], nonAdsLinkRegexps: [], extraAdServersRegexps: [/^https:\/\/example\.com\/ad/], components: [ { type: SearchSERPTelemetryUtils.COMPONENTS.AD_CAROUSEL, included: { parent: { selector: ".moz-carousel", }, children: [ { selector: ".moz-carousel-card", countChildren: true, }, ], related: { selector: "button", }, }, }, { type: SearchSERPTelemetryUtils.COMPONENTS.AD_LINK, included: { parent: { selector: ".moz_ad", }, children: [ { selector: ".multi-col", type: SearchSERPTelemetryUtils.COMPONENTS.AD_SITELINK, }, ], related: { selector: "button", }, }, excluded: { parent: { selector: ".rhs", }, }, }, { type: SearchSERPTelemetryUtils.COMPONENTS.INCONTENT_SEARCHBOX, included: { parent: { selector: "form", }, children: [ { selector: "input", }, ], related: { selector: "div", }, }, topDown: true, }, { type: SearchSERPTelemetryUtils.COMPONENTS.AD_LINK, default: true, }, ], }, ]; function getSERPUrl(page, organic = false) { let url = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://example.org" ) + page; return `${url}?s=test${organic ? "" : "&abc=ff"}`; } async function promiseImpressionReceived() { return TestUtils.waitForCondition(() => { let adImpressions = Glean.serp.adImpression.testGetValue() ?? []; return adImpressions.length; }, "Should have received an ad impression."); } async function waitForIdle() { for (let i = 0; i < 10; i++) { await new Promise(resolve => Services.tm.idleDispatchToMainThread(resolve)); } } add_setup(async function () { SearchSERPTelemetry.overrideSearchTelemetryForTests(TEST_PROVIDER_INFO); await waitForIdle(); // Enable local telemetry recording for the duration of the tests. let oldCanRecord = Services.telemetry.canRecordExtended; Services.telemetry.canRecordExtended = true; await SpecialPowers.pushPrefEnv({ set: [ ["browser.search.log", true], ["browser.search.serpEventTelemetry.enabled", true], ], }); registerCleanupFunction(async () => { SearchSERPTelemetry.overrideSearchTelemetryForTests(); Services.telemetry.canRecordExtended = oldCanRecord; resetTelemetry(); }); }); add_task(async function test_click_cached_page() { let url = getSERPUrl("searchTelemetryAd_components_text.html"); let cacheableUrl = "https://example.com/browser/browser/components/search/test/browser/cacheable.html"; let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); await waitForPageWithAdImpressions(); let pageLoadPromise = BrowserTestUtils.waitForLocationChange( gBrowser, cacheableUrl ); await BrowserTestUtils.synthesizeMouseAtCenter( "a#non_ads_link", {}, tab.linkedBrowser ); await pageLoadPromise; gBrowser.goBack(); await waitForPageWithAdImpressions(); pageLoadPromise = BrowserTestUtils.waitForLocationChange( gBrowser, cacheableUrl ); await BrowserTestUtils.synthesizeMouseAtCenter( "a#non_ads_link", {}, tab.linkedBrowser ); await pageLoadPromise; assertImpressionEvents([ { impression: { provider: "example", tagged: "true", partner_code: "ff", source: "unknown", is_shopping_page: "false", shopping_tab_displayed: "false", }, engagements: [ { action: SearchSERPTelemetryUtils.ACTIONS.CLICKED, target: SearchSERPTelemetryUtils.COMPONENTS.NON_ADS_LINK, }, ], }, { impression: { provider: "example", tagged: "true", partner_code: "ff", source: "tabhistory", is_shopping_page: "false", shopping_tab_displayed: "false", }, engagements: [ { action: SearchSERPTelemetryUtils.ACTIONS.CLICKED, target: SearchSERPTelemetryUtils.COMPONENTS.NON_ADS_LINK, }, ], }, ]); BrowserTestUtils.removeTab(tab); });