summaryrefslogtreecommitdiffstats
path: root/toolkit/components/url-classifier/tests/browser
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/components/url-classifier/tests/browser/browser.ini6
-rw-r--r--toolkit/components/url-classifier/tests/browser/browser_emailtracking_telemetry.js423
-rw-r--r--toolkit/components/url-classifier/tests/browser/page.html8
-rw-r--r--toolkit/components/url-classifier/tests/browser/raptor.jpgbin0 -> 49629 bytes
4 files changed, 437 insertions, 0 deletions
diff --git a/toolkit/components/url-classifier/tests/browser/browser.ini b/toolkit/components/url-classifier/tests/browser/browser.ini
new file mode 100644
index 0000000000..7368169b3f
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+support-files =
+ page.html
+ raptor.jpg
+
+[browser_emailtracking_telemetry.js]
diff --git a/toolkit/components/url-classifier/tests/browser/browser_emailtracking_telemetry.js b/toolkit/components/url-classifier/tests/browser/browser_emailtracking_telemetry.js
new file mode 100644
index 0000000000..086ca49afe
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/browser_emailtracking_telemetry.js
@@ -0,0 +1,423 @@
+/* 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();
+});
diff --git a/toolkit/components/url-classifier/tests/browser/page.html b/toolkit/components/url-classifier/tests/browser/page.html
new file mode 100644
index 0000000000..a99e8be179
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/page.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+ <title>Just a top-level page</title>
+</head>
+<body>
+ <h1>This is the top-level page</h1>
+</body>
+</html>
diff --git a/toolkit/components/url-classifier/tests/browser/raptor.jpg b/toolkit/components/url-classifier/tests/browser/raptor.jpg
new file mode 100644
index 0000000000..243ba9e2d4
--- /dev/null
+++ b/toolkit/components/url-classifier/tests/browser/raptor.jpg
Binary files differ