forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			423 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			423 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* vim: set ts=2 et sw=2 tw=80: */
 | |
| /* 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/. */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| let { UrlClassifierTestUtils } = ChromeUtils.importESModule(
 | |
|   "resource://testing-common/UrlClassifierTestUtils.sys.mjs"
 | |
| );
 | |
| 
 | |
| const TEST_DOMAIN = "https://example.com/";
 | |
| const TEST_EMAIL_WEBAPP_DOMAIN = "https://test1.example.com/";
 | |
| const EMAIL_TRACKER_DOMAIN = "https://email-tracking.example.org/";
 | |
| const TEST_PATH = "browser/toolkit/components/url-classifier/tests/browser/";
 | |
| 
 | |
| const TEST_PAGE = TEST_DOMAIN + TEST_PATH + "page.html";
 | |
| const TEST_EMAIL_WEBAPP_PAGE =
 | |
|   TEST_EMAIL_WEBAPP_DOMAIN + TEST_PATH + "page.html";
 | |
| 
 | |
| const EMAIL_TRACKER_PAGE = EMAIL_TRACKER_DOMAIN + TEST_PATH + "page.html";
 | |
| const EMAIL_TRACKER_IMAGE = EMAIL_TRACKER_DOMAIN + TEST_PATH + "raptor.jpg";
 | |
| 
 | |
| const TELEMETRY_EMAIL_TRACKER_COUNT = "EMAIL_TRACKER_COUNT";
 | |
| const TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB =
 | |
|   "EMAIL_TRACKER_EMBEDDED_PER_TAB";
 | |
| 
 | |
| const LABEL_BASE_NORMAL = 0;
 | |
| const LABEL_CONTENT_NORMAL = 1;
 | |
| const LABEL_BASE_EMAIL_WEBAPP = 2;
 | |
| const LABEL_CONTENT_EMAIL_WEBAPP = 3;
 | |
| 
 | |
| const KEY_BASE_NORMAL = "base_normal";
 | |
| const KEY_CONTENT_NORMAL = "content_normal";
 | |
| const KEY_ALL_NORMAL = "all_normal";
 | |
| const KEY_BASE_EMAILAPP = "base_emailapp";
 | |
| const KEY_CONTENT_EMAILAPP = "content_emailapp";
 | |
| const KEY_ALL_EMAILAPP = "all_emailapp";
 | |
| 
 | |
| async function clearTelemetry() {
 | |
|   Services.telemetry.getSnapshotForHistograms("main", true /* clear */);
 | |
|   Services.telemetry.getHistogramById(TELEMETRY_EMAIL_TRACKER_COUNT).clear();
 | |
|   Services.telemetry
 | |
|     .getKeyedHistogramById(TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB)
 | |
|     .clear();
 | |
| }
 | |
| 
 | |
| async function loadImage(browser, url) {
 | |
|   return SpecialPowers.spawn(browser, [url], page => {
 | |
|     return new Promise(resolve => {
 | |
|       let image = new content.Image();
 | |
|       image.src = page + "?" + Math.random();
 | |
|       image.onload = _ => resolve(true);
 | |
|       image.onerror = _ => resolve(false);
 | |
|     });
 | |
|   });
 | |
| }
 | |
| 
 | |
| async function getTelemetryProbe(key, label, checkCntFn) {
 | |
|   let histogram;
 | |
| 
 | |
|   // Wait until the telemetry probe appears.
 | |
|   await TestUtils.waitForCondition(() => {
 | |
|     let histograms = Services.telemetry.getSnapshotForHistograms(
 | |
|       "main",
 | |
|       false /* clear */
 | |
|     ).parent;
 | |
| 
 | |
|     histogram = histograms[key];
 | |
| 
 | |
|     let checkRes = false;
 | |
| 
 | |
|     if (histogram) {
 | |
|       checkRes = checkCntFn ? checkCntFn(histogram.values[label]) : true;
 | |
|     }
 | |
| 
 | |
|     return checkRes;
 | |
|   });
 | |
| 
 | |
|   return histogram.values[label] || 0;
 | |
| }
 | |
