diff options
Diffstat (limited to 'browser/components/search/test/browser/telemetry/browser_search_telemetry_domain_categorization_reporting_timer.js')
-rw-r--r-- | browser/components/search/test/browser/telemetry/browser_search_telemetry_domain_categorization_reporting_timer.js | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/browser/components/search/test/browser/telemetry/browser_search_telemetry_domain_categorization_reporting_timer.js b/browser/components/search/test/browser/telemetry/browser_search_telemetry_domain_categorization_reporting_timer.js new file mode 100644 index 0000000000..cfb8590960 --- /dev/null +++ b/browser/components/search/test/browser/telemetry/browser_search_telemetry_domain_categorization_reporting_timer.js @@ -0,0 +1,287 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * These tests check that we report the categorization if the SERP is loaded, + * and the user idles. The tests also check that if we report the + * categorization and trigger another event that could cause a reporting, we + * don't cause more than one categorization to be reported. + */ + +ChromeUtils.defineESModuleGetters(this, { + SearchSERPCategorizationEventScheduler: + "resource:///modules/SearchSERPTelemetry.sys.mjs", +}); + +const TEST_PROVIDER_INFO = [ + { + telemetryId: "example", + searchPageRegexp: + /^https:\/\/example.org\/browser\/browser\/components\/search\/test\/browser\/telemetry\/searchTelemetry/, + queryParamNames: ["s"], + codeParamName: "abc", + taggedCodes: ["ff"], + adServerAttributes: ["mozAttr"], + nonAdsLinkRegexps: [], + extraAdServersRegexps: [/^https:\/\/example\.com\/ad/], + // The search telemetry entry responsible for targeting the specific results. + domainExtraction: { + ads: [ + { + selectors: "[data-ad-domain]", + method: "data-attribute", + options: { + dataAttributeKey: "adDomain", + }, + }, + { + selectors: ".ad", + method: "href", + options: { + queryParamKey: "ad_domain", + }, + }, + ], + nonAds: [ + { + selectors: "#results .organic a", + method: "href", + }, + ], + }, + components: [ + { + type: SearchSERPTelemetryUtils.COMPONENTS.AD_LINK, + default: true, + }, + ], + }, +]; + +add_setup(async function () { + SearchTestUtils.useMockIdleService(); + SearchSERPTelemetry.overrideSearchTelemetryForTests(TEST_PROVIDER_INFO); + + // On startup, the event scheduler is initialized. + // If serpEventTelemetryCategorization is already true, the instance of the + // class will be subscribed to to the real idle service instead of the mock + // idle service. If it's false, toggling the preference (which happens later + // in this setup) will initialize it. + if ( + Services.prefs.getBoolPref( + "browser.search.serpEventTelemetryCategorization.enabled" + ) + ) { + SearchSERPCategorizationEventScheduler.uninit(); + SearchSERPCategorizationEventScheduler.init(); + } + await waitForIdle(); + + let promise = waitForDomainToCategoriesUpdate(); + await insertRecordIntoCollectionAndSync(); + await SpecialPowers.pushPrefEnv({ + set: [["browser.search.serpEventTelemetryCategorization.enabled", true]], + }); + await promise; + + registerCleanupFunction(async () => { + // The scheduler uses the mock idle service. + SearchSERPCategorizationEventScheduler.uninit(); + SearchSERPCategorizationEventScheduler.init(); + SearchSERPTelemetry.overrideSearchTelemetryForTests(); + resetTelemetry(); + }); +}); + +add_task(async function test_categorize_serp_and_wait() { + resetTelemetry(); + + let url = getSERPUrl("searchTelemetryDomainCategorizationReporting.html"); + info("Load a SERP with organic and sponsored results."); + let promise = waitForPageWithCategorizedDomains(); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + await promise; + + assertCategorizationValues([]); + + promise = waitForAllCategorizedEvents(); + SearchTestUtils.idleService._fireObservers("idle"); + await promise; + assertCategorizationValues([ + { + organic_category: "3", + organic_num_domains: "1", + organic_num_inconclusive: "0", + organic_num_unknown: "0", + sponsored_category: "4", + sponsored_num_domains: "2", + sponsored_num_inconclusive: "0", + sponsored_num_unknown: "0", + mappings_version: "1", + app_version: APP_MAJOR_VERSION, + channel: CHANNEL, + region: REGION, + partner_code: "ff", + provider: "example", + tagged: "true", + num_ads_clicked: "0", + num_ads_visible: "2", + }, + ]); + + info("Ensure we don't record a duplicate of this event."); + resetTelemetry(); + SearchTestUtils.idleService._fireObservers("idle"); + SearchTestUtils.idleService._fireObservers("active"); + await BrowserTestUtils.removeTab(tab); + + assertCategorizationValues([]); +}); + +add_task(async function test_categorize_serp_open_multiple_tabs() { + resetTelemetry(); + + let tabs = []; + let expectedResults = []; + for (let i = 0; i < 5; ++i) { + let url = getSERPUrl("searchTelemetryDomainCategorizationReporting.html"); + info("Load a SERP with organic and sponsored results."); + let promise = waitForPageWithCategorizedDomains(); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + await promise; + tabs.push(tab); + // Pushing expected results into a single array to avoid having a massive, + // unreadable array. + expectedResults.push({ + organic_category: "3", + organic_num_domains: "1", + organic_num_inconclusive: "0", + organic_num_unknown: "0", + sponsored_category: "4", + sponsored_num_domains: "2", + sponsored_num_inconclusive: "0", + sponsored_num_unknown: "0", + mappings_version: "1", + app_version: APP_MAJOR_VERSION, + channel: CHANNEL, + region: REGION, + partner_code: "ff", + provider: "example", + tagged: "true", + num_ads_clicked: "0", + num_ads_visible: "2", + }); + } + + info("Simulate idle event and wait for results."); + let promise = waitForAllCategorizedEvents(); + SearchTestUtils.idleService._fireObservers("idle"); + await promise; + assertCategorizationValues(expectedResults); + + info("Ensure we don't record a duplicate of any event."); + resetTelemetry(); + for (let tab of tabs) { + await BrowserTestUtils.removeTab(tab); + } + assertCategorizationValues([]); +}); + +// Ensures we don't double record a categorization event if the closed the tab +// before an idle event. +add_task(async function test_categorize_serp_close_tab_and_wait() { + resetTelemetry(); + + let url = getSERPUrl("searchTelemetryDomainCategorizationReporting.html"); + info("Load a SERP with organic and sponsored results."); + let promise = waitForPageWithCategorizedDomains(); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + await promise; + + assertCategorizationValues([]); + + promise = waitForSingleCategorizedEvent(); + await BrowserTestUtils.removeTab(tab); + await promise; + + assertCategorizationValues([ + { + organic_category: "3", + organic_num_domains: "1", + organic_num_inconclusive: "0", + organic_num_unknown: "0", + sponsored_category: "4", + sponsored_num_domains: "2", + sponsored_num_inconclusive: "0", + sponsored_num_unknown: "0", + mappings_version: "1", + app_version: APP_MAJOR_VERSION, + channel: CHANNEL, + region: REGION, + partner_code: "ff", + provider: "example", + tagged: "true", + num_ads_clicked: "0", + num_ads_visible: "2", + }, + ]); + + info("Ensure we don't record a duplicate of this event."); + resetTelemetry(); + SearchTestUtils.idleService._fireObservers("idle"); + assertCategorizationValues([]); +}); + +add_task(async function test_categorize_serp_open_ad_and_wait() { + resetTelemetry(); + + let url = getSERPUrl("searchTelemetryDomainCategorizationReporting.html"); + info("Load a SERP with organic and sponsored results."); + let promise = waitForPageWithCategorizedDomains(); + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + await promise; + + info("Open ad in new tab."); + let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser); + await BrowserTestUtils.synthesizeMouseAtCenter( + ".ad", + { button: 1 }, + tab.linkedBrowser + ); + let tab2 = await promiseTabOpened; + + assertCategorizationValues([]); + + promise = waitForAllCategorizedEvents(); + SearchTestUtils.idleService._fireObservers("idle"); + info("Waiting for categorized events."); + await promise; + + assertCategorizationValues([ + { + organic_category: "3", + organic_num_domains: "1", + organic_num_inconclusive: "0", + organic_num_unknown: "0", + sponsored_category: "4", + sponsored_num_domains: "2", + sponsored_num_inconclusive: "0", + sponsored_num_unknown: "0", + mappings_version: "1", + app_version: APP_MAJOR_VERSION, + channel: CHANNEL, + region: REGION, + partner_code: "ff", + provider: "example", + tagged: "true", + num_ads_clicked: "1", + num_ads_visible: "2", + }, + ]); + + // Clean up. + await BrowserTestUtils.removeTab(tab); + await BrowserTestUtils.removeTab(tab2); +}); |