Bug 1699668 - Tests for shim warning. r=webcompat-reviewers,johannh,denschub

Differential Revision: https://phabricator.services.mozilla.com/D109718
This commit is contained in:
Paul Zuehlcke 2021-04-13 16:11:21 +00:00
Родитель 58eba8e1ac
Коммит 522131845a
18 изменённых файлов: 533 добавлений и 24 удалений

Просмотреть файл

@ -40,3 +40,4 @@ support-files =
[browser_protectionsUI_state_reset.js]
[browser_protectionsUI_telemetry.js]
[browser_protectionsUI_trackers_subview.js]
[browser_protectionsUI_subview_shim.js]

Просмотреть файл

@ -617,7 +617,7 @@ add_task(async function testNumberOfBlockedTrackers() {
add_task(async function testSubViewTelemetry() {
let items = [
["protections-popup-category-tracking-protection", "trackers"],
["protections-popup-category-trackers", "trackers"],
["protections-popup-category-socialblock", "social"],
["protections-popup-category-cookies", "cookies"],
["protections-popup-category-cryptominers", "cryptominers"],

Просмотреть файл

@ -15,8 +15,13 @@ registerCleanupFunction(function() {
});
add_task(async function testNormalBrowsing() {
let TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
ok(TrackingProtection, "TP is attached to the browser window");
let {
TrackingProtection,
} = gBrowser.ownerGlobal.gProtectionsHandler.blockers;
ok(
TrackingProtection,
"Normal window gProtectionsHandler should have TrackingProtection blocker."
);
Services.prefs.setBoolPref(PREF, true);
Services.prefs.setBoolPref(PB_PREF, false);
@ -35,8 +40,13 @@ add_task(async function testPrivateBrowsing() {
let privateWin = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
let TrackingProtection = privateWin.gBrowser.ownerGlobal.TrackingProtection;
ok(TrackingProtection, "TP is attached to the browser window");
let {
TrackingProtection,
} = privateWin.gBrowser.ownerGlobal.gProtectionsHandler.blockers;
ok(
TrackingProtection,
"Private window gProtectionsHandler should have TrackingProtection blocker."
);
Services.prefs.setBoolPref(PREF, true);
Services.prefs.setBoolPref(PB_PREF, false);

Просмотреть файл

@ -212,9 +212,13 @@ add_task(async function testNormalBrowsing() {
gProtectionsHandler,
"gProtectionsHandler is attached to the browser window"
);
let TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
let {
TrackingProtection,
} = gBrowser.ownerGlobal.gProtectionsHandler.blockers;
ok(TrackingProtection, "TP is attached to the browser window");
let ThirdPartyCookies = gBrowser.ownerGlobal.ThirdPartyCookies;
let { ThirdPartyCookies } = gBrowser.ownerGlobal.gProtectionsHandler.blockers;
ok(ThirdPartyCookies, "TPC is attached to the browser window");
Services.prefs.setBoolPref(TP_PREF, true);
@ -242,9 +246,13 @@ add_task(async function testPrivateBrowsing() {
gProtectionsHandler,
"gProtectionsHandler is attached to the private window"
);
let TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
let {
TrackingProtection,
} = tabbrowser.ownerGlobal.gProtectionsHandler.blockers;
ok(TrackingProtection, "TP is attached to the private window");
let ThirdPartyCookies = tabbrowser.ownerGlobal.ThirdPartyCookies;
let {
ThirdPartyCookies,
} = tabbrowser.ownerGlobal.gProtectionsHandler.blockers;
ok(ThirdPartyCookies, "TPC is attached to the browser window");
Services.prefs.setBoolPref(TP_PB_PREF, true);

Просмотреть файл

@ -182,7 +182,7 @@ add_task(async function testCategorySections() {
await closeProtectionsPanel();
let categoryItems = [
"protections-popup-category-tracking-protection",
"protections-popup-category-trackers",
"protections-popup-category-socialblock",
"protections-popup-category-cookies",
"protections-popup-category-cryptominers",
@ -234,7 +234,7 @@ add_task(async function testCategorySections() {
*/
add_task(async function testCategorySectionInitial() {
let categoryItems = [
"protections-popup-category-tracking-protection",
"protections-popup-category-trackers",
"protections-popup-category-socialblock",
"protections-popup-category-cookies",
"protections-popup-category-cryptominers",

Просмотреть файл

@ -153,6 +153,11 @@ async function testSubview(hasException) {
categoryItem.click();
await viewShown;
let trackersViewShimHint = document.getElementById(
"protections-popup-cryptominersView-shim-allow-hint"
);
ok(trackersViewShimHint.hidden, "Shim hint is hidden");
let listItems = subview.querySelectorAll(".protections-popup-list-item");
is(listItems.length, 1, "We have 1 item in the list");
let listItem = listItems[0];

Просмотреть файл

@ -228,6 +228,11 @@ async function testSubview(hasException) {
categoryItem.click();
await viewShown;
let trackersViewShimHint = document.getElementById(
"protections-popup-fingerprintersView-shim-allow-hint"
);
ok(trackersViewShimHint.hidden, "Shim hint is hidden");
let listItems = subview.querySelectorAll(".protections-popup-list-item");
is(listItems.length, 1, "We have 1 item in the list");
let listItem = listItems[0];

Просмотреть файл

@ -67,7 +67,7 @@ add_task(async function testOpenPreferencesFromTrackersSubview() {
await openProtectionsPanel();
let categoryItem = document.getElementById(
"protections-popup-category-tracking-protection"
"protections-popup-category-trackers"
);
// Explicitly waiting for the category item becoming visible.

Просмотреть файл

@ -91,7 +91,9 @@ add_task(async function testExceptionAddition() {
gProtectionsHandler = browser.ownerGlobal.gProtectionsHandler;
ok(gProtectionsHandler, "CB is attached to the private window");
TrackingProtection = browser.ownerGlobal.TrackingProtection;
TrackingProtection =
browser.ownerGlobal.gProtectionsHandler.blockers.TrackingProtection;
ok(TrackingProtection, "TP is attached to the private window");
Services.prefs.setBoolPref(TP_PB_PREF, true);
@ -135,7 +137,8 @@ add_task(async function testExceptionPersistence() {
gProtectionsHandler = browser.ownerGlobal.gProtectionsHandler;
ok(gProtectionsHandler, "CB is attached to the private window");
TrackingProtection = browser.ownerGlobal.TrackingProtection;
TrackingProtection =
browser.ownerGlobal.gProtectionsHandler.blockers.TrackingProtection;
ok(TrackingProtection, "TP is attached to the private window");
ok(TrackingProtection.enabled, "TP is still enabled");

Просмотреть файл

@ -159,6 +159,11 @@ async function testSubview(hasException) {
categoryItem.click();
await viewShown;
let trackersViewShimHint = document.getElementById(
"protections-popup-socialblockView-shim-allow-hint"
);
ok(trackersViewShimHint.hidden, "Shim hint is hidden");
let listItems = subview.querySelectorAll(".protections-popup-list-item");
is(listItems.length, 1, "We have 1 item in the list");
let listItem = listItems[0];

Просмотреть файл

@ -88,7 +88,7 @@ async function testBenignPage() {
"Cookie restrictions category is not found"
);
ok(
notFound("protections-popup-category-tracking-protection"),
notFound("protections-popup-category-trackers"),
"Trackers category is not found"
);
await closeProtectionsPanel(win);
@ -125,7 +125,7 @@ async function testBenignPageWithException() {
"Cookie restrictions category is not found"
);
ok(
notFound("protections-popup-category-tracking-protection"),
notFound("protections-popup-category-trackers"),
"Trackers category is not found"
);
await closeProtectionsPanel(win);
@ -170,7 +170,7 @@ async function testTrackingPage(window) {
await openProtectionsPanel(false, window);
ok(
!notFound("protections-popup-category-tracking-protection"),
!notFound("protections-popup-category-trackers"),
"Trackers category is detected"
);
if (gTrackingPageURL == COOKIE_PAGE) {
@ -213,7 +213,7 @@ async function testTrackingPageUnblocked(blockedByTP, window) {
await openProtectionsPanel(false, window);
ok(
!notFound("protections-popup-category-tracking-protection"),
!notFound("protections-popup-category-trackers"),
"Trackers category is detected"
);
if (gTrackingPageURL == COOKIE_PAGE) {
@ -284,7 +284,9 @@ add_task(async function testNormalBrowsing() {
gProtectionsHandler,
"gProtectionsHandler is attached to the browser window"
);
TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
TrackingProtection =
gBrowser.ownerGlobal.gProtectionsHandler.blockers.TrackingProtection;
ok(TrackingProtection, "TP is attached to the browser window");
is(
TrackingProtection.enabled,
@ -323,7 +325,9 @@ add_task(async function testPrivateBrowsing() {
gProtectionsHandler,
"gProtectionsHandler is attached to the private window"
);
TrackingProtection = tabbrowser.ownerGlobal.TrackingProtection;
TrackingProtection =
tabbrowser.ownerGlobal.gProtectionsHandler.blockers.TrackingProtection;
ok(TrackingProtection, "TP is attached to the private window");
is(
TrackingProtection.enabled,
@ -355,7 +359,8 @@ add_task(async function testThirdPartyCookies() {
gProtectionsHandler,
"gProtectionsHandler is attached to the browser window"
);
ThirdPartyCookies = gBrowser.ownerGlobal.ThirdPartyCookies;
ThirdPartyCookies =
gBrowser.ownerGlobal.gProtectionsHandler.blockers.ThirdPartyCookies;
ok(ThirdPartyCookies, "TP is attached to the browser window");
is(
ThirdPartyCookies.enabled,

Просмотреть файл

@ -0,0 +1,399 @@
/* eslint-disable mozilla/no-arbitrary-setTimeout */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests the warning and list indicators that are shown in the protections panel
* subview when a tracking channel is allowed via the
* "urlclassifier-before-block-channel" event.
*/
// Choose origin so that all tracking origins used are third-parties.
const TRACKING_PAGE =
"http://example.net/browser/browser/base/content/test/protectionsUI/trackingPage.html";
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [
["privacy.trackingprotection.enabled", true],
["privacy.trackingprotection.annotate_channels", true],
["privacy.trackingprotection.cryptomining.enabled", true],
["privacy.trackingprotection.socialtracking.enabled", true],
["privacy.trackingprotection.fingerprinting.enabled", true],
["privacy.socialtracking.block_cookies.enabled", true],
// Allowlist trackertest.org loaded by default in trackingPage.html
["urlclassifier.trackingSkipURLs", "trackertest.org"],
["urlclassifier.trackingAnnotationSkipURLs", "trackertest.org"],
// Additional denylisted hosts.
[
"urlclassifier.trackingAnnotationTable.testEntries",
"tracking.example.com",
],
[
"urlclassifier.features.cryptomining.blacklistHosts",
"cryptomining.example.com",
],
[
"urlclassifier.features.cryptomining.annotate.blacklistHosts",
"cryptomining.example.com",
],
[
"urlclassifier.features.fingerprinting.blacklistHosts",
"fingerprinting.example.com",
],
[
"urlclassifier.features.fingerprinting.annotate.blacklistHosts",
"fingerprinting.example.com",
],
],
});
await UrlClassifierTestUtils.addTestTrackers();
registerCleanupFunction(() => {
UrlClassifierTestUtils.cleanupTestTrackers();
});
});
async function assertSubViewState(category, expectedState) {
await openProtectionsPanel();
// Sort the expected state by origin and transform it into an array.
let expectedStateSorted = Object.keys(expectedState)
.sort()
.reduce((stateArr, key) => {
let obj = expectedState[key];
obj.origin = key;
stateArr.push(obj);
return stateArr;
}, []);
if (!expectedStateSorted.length) {
ok(
BrowserTestUtils.is_visible(
document.getElementById(
"protections-popup-no-trackers-found-description"
)
),
"No Trackers detected should be shown"
);
return;
}
let categoryItem = document.getElementById(
`protections-popup-category-${category}`
);
// Explicitly waiting for the category item becoming visible.
await TestUtils.waitForCondition(() => {
return BrowserTestUtils.is_visible(categoryItem);
});
ok(
BrowserTestUtils.is_visible(categoryItem),
`${category} category item is visible`
);
ok(!categoryItem.disabled, `${category} category item is enabled`);
let subView = document.getElementById(`protections-popup-${category}View`);
let viewShown = BrowserTestUtils.waitForEvent(subView, "ViewShown");
categoryItem.click();
await viewShown;
ok(true, `${category} subView was shown`);
info("Testing tracker list");
// Get the listed trackers in the UI and sort them by origin.
let items = Array.from(
subView.querySelectorAll(
`#protections-popup-${category}View-list .protections-popup-list-item`
)
).sort((a, b) => {
let originA = a.querySelector("label").value;
let originB = b.querySelector("label").value;
return originA.localeCompare(originB);
});
is(
items.length,
expectedStateSorted.length,
"List has expected amount of entries"
);
for (let i = 0; i < expectedStateSorted.length; i += 1) {
let expected = expectedStateSorted[i];
let item = items[i];
let label = item.querySelector(".protections-popup-list-host-label");
ok(label, "Item has label.");
is(label.tooltipText, expected.origin, "Label has correct tooltip.");
is(label.value, expected.origin, "Label has correct text.");
is(
item.classList.contains("allowed"),
!expected.block,
"Item has allowed class if tracker is not blocked"
);
let shimAllowIndicator = item.querySelector(
".protections-popup-list-host-shim-allow-indicator"
);
if (expected.shimAllow) {
is(item.childNodes.length, 2, "Item has two childNodes.");
ok(shimAllowIndicator, "Item has shim allow indicator icon.");
ok(
shimAllowIndicator.tooltipText,
"Shim allow indicator icon has tooltip text"
);
} else {
is(item.childNodes.length, 1, "Item has one childNode.");
ok(!shimAllowIndicator, "Item does not have shim allow indicator icon.");
}
}
let shimAllowSection = document.getElementById(
`protections-popup-${category}View-shim-allow-hint`
);
ok(shimAllowSection, `Category ${category} has shim-allow hint.`);
if (Object.values(expectedState).some(entry => entry.shimAllow)) {
BrowserTestUtils.is_visible(
shimAllowSection,
"Shim allow hint is visible."
);
} else {
BrowserTestUtils.is_hidden(shimAllowSection, "Shim allow hint is hidden.");
}
await closeProtectionsPanel();
}
async function runTestForCategoryAndState(category, action) {
// Maps the protection categories to the test tracking origins defined in
// ./trackingAPI.js and the UI class identifiers to look for in the
// protections UI.
let categoryToTestData = {
tracking: {
apiMessage: "more-tracking",
origin: "https://itisatracker.org",
elementId: "trackers",
},
socialtracking: {
origin: "https://social-tracking.example.org",
elementId: "socialblock",
},
cryptomining: {
origin: "http://cryptomining.example.com",
elementId: "cryptominers",
},
fingerprinting: {
origin: "https://fingerprinting.example.com",
elementId: "fingerprinters",
},
};
let promise = BrowserTestUtils.openNewForegroundTab({
url: TRACKING_PAGE,
gBrowser,
});
// Wait for the tab to load and the initial blocking events from the
// classifier.
let [tab] = await Promise.all([promise, waitForContentBlockingEvent()]);
let {
origin: trackingOrigin,
elementId: categoryElementId,
apiMessage,
} = categoryToTestData[category];
if (!apiMessage) {
apiMessage = category;
}
// For allow or replace actions we need to hook into before-block-channel.
// If we don't hook into the event, the tracking channel will be blocked.
let beforeBlockChannelPromise;
if (action != "block") {
beforeBlockChannelPromise = UrlClassifierTestUtils.handleBeforeBlockChannel(
{
filterOrigin: trackingOrigin,
action,
}
);
}
// Load the test tracker matching the category.
await SpecialPowers.spawn(tab.linkedBrowser, [{ apiMessage }], function(
args
) {
content.postMessage(args.apiMessage, "*");
});
await beforeBlockChannelPromise;
// Next, test if the UI state is correct for the given category and action.
let expectedState = {};
expectedState[trackingOrigin] = {
block: action == "block",
shimAllow: action == "allow",
};
await assertSubViewState(categoryElementId, expectedState);
BrowserTestUtils.removeTab(tab);
}
/**
* Test mixed allow/block/replace states for the tracking protection category.
* @param {Object} options - States to test.
* @param {boolean} options.block - Test tracker block state.
* @param {boolean} options.allow - Test tracker allow state.
* @param {boolean} options.replace - Test tracker replace state.
*/
async function runTestMixed({ block, allow, replace }) {
const ORIGIN_BLOCK = "https://trackertest.org";
const ORIGIN_ALLOW = "https://itisatracker.org";
const ORIGIN_REPLACE = "https://tracking.example.com";
let promise = BrowserTestUtils.openNewForegroundTab({
url: TRACKING_PAGE,
gBrowser,
});
let [tab] = await Promise.all([promise, waitForContentBlockingEvent()]);
if (block) {
// Temporarily remove trackertest.org from the allowlist.
await SpecialPowers.pushPrefEnv({
clear: [
["urlclassifier.trackingSkipURLs"],
["urlclassifier.trackingAnnotationSkipURLs"],
],
});
let blockEventPromise = waitForContentBlockingEvent();
await SpecialPowers.spawn(tab.linkedBrowser, [], function() {
content.postMessage("tracking", "*");
});
await blockEventPromise;
await SpecialPowers.popPrefEnv();
}
if (allow) {
let promiseEvent = waitForContentBlockingEvent();
let promiseAllow = UrlClassifierTestUtils.handleBeforeBlockChannel({
filterOrigin: ORIGIN_ALLOW,
action: "allow",
});
await SpecialPowers.spawn(tab.linkedBrowser, [], function() {
content.postMessage("more-tracking", "*");
});
await promiseAllow;
await promiseEvent;
}
if (replace) {
let promiseReplace = UrlClassifierTestUtils.handleBeforeBlockChannel({
filterOrigin: ORIGIN_REPLACE,
action: "replace",
});
await SpecialPowers.spawn(tab.linkedBrowser, [], function() {
content.postMessage("more-tracking-2", "*");
});
await promiseReplace;
}
let expectedState = {};
if (block) {
expectedState[ORIGIN_BLOCK] = {
shimAllow: false,
block: true,
};
}
if (replace) {
expectedState[ORIGIN_REPLACE] = {
shimAllow: false,
block: false,
};
}
if (allow) {
expectedState[ORIGIN_ALLOW] = {
shimAllow: true,
block: false,
};
}
// Check the protection categories subview with the block list.
await assertSubViewState("trackers", expectedState);
BrowserTestUtils.removeTab(tab);
}
add_task(async function testNoShim() {
await runTestMixed({
allow: false,
replace: false,
block: false,
});
await runTestMixed({
allow: false,
replace: false,
block: true,
});
});
add_task(async function testShimAllow() {
await runTestMixed({
allow: true,
replace: false,
block: false,
});
await runTestMixed({
allow: true,
replace: false,
block: true,
});
});
add_task(async function testShimReplace() {
await runTestMixed({
allow: false,
replace: true,
block: false,
});
await runTestMixed({
allow: false,
replace: true,
block: true,
});
});
add_task(async function testShimMixed() {
await runTestMixed({
allow: true,
replace: true,
block: true,
});
});
add_task(async function testShimCategorySubviews() {
let categories = [
"tracking",
"socialtracking",
"cryptomining",
"fingerprinting",
];
for (let category of categories) {
for (let action of ["block", "allow", "replace"]) {
info(`Test category subview. category: ${category}, action: ${action}`);
await runTestForCategoryAndState(category, action);
}
}
});

Просмотреть файл

@ -33,7 +33,8 @@ add_task(async function setup() {
await UrlClassifierTestUtils.addTestTrackers();
Services.prefs.setBoolPref(DTSCBN_PREF, true);
let TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
let TrackingProtection =
gBrowser.ownerGlobal.gProtectionsHandler.blockers.TrackingProtection;
ok(TrackingProtection, "TP is attached to the browser window");
ok(!TrackingProtection.enabled, "TP is not enabled");

Просмотреть файл

@ -33,7 +33,7 @@ async function assertSitesListed(blocked) {
await openProtectionsPanel();
let categoryItem = document.getElementById(
"protections-popup-category-tracking-protection"
"protections-popup-category-trackers"
);
// Explicitly waiting for the category item becoming visible.
@ -49,6 +49,10 @@ async function assertSitesListed(blocked) {
ok(true, "Trackers view was shown");
let trackersViewShimHint = document.getElementById(
"protections-popup-trackersView-shim-allow-hint"
);
ok(trackersViewShimHint.hidden, "Shim hint is hidden");
let listItems = trackersView.querySelectorAll(".protections-popup-list-item");
is(listItems.length, 1, "We have 1 tracker in the list");

Просмотреть файл

@ -32,6 +32,9 @@ onmessage = event => {
case "more-tracking":
createIframe("https://itisatracker.org/");
break;
case "more-tracking-2":
createIframe("https://tracking.example.com/");
break;
case "cookie":
createIframe(
"https://trackertest.org/browser/browser/base/content/test/protectionsUI/cookieServer.sjs"

Просмотреть файл

@ -41,7 +41,8 @@ async function testShimRuns(
waitForLoad: true,
});
const TrackingProtection = tab.ownerGlobal.TrackingProtection;
const TrackingProtection =
tab.ownerGlobal.gProtectionsHandler.blockers.TrackingProtection;
ok(TrackingProtection, "TP is attached to the tab");
ok(TrackingProtection.enabled, "TP is enabled");

Просмотреть файл

@ -233,4 +233,62 @@ var UrlClassifierTestUtils = {
}
});
},
/**
* Handle the next "urlclassifier-before-block-channel" event.
* @param {Object} options
* @param {String} [options.filterOrigin] - Only handle event for channels
* with matching origin.
* @param {function} [options.onBeforeBlockChannel] - Optional callback for
* the event. Called before acting on the channel.
* @param {("allow"|"replace")} [options.action] - Whether to allow or replace
* the channel.
* @returns {Promise} - Resolves once event has been handled.
*/
handleBeforeBlockChannel({
filterOrigin = null,
onBeforeBlockChannel,
action,
}) {
if (action && action != "allow" && action != "replace") {
throw new Error("Invalid action " + action);
}
let channelClassifierService = Cc[
"@mozilla.org/url-classifier/channel-classifier-service;1"
].getService(Ci.nsIChannelClassifierService);
let resolver;
let promise = new Promise(resolve => {
resolver = resolve;
});
let observer = {
observe(subject, topic) {
if (topic != "urlclassifier-before-block-channel") {
return;
}
let channel = subject.QueryInterface(Ci.nsIUrlClassifierBlockedChannel);
if (filterOrigin) {
let { url } = channel;
let { origin } = new URL(url);
if (filterOrigin != origin) {
return;
}
}
if (onBeforeBlockChannel) {
onBeforeBlockChannel(channel);
}
if (action) {
channel[action]();
}
channelClassifierService.removeListener(observer);
resolver();
},
};
channelClassifierService.addListener(observer);
return promise;
},
};

Просмотреть файл

@ -38,6 +38,7 @@ avoid-blacklist-and-whitelist:
- browser/base/content/test/protectionsUI/browser_protectionsUI_report_breakage.js
- browser/base/content/test/protectionsUI/browser_protectionsUI_socialtracking.js
- browser/base/content/test/protectionsUI/browser_protectionsUI_state.js
- browser/base/content/test/protectionsUI/browser_protectionsUI_subview_shim.js
- browser/base/content/test/siteIdentity/browser_no_mcb_for_loopback.js
- browser/base/content/test/siteIdentity/browser_no_mcb_for_onions.js
- browser/base/content/test/static/browser_all_files_referenced.js