| 
 | |
| async function getKeyedHistogram(histogram_id, key, bucket, checkCntFn) {
 | |
|   let histogram;
 | |
| 
 | |
|   // Wait until the telemetry probe appears.
 | |
|   await TestUtils.waitForCondition(() => {
 | |
|     let histograms = Services.telemetry.getSnapshotForKeyedHistograms(
 | |
|       "main",
 | |
|       false /* clear */
 | |
|     ).parent;
 | |
| 
 | |
|     histogram = histograms[histogram_id];
 | |
| 
 | |
|     let checkRes = false;
 | |
| 
 | |
|     if (histogram && histogram[key]) {
 | |
|       checkRes = checkCntFn ? checkCntFn(histogram[key].values[bucket]) : true;
 | |
|     }
 | |
| 
 | |
|     return checkRes;
 | |
|   });
 | |
| 
 | |
|   return histogram[key].values[bucket] || 0;
 | |
| }
 | |
| 
 | |
| async function checkTelemetryProbe(key, label, expectedCnt) {
 | |
|   let cnt = await getTelemetryProbe(key, label, cnt => {
 | |
|     if (cnt === undefined) {
 | |
|       cnt = 0;
 | |
|     }
 | |
| 
 | |
|     return cnt == expectedCnt;
 | |
|   });
 | |
| 
 | |
|   is(cnt, expectedCnt, "There should be expected count in telemetry.");
 | |
| }
 | |
| 
 | |
| async function checkKeyedHistogram(histogram_id, key, bucket, expectedCnt) {
 | |
|   let cnt = await getKeyedHistogram(histogram_id, key, bucket, cnt => {
 | |
|     if (cnt === undefined) {
 | |
|       cnt = 0;
 | |
|     }
 | |
| 
 | |
|     return cnt == expectedCnt;
 | |
|   });
 | |
| 
 | |
|   is(cnt, expectedCnt, "There should be expected count in keyed telemetry.");
 | |
| }
 | |
| 
 | |
| function checkNoTelemetryProbe(key) {
 | |
|   let histograms = Services.telemetry.getSnapshotForHistograms(
 | |
|     "main",
 | |
|     false /* clear */
 | |
|   ).parent;
 | |
| 
 | |
|   let histogram = histograms[key];
 | |
| 
 | |
|   ok(!histogram, `No Telemetry has been recorded for ${key}`);
 | |
| }
 | |
| 
 | |
| add_setup(async function () {
 | |
|   await SpecialPowers.pushPrefEnv({
 | |
|     set: [
 | |
|       [
 | |
|         "urlclassifier.features.emailtracking.datacollection.blocklistTables",
 | |
|         "mochitest5-track-simple",
 | |
|       ],
 | |
|       [
 | |
|         "urlclassifier.features.emailtracking.datacollection.allowlistTables",
 | |
|         "",
 | |
|       ],
 | |
|       [
 | |
|         "urlclassifier.features.emailtracking.blocklistTables",
 | |
|         "mochitest5-track-simple",
 | |
|       ],
 | |
|       ["urlclassifier.features.emailtracking.allowlistTables", ""],
 | |
|       ["privacy.trackingprotection.enabled", false],
 | |
|       ["privacy.trackingprotection.annotate_channels", false],
 | |
|       ["privacy.trackingprotection.cryptomining.enabled", false],
 | |
|       ["privacy.trackingprotection.emailtracking.enabled", true],
 | |
|       [
 | |
|         "privacy.trackingprotection.emailtracking.data_collection.enabled",
 | |
|         true,
 | |
|       ],
 | |
|       ["privacy.trackingprotection.fingerprinting.enabled", false],
 | |
|       ["privacy.trackingprotection.socialtracking.enabled", false],
 | |
|       [
 | |
|         "privacy.trackingprotection.emailtracking.webapp.domains",
 | |
|         "test1.example.com",
 | |
|       ],
 | |
|     ],
 | |
|   });
 | |
| 
 | |
|   await UrlClassifierTestUtils.addTestTrackers();
 | |
| 
 | |
|   registerCleanupFunction(function () {
 | |
|     UrlClassifierTestUtils.cleanupTestTrackers();
 | |
|   });
 | |
| 
 | |
|   await clearTelemetry();
 | |
| });
 | |
