browser_protectionsUI_fingerprinters.js (8598B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const TRACKING_PAGE = 7 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 8 "http://example.org/browser/browser/base/content/test/protectionsUI/trackingPage.html"; 9 const FP_PROTECTION_PREF = "privacy.trackingprotection.fingerprinting.enabled"; 10 let fpHistogram; 11 12 add_setup(async function () { 13 await SpecialPowers.pushPrefEnv({ 14 set: [ 15 [ 16 "urlclassifier.features.fingerprinting.blacklistHosts", 17 "fingerprinting.example.com", 18 ], 19 [ 20 "urlclassifier.features.fingerprinting.annotate.blacklistHosts", 21 "fingerprinting.example.com", 22 ], 23 ["privacy.trackingprotection.enabled", false], 24 ["privacy.trackingprotection.annotate_channels", false], 25 ["privacy.trackingprotection.cryptomining.enabled", false], 26 ["urlclassifier.features.cryptomining.annotate.blacklistHosts", ""], 27 ["urlclassifier.features.cryptomining.annotate.blacklistTables", ""], 28 ], 29 }); 30 fpHistogram = Services.telemetry.getHistogramById( 31 "FINGERPRINTERS_BLOCKED_COUNT" 32 ); 33 registerCleanupFunction(() => { 34 fpHistogram.clear(); 35 }); 36 }); 37 38 async function testIdentityState(hasException) { 39 fpHistogram.clear(); 40 let promise = BrowserTestUtils.openNewForegroundTab({ 41 url: TRACKING_PAGE, 42 gBrowser, 43 }); 44 let [tab] = await Promise.all([promise, waitForContentBlockingEvent()]); 45 46 if (hasException) { 47 let loaded = BrowserTestUtils.browserLoaded( 48 tab.linkedBrowser, 49 false, 50 TRACKING_PAGE 51 ); 52 gProtectionsHandler.disableForCurrentPage(); 53 await loaded; 54 } 55 56 await openProtectionsPanel(); 57 58 ok( 59 !gProtectionsHandler._protectionsPopup.hasAttribute("detected"), 60 "fingerprinters are not detected" 61 ); 62 ok( 63 !BrowserTestUtils.isHidden(gProtectionsHandler.iconBox), 64 "icon box is visible regardless the exception" 65 ); 66 67 promise = waitForContentBlockingEvent(); 68 69 await SpecialPowers.spawn(tab.linkedBrowser, [], function () { 70 content.postMessage("fingerprinting", "*"); 71 }); 72 73 await promise; 74 75 ok( 76 gProtectionsHandler._protectionsPopup.hasAttribute("detected"), 77 "trackers are detected" 78 ); 79 ok( 80 BrowserTestUtils.isVisible(gProtectionsHandler.iconBox), 81 "icon box is visible" 82 ); 83 is( 84 gProtectionsHandler.iconBox.hasAttribute("hasException"), 85 hasException, 86 "Shows an exception when appropriate" 87 ); 88 89 if (hasException) { 90 let loaded = BrowserTestUtils.browserLoaded( 91 tab.linkedBrowser, 92 false, 93 TRACKING_PAGE 94 ); 95 gProtectionsHandler.enableForCurrentPage(); 96 await loaded; 97 } 98 99 let loads = hasException ? 3 : 1; 100 testTelemetry(loads, 1, hasException); 101 102 BrowserTestUtils.removeTab(tab); 103 } 104 105 async function testCategoryItem() { 106 Services.prefs.setBoolPref(FP_PROTECTION_PREF, false); 107 let promise = BrowserTestUtils.openNewForegroundTab({ 108 url: TRACKING_PAGE, 109 gBrowser, 110 }); 111 let [tab] = await Promise.all([promise, waitForContentBlockingEvent()]); 112 113 await openProtectionsPanel(); 114 let categoryItem = document.getElementById( 115 "protections-popup-category-fingerprinters" 116 ); 117 118 ok( 119 !categoryItem.classList.contains("blocked"), 120 "Category not marked as blocked" 121 ); 122 ok( 123 categoryItem.classList.contains("notFound"), 124 "Category marked as not found" 125 ); 126 Services.prefs.setBoolPref(FP_PROTECTION_PREF, true); 127 ok(categoryItem.classList.contains("blocked"), "Category marked as blocked"); 128 ok( 129 categoryItem.classList.contains("notFound"), 130 "Category marked as not found" 131 ); 132 Services.prefs.setBoolPref(FP_PROTECTION_PREF, false); 133 ok( 134 !categoryItem.classList.contains("blocked"), 135 "Category not marked as blocked" 136 ); 137 ok( 138 categoryItem.classList.contains("notFound"), 139 "Category marked as not found" 140 ); 141 await closeProtectionsPanel(); 142 143 promise = waitForContentBlockingEvent(); 144 145 await SpecialPowers.spawn(tab.linkedBrowser, [], function () { 146 content.postMessage("fingerprinting", "*"); 147 }); 148 149 await promise; 150 151 await openProtectionsPanel(); 152 ok( 153 !categoryItem.classList.contains("blocked"), 154 "Category not marked as blocked" 155 ); 156 ok( 157 !categoryItem.classList.contains("notFound"), 158 "Category not marked as not found" 159 ); 160 Services.prefs.setBoolPref(FP_PROTECTION_PREF, true); 161 ok(categoryItem.classList.contains("blocked"), "Category marked as blocked"); 162 ok( 163 !categoryItem.classList.contains("notFound"), 164 "Category not marked as not found" 165 ); 166 Services.prefs.setBoolPref(FP_PROTECTION_PREF, false); 167 ok( 168 !categoryItem.classList.contains("blocked"), 169 "Category not marked as blocked" 170 ); 171 ok( 172 !categoryItem.classList.contains("notFound"), 173 "Category not marked as not found" 174 ); 175 await closeProtectionsPanel(); 176 177 BrowserTestUtils.removeTab(tab); 178 } 179 180 async function testSubview(hasException) { 181 fpHistogram.clear(); 182 let promise = BrowserTestUtils.openNewForegroundTab({ 183 url: TRACKING_PAGE, 184 gBrowser, 185 }); 186 let [tab] = await Promise.all([promise, waitForContentBlockingEvent()]); 187 188 if (hasException) { 189 let loaded = BrowserTestUtils.browserLoaded( 190 tab.linkedBrowser, 191 false, 192 TRACKING_PAGE 193 ); 194 gProtectionsHandler.disableForCurrentPage(); 195 await loaded; 196 } 197 198 promise = waitForContentBlockingEvent(); 199 await SpecialPowers.spawn(tab.linkedBrowser, [], function () { 200 content.postMessage("fingerprinting", "*"); 201 }); 202 await promise; 203 204 await openProtectionsPanel(); 205 206 let categoryItem = document.getElementById( 207 "protections-popup-category-fingerprinters" 208 ); 209 210 // Explicitly waiting for the category item becoming visible. 211 await TestUtils.waitForCondition(() => { 212 return BrowserTestUtils.isVisible(categoryItem); 213 }); 214 215 ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible"); 216 217 /* eslint-disable mozilla/no-arbitrary-setTimeout */ 218 // We have to wait until the ContentBlockingLog gets updated in the content. 219 // Unfortunately, we need to use the setTimeout here since we don't have an 220 // easy to know whether the log is updated in the content. This should be 221 // removed after the log been removed in the content (Bug 1599046). 222 await new Promise(resolve => { 223 setTimeout(resolve, 500); 224 }); 225 /* eslint-enable mozilla/no-arbitrary-setTimeout */ 226 227 let subview = document.getElementById("protections-popup-fingerprintersView"); 228 let viewShown = BrowserTestUtils.waitForEvent(subview, "ViewShown"); 229 categoryItem.click(); 230 await viewShown; 231 232 let trackersViewShimHint = document.getElementById( 233 "protections-popup-fingerprintersView-shim-allow-hint" 234 ); 235 ok(trackersViewShimHint.hidden, "Shim hint is hidden"); 236 237 let listItems = subview.querySelectorAll(".protections-popup-list-item"); 238 is(listItems.length, 1, "We have 1 item in the list"); 239 let listItem = listItems[0]; 240 ok(BrowserTestUtils.isVisible(listItem), "List item is visible"); 241 is( 242 listItem.querySelector("label").value, 243 "https://fingerprinting.example.com", 244 "Has the correct host" 245 ); 246 is( 247 listItem.classList.contains("allowed"), 248 hasException, 249 "Indicates the fingerprinter was blocked or allowed" 250 ); 251 252 let mainView = document.getElementById("protections-popup-mainView"); 253 viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown"); 254 let backButton = subview.querySelector(".subviewbutton-back"); 255 backButton.click(); 256 await viewShown; 257 258 ok(true, "Main view was shown"); 259 260 if (hasException) { 261 let loaded = BrowserTestUtils.browserLoaded( 262 tab.linkedBrowser, 263 false, 264 TRACKING_PAGE 265 ); 266 gProtectionsHandler.enableForCurrentPage(); 267 await loaded; 268 } 269 270 let loads = hasException ? 3 : 1; 271 testTelemetry(loads, 1, hasException); 272 273 BrowserTestUtils.removeTab(tab); 274 } 275 276 function testTelemetry(pagesVisited, pagesWithBlockableContent, hasException) { 277 let results = fpHistogram.snapshot(); 278 Assert.equal( 279 results.values[0], 280 pagesVisited, 281 "The correct number of page loads have been recorded" 282 ); 283 let expectedValue = hasException ? 2 : 1; 284 Assert.equal( 285 results.values[expectedValue], 286 pagesWithBlockableContent, 287 "The correct number of fingerprinters have been recorded as blocked or allowed." 288 ); 289 } 290 291 add_task(async function test() { 292 Services.prefs.setBoolPref(FP_PROTECTION_PREF, true); 293 294 await testIdentityState(false); 295 await testIdentityState(true); 296 297 await testSubview(false); 298 await testSubview(true); 299 300 await testCategoryItem(); 301 302 Services.prefs.clearUserPref(FP_PROTECTION_PREF); 303 });