Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/**
* Bug 1668199 - Testing the content blocking telemetry.
*/
"use strict";
const { TelemetryTestUtils } = ChromeUtils.importESModule(
);
const LABEL_STORAGE_GRANTED = 0;
const LABEL_STORAGE_ACCESS_API = 1;
const LABEL_OPENER_AFTER_UI = 2;
const LABEL_OPENER = 3;
const LABEL_REDIRECT = 4;
function clearTelemetry() {
Services.telemetry.getSnapshotForHistograms("main", true /* clear */);
Services.telemetry.getHistogramById("STORAGE_ACCESS_REMAINING_DAYS").clear();
}
function getExpectedExpiredDaysFromPref(pref) {
let expiredSecond = Services.prefs.getIntPref(pref);
// This is unlikely to happen, but just in case.
if (expiredSecond <= 0) {
return 0;
}
// We need to subtract one second from the expect expired second because there
// will be a short delay between the time we add the permission and the time
// we record the telemetry. Subtracting one can help us to get the correct
// expected expired days.
//
// Note that 86400 is seconds in one day.
return Math.trunc((expiredSecond - 1) / 86400);
}
async function testTelemetry(
aProbeInParent,
aExpectedCnt,
aLabel,
aExpectedIdx
) {
info("Trigger the 'idle-daily' to trigger the telemetry probe.");
// Synthesis a fake 'idle-daily' notification to the content blocking
// telemetry service.
let cbts = Cc["@mozilla.org/content-blocking-telemetry-service;1"].getService(
Ci.nsIObserver
);
cbts.observe(null, "idle-daily", null);
let storageAccessGrantedHistogram;
// Wait until the telemetry probe appears.
await BrowserTestUtils.waitForCondition(() => {
let histograms;
if (aProbeInParent) {
histograms = Services.telemetry.getSnapshotForHistograms(
"main",
false /* clear */
).parent;
} else {
histograms = Services.telemetry.getSnapshotForHistograms(
"main",
false /* clear */
).content;
}
storageAccessGrantedHistogram = histograms.STORAGE_ACCESS_GRANTED_COUNT;
return (
!!storageAccessGrantedHistogram &&
storageAccessGrantedHistogram.values[LABEL_STORAGE_GRANTED] ==
aExpectedCnt
);
});
is(
storageAccessGrantedHistogram.values[LABEL_STORAGE_GRANTED],
aExpectedCnt,
"There should be expected storage access granted count in telemetry."
);
is(
storageAccessGrantedHistogram.values[aLabel],
1,
"There should be one reason count in telemetry."
);
let storageAccessRemainingDaysHistogram = Services.telemetry.getHistogramById(
"STORAGE_ACCESS_REMAINING_DAYS"
);
TelemetryTestUtils.assertHistogram(
storageAccessRemainingDaysHistogram,
aExpectedIdx,
1
);
// Clear telemetry probes
clearTelemetry();
}
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [
["network.cookie.cookieBehavior", BEHAVIOR_REJECT_TRACKER],
["network.cookie.cookieBehavior.pbmode", BEHAVIOR_REJECT_TRACKER],
["privacy.trackingprotection.annotate_channels", true],
[
"privacy.restrict3rdpartystorage.userInteractionRequiredForHosts",
"tracking.example.com,tracking.example.org",
],
["privacy.restrict3rdpartystorage.heuristic.redirect", true],
["toolkit.telemetry.ipcBatchTimeout", 0],
// Explicity set the expiration time to 29 days to avoid an intermittent
// issue that we could get 30 days of expiration time if we test the
// telemetry too soon.
["privacy.restrict3rdpartystorage.expiration", 2591999],
["privacy.restrict3rdpartystorage.expiration_redirect", 2591999],
],
});
// Clear Telemetry probes before testing.
// There can be telemetry race conditions if the previous test generates
// content blocking telemetry.
clearTelemetry();
await UrlClassifierTestUtils.addTestTrackers();
registerCleanupFunction(_ => {
Services.perms.removeAll();
});
});
add_task(async function testTelemetryForStorageAccessAPI() {
info("Starting testing if storage access API send telemetry probe ...");
// First, clear all permissions.
Services.perms.removeAll();
info("Creating a new tab");
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
info("Loading the tracking iframe and call the RequestStorageAccess.");
await SpecialPowers.spawn(
browser,
[
{
page: TEST_3RD_PARTY_PAGE_UI,
},
],
async obj => {
let msg = {};
msg.callback = (async _ => {
/* import-globals-from storageAccessAPIHelpers.js */
await callRequestStorageAccess();
}).toString();
await new content.Promise(resolve => {
let ifr = content.document.createElement("iframe");
ifr.onload = function () {
info("Sending code to the 3rd party content");
ifr.contentWindow.postMessage(msg, "*");
};
content.addEventListener("message", function msg(event) {
if (event.data.type == "finish") {
content.removeEventListener("message", msg);
resolve();
return;
}
if (event.data.type == "ok") {
ok(event.data.what, event.data.msg);
return;
}
if (event.data.type == "info") {
info(event.data.msg);
return;
}
ok(false, "Unknown message");
});
content.document.body.appendChild(ifr);
ifr.src = obj.page;
});
}
);
info("Removing the tab");
BrowserTestUtils.removeTab(tab);
let expectedExpiredDays = getExpectedExpiredDaysFromPref(
"privacy.restrict3rdpartystorage.expiration"
);
// The storage access permission will be expired in 29 days, so the expected
// index in the telemetry probe would be 29.
await testTelemetry(false, 1, LABEL_STORAGE_ACCESS_API, expectedExpiredDays);
});
add_task(async function testTelemetryForWindowOpenHeuristic() {
info("Starting testing if window open heuristic send telemetry probe ...");
// First, clear all permissions.
Services.perms.removeAll();
info("Creating a new tab");
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
info("Loading the tracking iframe and trigger the heuristic");
await SpecialPowers.spawn(
browser,
[
{
page: TEST_3RD_PARTY_PAGE_WO,
},
],
async obj => {
let msg = {};
msg.blockingCallback = (async _ => {
/* import-globals-from storageAccessAPIHelpers.js */
await noStorageAccessInitially();
}).toString();
msg.nonBlockingCallback = (async _ => {
/* import-globals-from storageAccessAPIHelpers.js */
await hasStorageAccessInitially();
}).toString();
info("Checking if storage access is denied");
await new content.Promise(resolve => {
let ifr = content.document.createElement("iframe");
ifr.onload = function () {
info("Sending code to the 3rd party content");
ifr.contentWindow.postMessage(msg, "*");
};
content.addEventListener("message", function msg(event) {
if (event.data.type == "finish") {
content.removeEventListener("message", msg);
resolve();
return;
}
if (event.data.type == "ok") {
ok(event.data.what, event.data.msg);
return;
}
if (event.data.type == "info") {
info(event.data.msg);
return;
}
ok(false, "Unknown message");
});
content.document.body.appendChild(ifr);
ifr.src = obj.page;
});
}
);
info("Removing the tab");
BrowserTestUtils.removeTab(tab);
let expectedExpiredDays = getExpectedExpiredDaysFromPref(
"privacy.restrict3rdpartystorage.expiration"
);
// The storage access permission will be expired in 29 days, so the expected
// index in the telemetry probe would be 29.
await testTelemetry(false, 1, LABEL_OPENER, expectedExpiredDays);
});
add_task(async function testTelemetryForUserInteractionHeuristic() {
info(
"Starting testing if UserInteraction heuristic send telemetry probe ..."
);
// First, clear all permissions.
Services.perms.removeAll();
info("Creating a new tab");
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
info("Interact with the tracker in top-level.");
await AntiTracking.interactWithTracker();
info("Loading the tracking iframe and trigger the heuristic");
await SpecialPowers.spawn(
browser,
[
{
page: TEST_3RD_PARTY_PAGE_UI,
popup: TEST_POPUP_PAGE,
},
],
async obj => {
let msg = {};
msg.blockingCallback = (async _ => {
await noStorageAccessInitially();
}).toString();
msg.nonBlockingCallback = (async _ => {
/* import-globals-from storageAccessAPIHelpers.js */
await hasStorageAccessInitially();
}).toString();
let ifr = content.document.createElement("iframe");
let loading = new content.Promise(resolve => {
ifr.onload = resolve;
});
content.document.body.appendChild(ifr);
ifr.src = obj.page;
await loading;
info("Opening a window from the iframe.");
await SpecialPowers.spawn(ifr, [obj.popup], async popup => {
let windowClosed = new content.Promise(resolve => {
Services.ww.registerNotification(function notification(
aSubject,
aTopic
) {
// We need to check the document URI here as well for the same
// reason above.
if (
aTopic == "domwindowclosed" &&
aSubject.document.documentURI ==
) {
Services.ww.unregisterNotification(notification);
resolve();
}
});
});
content.open(popup);
info("Let's wait for the window to be closed");
await windowClosed;
});
}
);
info("Removing the tab");
BrowserTestUtils.removeTab(tab);
let expectedExpiredDays = getExpectedExpiredDaysFromPref(
"privacy.restrict3rdpartystorage.expiration"
);
// The storage access permission will be expired in 29 days, so the expected
// index in the telemetry probe would be 29.
//
// Note that the expected count here is 2. It's because the opener heuristic
// will also be triggered when triggered UserInteraction Heuristic.
await testTelemetry(false, 2, LABEL_OPENER_AFTER_UI, expectedExpiredDays);
});
add_task(async function testTelemetryForRedirectHeuristic() {
info("Starting testing if redirect heuristic send telemetry probe ...");
const TEST_TRACKING_PAGE = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "page.html";
const TEST_REDIRECT_PAGE =
TEST_3RD_PARTY_DOMAIN + TEST_PATH + "redirect.sjs?" + TEST_TOP_PAGE;
// First, clear all permissions.
Services.perms.removeAll();
info("Creating a new tab");
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TRACKING_PAGE);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
info("Loading the tracking page and trigger the redirect.");
SpecialPowers.spawn(browser, [TEST_REDIRECT_PAGE], async url => {
content.document.userInteractionForTesting();
let link = content.document.createElement("a");
link.appendChild(content.document.createTextNode("click me!"));
link.href = url;
content.document.body.appendChild(link);
link.click();
});
await BrowserTestUtils.browserLoaded(browser, false, TEST_TOP_PAGE);
info("Removing the tab");
BrowserTestUtils.removeTab(tab);
let expectedExpiredDaysRedirect = getExpectedExpiredDaysFromPref(
"privacy.restrict3rdpartystorage.expiration_redirect"
);
// We would only grant the storage permission for 29 days for the redirect
// heuristic, so the expected index in the telemetry probe would be 29.
await testTelemetry(true, 1, LABEL_REDIRECT, expectedExpiredDaysRedirect);
});