| 
 | |
| add_task(async function test_email_tracking_telemetry() {
 | |
|   // Open a non email webapp tab.
 | |
|   await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
 | |
|     // Load a image from the email tracker
 | |
|     let res = await loadImage(browser, EMAIL_TRACKER_IMAGE);
 | |
| 
 | |
|     is(res, false, "The image is blocked.");
 | |
| 
 | |
|     // Verify the telemetry of the email tracker count.
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_BASE_NORMAL,
 | |
|       1
 | |
|     );
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_CONTENT_NORMAL,
 | |
|       0
 | |
|     );
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_BASE_EMAIL_WEBAPP,
 | |
|       0
 | |
|     );
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_CONTENT_EMAIL_WEBAPP,
 | |
|       0
 | |
|     );
 | |
|   });
 | |
| 
 | |
|   // Open an email webapp tab.
 | |
|   await BrowserTestUtils.withNewTab(TEST_EMAIL_WEBAPP_PAGE, async browser => {
 | |
|     // Load a image from the email tracker
 | |
|     let res = await loadImage(browser, EMAIL_TRACKER_IMAGE);
 | |
| 
 | |
|     is(res, false, "The image is blocked.");
 | |
| 
 | |
|     // Verify the telemetry of the email tracker count.
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_BASE_NORMAL,
 | |
|       1
 | |
|     );
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_CONTENT_NORMAL,
 | |
|       0
 | |
|     );
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_BASE_EMAIL_WEBAPP,
 | |
|       1
 | |
|     );
 | |
|     await checkTelemetryProbe(
 | |
|       TELEMETRY_EMAIL_TRACKER_COUNT,
 | |
|       LABEL_CONTENT_EMAIL_WEBAPP,
 | |
|       0
 | |
|     );
 | |
|   });
 | |
|   // Make sure the tab was closed properly before clearing Telemetry.
 | |
|   await BrowserUtils.promiseObserved("window-global-destroyed");
 | |
| 
 | |
|   await clearTelemetry();
 | |
| });
 | |
| 
 | |
| add_task(async function test_no_telemetry_for_first_party_email_tracker() {
 | |
|   // Open a email tracker tab.
 | |
|   await BrowserTestUtils.withNewTab(EMAIL_TRACKER_PAGE, async browser => {
 | |
|     // Load a image from the first-party email tracker
 | |
|     let res = await loadImage(browser, EMAIL_TRACKER_IMAGE);
 | |
| 
 | |
|     is(res, true, "The image is loaded.");
 | |
| 
 | |
|     // Verify that there was no telemetry recorded.
 | |
|     checkNoTelemetryProbe(TELEMETRY_EMAIL_TRACKER_COUNT);
 | |
|   });
 | |
|   // Make sure the tab was closed properly before clearing Telemetry.
 | |
|   await BrowserUtils.promiseObserved("window-global-destroyed");
 | |
| 
 | |
|   await clearTelemetry();
 | |
| });
 | |
| 
 | |
| add_task(async function test_disable_email_data_collection() {
 | |
|   // Disable Email Tracking Data Collection.
 | |
|   await SpecialPowers.pushPrefEnv({
 | |
|     set: [
 | |
|       [
 | |
|         "privacy.trackingprotection.emailtracking.data_collection.enabled",
 | |
|         false,
 | |
|       ],
 | |
|     ],
 | |
|   });
 | |
| 
 | |
|   // Open an email webapp tab.
 | |
|   await BrowserTestUtils.withNewTab(TEST_EMAIL_WEBAPP_PAGE, async browser => {
 | |
|     // Load a image from the email tracker
 | |
|     let res = await loadImage(browser, EMAIL_TRACKER_IMAGE);
 | |
| 
 | |
|     is(res, false, "The image is blocked.");
 | |
| 
 | |
|     // Verify that there was no telemetry recorded.
 | |
|     checkNoTelemetryProbe(TELEMETRY_EMAIL_TRACKER_COUNT);
 | |
|   });
 | |
|   // Make sure the tab was closed properly before clearing Telemetry.
 | |
|   await BrowserUtils.promiseObserved("window-global-destroyed");
 | |
| 
 | |
|   await SpecialPowers.popPrefEnv();
 | |
|   await clearTelemetry();
 | |
| });
 | |
