Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* 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(
);
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();
});