Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

/* Any copyright is dedicated to the Public Domain.
"use strict";
requestLongerTimeout(2);
/**
* Bug 1863280 - Testing the fingerprinting category of the protection panel
* shows the suspicious fingerpinter domain if the fingerprinting
* protection is enabled
*/
const TEST_PATH = getRootDirectory(gTestPath).replace(
""
);
const TEST_DOMAIN = "https://www.example.com";
const TEST_3RD_DOMAIN = "https://example.org";
const TEST_PAGE = TEST_DOMAIN + TEST_PATH + "benignPage.html";
const TEST_3RD_CANVAS_FP_PAGE =
TEST_3RD_DOMAIN + TEST_PATH + "canvas-fingerprinter.html";
const TEST_3RD_FONT_FP_PAGE =
TEST_3RD_DOMAIN + TEST_PATH + "font-fingerprinter.html";
const FINGERPRINT_BLOCKING_PREF =
"privacy.trackingprotection.fingerprinting.enabled";
const FINGERPRINT_PROTECTION_PREF = "privacy.fingerprintingProtection";
const FINGERPRINT_PROTECTION_PBM_PREF =
"privacy.fingerprintingProtection.pbmode";
/**
* A helper function to check whether or not an element has "notFound" class.
*
* @param {String} id The id of the testing element.
* @returns {Boolean} true when the element has "notFound" class.
*/
function notFound(id) {
return document.getElementById(id).classList.contains("notFound");
}
/**
* A helper function to wait until the suspicious fingerprinting content
* blocking event is dispatched.
*
* @param {Window} win The window to listen content blocking events.
* @returns {Promise} A promise that resolves when the event files.
*/
async function waitForSuspiciousFingerprintingEvent(win) {
return new Promise(resolve => {
let listener = {
onContentBlockingEvent(webProgress, request, event) {
info(`Received onContentBlockingEvent event: ${event}`);
if (
event &
Ci.nsIWebProgressListener.STATE_BLOCKED_SUSPICIOUS_FINGERPRINTING
) {
win.gBrowser.removeProgressListener(listener);
resolve();
}
},
};
win.gBrowser.addProgressListener(listener);
});
}
/**
* A helper function that opens a tests page that embeds iframes with given
* urls.
*
* @param {string[]} urls An array of urls that will be embedded in the test page.
* @param {boolean} usePrivateWin true to indicate testing in a private window.
* @param {Function} testFn The test function that will be called after the
* iframes have been loaded.
*/
async function openTestPage(urls, usePrivateWin, testFn) {
let win = window;
if (usePrivateWin) {
win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
}
await BrowserTestUtils.withNewTab(
{ gBrowser: win.gBrowser, url: TEST_PAGE },
async browser => {
info("Loading all iframes");
for (const url of urls) {
await SpecialPowers.spawn(browser, [url], async testUrl => {
await new content.Promise(resolve => {
let ifr = content.document.createElement("iframe");
ifr.onload = resolve;
content.document.body.appendChild(ifr);
ifr.src = testUrl;
});
});
}
info("Running the test");
await testFn(win, browser);
}
);
if (usePrivateWin) {
await BrowserTestUtils.closeWindow(win);
}
}
/**
* A testing function verifies that fingerprinting category is not shown.
*
* @param {*} win The window to run the test.
*/
async function testCategoryNotShown(win) {
await openProtectionsPanel(false, win);
let categoryItem = win.document.getElementById(
"protections-popup-category-fingerprinters"
);
// The fingerprinting category should have the 'notFound' class to indicate
// that no fingerprinter was found in the page.
ok(
notFound("protections-popup-category-fingerprinters"),
"Fingerprinting category is not found"
);
ok(
!BrowserTestUtils.isVisible(categoryItem),
"Fingerprinting category item is not visible"
);
await closeProtectionsPanel(win);
}
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [[FINGERPRINT_BLOCKING_PREF, true]],
});
});
// Verify that fingerprinting category is not shown if fingerprinting protection
// is disabled.
add_task(async function testFPPDisabled() {
await SpecialPowers.pushPrefEnv({
set: [[FINGERPRINT_PROTECTION_PREF, false]],
});
await openTestPage(
[TEST_3RD_CANVAS_FP_PAGE, TEST_3RD_FONT_FP_PAGE],
false,
testCategoryNotShown
);
});
// Verify that fingerprinting category is not shown if no fingerprinting
// activity is detected.
add_task(async function testFPPEnabledWithoutFingerprintingActivity() {
await SpecialPowers.pushPrefEnv({
set: [[FINGERPRINT_PROTECTION_PREF, true]],
});
// Test the case where the page doesn't load any fingerprinter.
await openTestPage([], false, testCategoryNotShown);
// Test the case where the page loads only one fingerprinter. We don't treat
// this case as suspicious fingerprinting.
await openTestPage([TEST_3RD_FONT_FP_PAGE], false, testCategoryNotShown);
// Test the case where the page loads the same fingerprinter multiple times.
// We don't treat this case as suspicious fingerprinting.
await openTestPage(
[TEST_3RD_FONT_FP_PAGE, TEST_3RD_FONT_FP_PAGE],
false,
testCategoryNotShown
);
});
// Verify that fingerprinting category is not shown if no fingerprinting
// activity is detected.
add_task(
async function testFPPEnabledWithoutSuspiciousFingerprintingActivity() {
await SpecialPowers.pushPrefEnv({
set: [[FINGERPRINT_PROTECTION_PREF, true]],
});
// Test the case where the page doesn't load any fingerprinter.
await openTestPage([], false, testCategoryNotShown);
// Test the case where the page loads only one fingerprinter. We don't treat
// this case as suspicious fingerprinting.
await openTestPage([TEST_3RD_FONT_FP_PAGE], false, testCategoryNotShown);
// Test the case where the page loads the same fingerprinter multiple times.
// We don't treat this case as suspicious fingerprinting.
await openTestPage(
[TEST_3RD_FONT_FP_PAGE, TEST_3RD_FONT_FP_PAGE],
false,
testCategoryNotShown
);
}
);
// Verify that fingerprinting category is properly shown and the fingerprinting
// subview displays the origin of the suspicious fingerprinter.
add_task(async function testFingerprintingSubview() {
await SpecialPowers.pushPrefEnv({
set: [[FINGERPRINT_PROTECTION_PREF, true]],
});
await openTestPage(
[TEST_3RD_CANVAS_FP_PAGE, TEST_3RD_FONT_FP_PAGE],
false,
async (win, _) => {
await openProtectionsPanel(false, win);
let categoryItem = win.document.getElementById(
"protections-popup-category-fingerprinters"
);
// Explicitly waiting for the category item becoming visible.
await BrowserTestUtils.waitForMutationCondition(categoryItem, {}, () =>
BrowserTestUtils.isVisible(categoryItem)
);
ok(
BrowserTestUtils.isVisible(categoryItem),
"Fingerprinting category item is visible"
);
// Click the fingerprinting category and wait until the fingerprinter view is
// shown.
let fingerprintersView = win.document.getElementById(
"protections-popup-fingerprintersView"
);
let viewShown = BrowserTestUtils.waitForEvent(
fingerprintersView,
"ViewShown"
);
categoryItem.click();
await viewShown;
ok(true, "Fingerprinter view was shown");
// Ensure the fingerprinter is listed on the tracker list.
let listItems = Array.from(
fingerprintersView.querySelectorAll(".protections-popup-list-item")
);
is(listItems.length, 1, "We have 1 fingerprinter in the list");
let listItem = listItems.find(
item => item.querySelector("label").value == "https://example.org"
);
ok(listItem, "Has an item for example.org");
ok(BrowserTestUtils.isVisible(listItem), "List item is visible");
// Back to the popup main view.
let mainView = win.document.getElementById("protections-popup-mainView");
viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
let backButton = fingerprintersView.querySelector(".subviewbutton-back");
backButton.click();
await viewShown;
ok(true, "Main view was shown");
await closeProtectionsPanel(win);
}
);
});
// Verify the case where the fingerprinting protection is only enabled in PBM.
add_task(async function testFingerprintingSubviewInPBM() {
// Only enabled fingerprinting protection in PBM.
await SpecialPowers.pushPrefEnv({
set: [
[FINGERPRINT_PROTECTION_PREF, false],
[FINGERPRINT_PROTECTION_PBM_PREF, true],
],
});
// Verify that fingerprinting category isn't shown on a normal window.
await openTestPage(
[TEST_3RD_CANVAS_FP_PAGE, TEST_3RD_FONT_FP_PAGE],
false,
testCategoryNotShown
);
// Verify that fingerprinting category is shown on a private window.
await openTestPage(
[TEST_3RD_CANVAS_FP_PAGE, TEST_3RD_FONT_FP_PAGE],
true,
async (win, _) => {
await openProtectionsPanel(false, win);
let categoryItem = win.document.getElementById(
"protections-popup-category-fingerprinters"
);
// Explicitly waiting for the category item becoming visible.
await BrowserTestUtils.waitForMutationCondition(categoryItem, {}, () =>
BrowserTestUtils.isVisible(categoryItem)
);
ok(
BrowserTestUtils.isVisible(categoryItem),
"Fingerprinting category item is visible"
);
// Click the fingerprinting category and wait until the fingerprinter view is
// shown.
let fingerprintersView = win.document.getElementById(
"protections-popup-fingerprintersView"
);
let viewShown = BrowserTestUtils.waitForEvent(
fingerprintersView,
"ViewShown"
);
categoryItem.click();
await viewShown;
ok(true, "Fingerprinter view was shown");
// Ensure the fingerprinter is listed on the tracker list.
let listItems = Array.from(
fingerprintersView.querySelectorAll(".protections-popup-list-item")
);
is(listItems.length, 1, "We have 1 fingerprinter in the list");
let listItem = listItems.find(
item => item.querySelector("label").value == "https://example.org"
);
ok(listItem, "Has an item for example.org");
ok(BrowserTestUtils.isVisible(listItem), "List item is visible");
// Back to the popup main view.
let mainView = win.document.getElementById("protections-popup-mainView");
viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
let backButton = fingerprintersView.querySelector(".subviewbutton-back");
backButton.click();
await viewShown;
ok(true, "Main view was shown");
await closeProtectionsPanel(win);
}
);
});
// Verify that fingerprinting category will be shown after loading
// fingerprinters.
add_task(async function testDynamicallyLoadFingerprinter() {
await SpecialPowers.pushPrefEnv({
set: [[FINGERPRINT_PROTECTION_PREF, true]],
});
await openTestPage([TEST_3RD_FONT_FP_PAGE], false, async (win, browser) => {
await openProtectionsPanel(false, win);
let categoryItem = win.document.getElementById(
"protections-popup-category-fingerprinters"
);
// The fingerprinting category should have the 'notFound' class to indicate
// that no suspicious fingerprinter was found in the page.
ok(
notFound("protections-popup-category-fingerprinters"),
"Fingerprinting category is not found"
);
ok(
!BrowserTestUtils.isVisible(categoryItem),
"Fingerprinting category item is not visible"
);
// Add an iframe that triggers suspicious fingerprinting and wait until the
// content event files.
let contentBlockingEventPromise = waitForSuspiciousFingerprintingEvent(win);
await SpecialPowers.spawn(browser, [TEST_3RD_CANVAS_FP_PAGE], test_url => {
let ifr = content.document.createElement("iframe");
content.document.body.appendChild(ifr);
ifr.src = test_url;
});
await contentBlockingEventPromise;
// Click the fingerprinting category and wait until the fingerprinter view
// is shown.
let fingerprintersView = win.document.getElementById(
"protections-popup-fingerprintersView"
);
let viewShown = BrowserTestUtils.waitForEvent(
fingerprintersView,
"ViewShown"
);
categoryItem.click();
await viewShown;
ok(true, "Fingerprinter view was shown");
// Ensure the fingerprinter is listed on the tracker list.
let listItems = Array.from(
fingerprintersView.querySelectorAll(".protections-popup-list-item")
);
is(listItems.length, 1, "We have 1 fingerprinter in the list");
let listItem = listItems.find(
item => item.querySelector("label").value == "https://example.org"
);
ok(listItem, "Has an item for example.org");
ok(BrowserTestUtils.isVisible(listItem), "List item is visible");
// Back to the popup main view.
let mainView = win.document.getElementById("protections-popup-mainView");
viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
let backButton = fingerprintersView.querySelector(".subviewbutton-back");
backButton.click();
await viewShown;
ok(true, "Main view was shown");
await closeProtectionsPanel(win);
});
});