| 
 | |
| add_task(async function test_email_tracker_embedded_telemetry() {
 | |
|   // First, we open a page without loading any email trackers.
 | |
|   await BrowserTestUtils.withNewTab(TEST_PAGE, async _ => {});
 | |
|   // Make sure the tab was closed properly before checking Telemetry.
 | |
|   await BrowserUtils.promiseObserved("window-global-destroyed");
 | |
| 
 | |
|   // Check that the telemetry has been record properly for normal page. The
 | |
|   // telemetry should show there was no email tracker loaded.
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_BASE_NORMAL,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_CONTENT_NORMAL,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_ALL_NORMAL,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
| 
 | |
|   // Second, Open a email webapp tab that doesn't a load email tracker.
 | |
|   await BrowserTestUtils.withNewTab(TEST_EMAIL_WEBAPP_PAGE, async _ => {});
 | |
|   // Make sure the tab was closed properly before checking Telemetry.
 | |
|   await BrowserUtils.promiseObserved("window-global-destroyed");
 | |
| 
 | |
|   // Check that the telemetry has been record properly for the email webapp. The
 | |
|   // telemetry should show there was no email tracker loaded.
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_BASE_EMAILAPP,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_CONTENT_EMAILAPP,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_ALL_EMAILAPP,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
| 
 | |
|   // Third, open a page with one email tracker loaded.
 | |
|   await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
 | |
|     // Load a image from the email tracker
 | |
|     let res = await loadImage(browser, EMAIL_TRACKER_IMAGE);
 | |
| 
 | |
|     is(res, false, "The image is blocked.");
 | |
|   });
 | |
|   // Make sure the tab was closed properly before checking Telemetry.
 | |
|   await BrowserUtils.promiseObserved("window-global-destroyed");
 | |
| 
 | |
|   // Verify that the telemetry has been record properly, The telemetry should
 | |
|   // show there was one base email tracker loaded.
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_BASE_NORMAL,
 | |
|     1,
 | |
|     1
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_CONTENT_NORMAL,
 | |
|     0,
 | |
|     2
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_ALL_NORMAL,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_ALL_NORMAL,
 | |
|     1,
 | |
|     1
 | |
|   );
 | |
| 
 | |
|   // Open a page and load the same email tracker multiple times. There
 | |
|   // should be only one count for the same tracker.
 | |
|   await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
 | |
|     // Load a image from the email tracker two times.
 | |
|     await loadImage(browser, EMAIL_TRACKER_IMAGE);
 | |
|     await loadImage(browser, EMAIL_TRACKER_IMAGE);
 | |
|   });
 | |
|   // Make sure the tab was closed properly before checking Telemetry.
 | |
|   await BrowserUtils.promiseObserved("window-global-destroyed");
 | |
| 
 | |
|   // Verify that there is still only one count when loading the same tracker
 | |
|   // multiple times.
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_BASE_NORMAL,
 | |
|     1,
 | |
|     2
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_CONTENT_NORMAL,
 | |
|     0,
 | |
|     3
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_ALL_NORMAL,
 | |
|     0,
 | |
|     1
 | |
|   );
 | |
|   await checkKeyedHistogram(
 | |
|     TELEMETRY_EMAIL_TRACKER_EMBEDDED_PER_TAB,
 | |
|     KEY_ALL_NORMAL,
 | |
|     1,
 | |
|     2
 | |
|   );
 | |
| 
 | |
|   await clearTelemetry();
 | |
| });
 | 
