/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Test to verify we can toggle the Glean SERP telemetry feature via a Nimbus // variable. const { SearchSERPTelemetry, SearchSERPTelemetryUtils } = ChromeUtils.importESModule("resource:///modules/SearchSERPTelemetry.sys.mjs"); const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { ExperimentAPI: "resource://nimbus/ExperimentAPI.sys.mjs", ExperimentFakes: "resource://testing-common/NimbusTestUtils.sys.mjs", }); XPCOMUtils.defineLazyPreferenceGetter( lazy, "serpEventsEnabled", "browser.search.serpEventTelemetry.enabled", false ); const TEST_PROVIDER_INFO = [ { telemetryId: "example", searchPageRegexp: /^https:\/\/example.org\/browser\/browser\/components\/search\/test\/browser\/searchTelemetry(?:Ad)?.html/, queryParamName: "s", codeParamName: "abc", taggedCodes: ["ff"], followOnParamNames: ["a"], extraAdServersRegexps: [/^https:\/\/example\.com\/ad2?/], components: [ { type: SearchSERPTelemetryUtils.COMPONENTS.AD_LINK, default: true, }, ], }, ]; async function verifyEventsRecorded() { function getSERPUrl(page, organic = false) { let url = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://example.org" ) + page; return `${url}?s=test${organic ? "" : "&abc=ff"}`; } resetTelemetry(); let tab = await BrowserTestUtils.openNewForegroundTab( gBrowser, getSERPUrl("searchTelemetryAd.html") ); assertImpressionEvents([ { impression: { provider: "example", tagged: "true", partner_code: "ff", source: "unknown", is_shopping_page: "false", shopping_tab_displayed: "false", }, }, ]); await waitForPageWithAdImpressions(); assertAdImpressionEvents([ { component: SearchSERPTelemetryUtils.COMPONENTS.AD_LINK, ads_loaded: "2", ads_visible: "2", ads_hidden: "0", }, ]); BrowserTestUtils.removeTab(tab); assertAbandonmentEvent({ abandonment: { reason: SearchSERPTelemetryUtils.ABANDONMENTS.TAB_CLOSE, }, }); } // sharedData messages are only passed to the child on idle. Therefore // we wait for a few idles to try and ensure the messages have been able // to be passed across and handled. 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]], }); registerCleanupFunction(async () => { SearchSERPTelemetry.overrideSearchTelemetryForTests(); Services.telemetry.canRecordExtended = oldCanRecord; await SpecialPowers.popPrefEnv(); resetTelemetry(); }); }); add_task(async function test_enable_experiment() { Assert.equal( lazy.serpEventsEnabled, false, "serpEventsEnabled should be false when not enrolled in experiment." ); await lazy.ExperimentAPI.ready(); let doExperimentCleanup = await lazy.ExperimentFakes.enrollWithFeatureConfig( { featureId: NimbusFeatures.search.featureId, value: { serpEventTelemetryEnabled: true, }, }, { isRollout: true } ); Assert.equal( lazy.serpEventsEnabled, true, "serpEventsEnabled should be true when enrolled in experiment." ); // To ensure Nimbus set "browser.search.serpEventTelemetry.enabled" to true, // we test that an impression, ad_impression and abandonment event are // recorded correctly. await verifyEventsRecorded(); await doExperimentCleanup(); Assert.equal( lazy.serpEventsEnabled, false, "serpEventsEnabled should be false after experiment." ); });