browser_protectionsUI_cookies_subview.js (17575B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 /* eslint-disable mozilla/no-arbitrary-setTimeout */ 5 6 "use strict"; 7 8 const COOKIE_PAGE = 9 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 10 "http://not-tracking.example.com/browser/browser/base/content/test/protectionsUI/cookiePage.html"; 11 const CONTAINER_PAGE = 12 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 13 "http://not-tracking.example.com/browser/browser/base/content/test/protectionsUI/containerPage.html"; 14 15 const TPC_PREF = "network.cookie.cookieBehavior"; 16 17 add_setup(async function () { 18 await UrlClassifierTestUtils.addTestTrackers(); 19 20 registerCleanupFunction(() => { 21 UrlClassifierTestUtils.cleanupTestTrackers(); 22 }); 23 }); 24 25 /* 26 * Accepts an array containing 6 elements that identify the testcase: 27 * [0] - boolean indicating whether trackers are blocked. 28 * [1] - boolean indicating whether third party cookies are blocked. 29 * [2] - boolean indicating whether first party cookies are blocked. 30 * [3] - integer indicating number of expected content blocking events. 31 * [4] - integer indicating number of expected subview list headers. 32 * [5] - integer indicating number of expected cookie list items. 33 * [6] - integer indicating number of expected cookie list items 34 * after loading a cookie-setting third party URL in an iframe 35 * [7] - integer indicating number of expected cookie list items 36 * after loading a cookie-setting first party URL in an iframe 37 */ 38 async function assertSitesListed(testCase) { 39 let sitesListedTestCases = [ 40 [true, false, false, 4, 1, 1, 1, 1], 41 [true, true, false, 5, 1, 1, 2, 2], 42 [true, true, true, 6, 2, 2, 3, 3], 43 [false, false, false, 3, 1, 1, 1, 1], 44 ]; 45 let [ 46 trackersBlocked, 47 thirdPartyBlocked, 48 firstPartyBlocked, 49 contentBlockingEventCount, 50 listHeaderCount, 51 cookieItemsCount1, 52 cookieItemsCount2, 53 cookieItemsCount3, 54 ] = sitesListedTestCases[testCase]; 55 let promise = BrowserTestUtils.openNewForegroundTab({ 56 url: COOKIE_PAGE, 57 gBrowser, 58 }); 59 let [tab] = await Promise.all([ 60 promise, 61 waitForContentBlockingEvent(contentBlockingEventCount), 62 ]); 63 let browser = tab.linkedBrowser; 64 65 await openProtectionsPanel(); 66 67 let categoryItem = document.getElementById( 68 "protections-popup-category-cookies" 69 ); 70 71 // Explicitly waiting for the category item becoming visible. 72 await TestUtils.waitForCondition(() => { 73 return BrowserTestUtils.isVisible(categoryItem); 74 }); 75 76 ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible"); 77 let cookiesView = document.getElementById("protections-popup-cookiesView"); 78 let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown"); 79 categoryItem.click(); 80 await viewShown; 81 82 ok(true, "Cookies view was shown"); 83 84 let listHeaders = cookiesView.querySelectorAll( 85 ".protections-popup-cookiesView-list-header" 86 ); 87 is( 88 listHeaders.length, 89 listHeaderCount, 90 `We have ${listHeaderCount} list headers.` 91 ); 92 if (listHeaderCount == 1) { 93 ok( 94 !BrowserTestUtils.isVisible(listHeaders[0]), 95 "Only one header, should be hidden" 96 ); 97 } else { 98 for (let header of listHeaders) { 99 ok( 100 BrowserTestUtils.isVisible(header), 101 "Multiple list headers - all should be visible." 102 ); 103 } 104 } 105 106 let emptyLabels = cookiesView.querySelectorAll( 107 ".protections-popup-empty-label" 108 ); 109 is(emptyLabels.length, 0, `We have no empty labels`); 110 111 let listItems = cookiesView.querySelectorAll(".protections-popup-list-item"); 112 is( 113 listItems.length, 114 cookieItemsCount1, 115 `We have ${cookieItemsCount1} cookies in the list` 116 ); 117 118 if (trackersBlocked) { 119 let trackerTestItem; 120 for (let item of listItems) { 121 let label = item.querySelector(".protections-popup-list-host-label"); 122 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 123 if (label.value == "http://trackertest.org") { 124 trackerTestItem = item; 125 break; 126 } 127 } 128 ok(trackerTestItem, "Has an item for trackertest.org"); 129 ok(BrowserTestUtils.isVisible(trackerTestItem), "List item is visible"); 130 } 131 132 if (firstPartyBlocked) { 133 let notTrackingExampleItem; 134 for (let item of listItems) { 135 let label = item.querySelector(".protections-popup-list-host-label"); 136 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 137 if (label.value == "http://not-tracking.example.com") { 138 notTrackingExampleItem = item; 139 break; 140 } 141 } 142 ok(notTrackingExampleItem, "Has an item for not-tracking.example.com"); 143 ok( 144 BrowserTestUtils.isVisible(notTrackingExampleItem), 145 "List item is visible" 146 ); 147 } 148 let mainView = document.getElementById("protections-popup-mainView"); 149 viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown"); 150 let backButton = cookiesView.querySelector(".subviewbutton-back"); 151 backButton.click(); 152 await viewShown; 153 154 ok(true, "Main view was shown"); 155 156 let change = waitForContentBlockingEvent(); 157 let timeoutPromise = new Promise(resolve => setTimeout(resolve, 1000)); 158 159 await SpecialPowers.spawn(browser, [], function () { 160 content.postMessage("third-party-cookie", "*"); 161 }); 162 163 let result = await Promise.race([change, timeoutPromise]); 164 is(result, undefined, "No contentBlockingEvent events should be received"); 165 166 viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown"); 167 categoryItem.click(); 168 await viewShown; 169 170 ok(true, "Cookies view was shown"); 171 172 emptyLabels = cookiesView.querySelectorAll(".protections-popup-empty-label"); 173 is(emptyLabels.length, 0, `We have no empty labels`); 174 175 listItems = cookiesView.querySelectorAll(".protections-popup-list-item"); 176 is( 177 listItems.length, 178 cookieItemsCount2, 179 `We have ${cookieItemsCount2} cookies in the list` 180 ); 181 182 if (thirdPartyBlocked) { 183 let test1ExampleItem; 184 for (let item of listItems) { 185 let label = item.querySelector(".protections-popup-list-host-label"); 186 if (label.value == "https://test1.example.org") { 187 test1ExampleItem = item; 188 break; 189 } 190 } 191 ok(test1ExampleItem, "Has an item for test1.example.org"); 192 ok(BrowserTestUtils.isVisible(test1ExampleItem), "List item is visible"); 193 } 194 195 if (trackersBlocked || thirdPartyBlocked || firstPartyBlocked) { 196 let trackerTestItem; 197 for (let item of listItems) { 198 let label = item.querySelector(".protections-popup-list-host-label"); 199 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 200 if (label.value == "http://trackertest.org") { 201 trackerTestItem = item; 202 break; 203 } 204 } 205 ok(trackerTestItem, "List item should exist for http://trackertest.org"); 206 ok(BrowserTestUtils.isVisible(trackerTestItem), "List item is visible"); 207 } 208 209 viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown"); 210 backButton.click(); 211 await viewShown; 212 213 ok(true, "Main view was shown"); 214 215 change = waitForSecurityChange(); 216 timeoutPromise = new Promise(resolve => setTimeout(resolve, 1000)); 217 218 await SpecialPowers.spawn(browser, [], function () { 219 content.postMessage("first-party-cookie", "*"); 220 }); 221 222 result = await Promise.race([change, timeoutPromise]); 223 is(result, undefined, "No securityChange events should be received"); 224 225 viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown"); 226 categoryItem.click(); 227 await viewShown; 228 229 ok(true, "Cookies view was shown"); 230 231 emptyLabels = cookiesView.querySelectorAll(".protections-popup-empty-label"); 232 is(emptyLabels.length, 0, "We have no empty labels"); 233 234 listItems = cookiesView.querySelectorAll(".protections-popup-list-item"); 235 is( 236 listItems.length, 237 cookieItemsCount3, 238 `We have ${cookieItemsCount3} cookies in the list` 239 ); 240 241 if (firstPartyBlocked) { 242 let notTrackingExampleItem; 243 for (let item of listItems) { 244 let label = item.querySelector(".protections-popup-list-host-label"); 245 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 246 if (label.value == "http://not-tracking.example.com") { 247 notTrackingExampleItem = item; 248 break; 249 } 250 } 251 ok(notTrackingExampleItem, "Has an item for not-tracking.example.com"); 252 ok( 253 BrowserTestUtils.isVisible(notTrackingExampleItem), 254 "List item is visible" 255 ); 256 } 257 258 BrowserTestUtils.removeTab(tab); 259 } 260 261 add_task(async function testCookiesSubView() { 262 info("Testing cookies subview with reject tracking cookies."); 263 Services.prefs.setIntPref( 264 TPC_PREF, 265 Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER 266 ); 267 let testCaseIndex = 0; 268 await assertSitesListed(testCaseIndex++); 269 info("Testing cookies subview with reject third party cookies."); 270 Services.prefs.setIntPref( 271 TPC_PREF, 272 Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN 273 ); 274 await assertSitesListed(testCaseIndex++); 275 info("Testing cookies subview with reject all cookies."); 276 Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT); 277 await assertSitesListed(testCaseIndex++); 278 info("Testing cookies subview with accept all cookies."); 279 Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT); 280 await assertSitesListed(testCaseIndex++); 281 282 Services.prefs.clearUserPref(TPC_PREF); 283 }); 284 285 add_task(async function testCookiesSubViewAllowed() { 286 Services.prefs.setIntPref( 287 TPC_PREF, 288 Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER 289 ); 290 let principal = 291 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 292 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 293 "http://trackertest.org/" 294 ); 295 Services.perms.addFromPrincipal( 296 principal, 297 "cookie", 298 Services.perms.ALLOW_ACTION 299 ); 300 301 let promise = BrowserTestUtils.openNewForegroundTab({ 302 url: COOKIE_PAGE, 303 gBrowser, 304 }); 305 let [tab] = await Promise.all([promise, waitForContentBlockingEvent(3)]); 306 307 await openProtectionsPanel(); 308 309 let categoryItem = document.getElementById( 310 "protections-popup-category-cookies" 311 ); 312 313 // Explicitly waiting for the category item becoming visible. 314 await TestUtils.waitForCondition(() => { 315 return BrowserTestUtils.isVisible(categoryItem); 316 }); 317 318 ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible"); 319 let cookiesView = document.getElementById("protections-popup-cookiesView"); 320 let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown"); 321 categoryItem.click(); 322 await viewShown; 323 324 ok(true, "Cookies view was shown"); 325 326 let listItems = cookiesView.querySelectorAll(".protections-popup-list-item"); 327 is(listItems.length, 1, "We have 1 cookie in the list"); 328 329 let listItem = listItems[0]; 330 let label = listItem.querySelector(".protections-popup-list-host-label"); 331 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 332 is(label.value, "http://trackertest.org", "has an item for trackertest.org"); 333 ok(BrowserTestUtils.isVisible(listItem), "list item is visible"); 334 ok( 335 listItem.classList.contains("allowed"), 336 "indicates whether the cookie was blocked or allowed" 337 ); 338 339 let stateLabel = listItem.querySelector( 340 ".protections-popup-list-state-label" 341 ); 342 ok(stateLabel, "List item has a state label"); 343 ok(BrowserTestUtils.isVisible(stateLabel), "State label is visible"); 344 is( 345 stateLabel.getAttribute("data-l10n-id"), 346 "content-blocking-cookies-view-allowed-label", 347 "State label has correct text" 348 ); 349 350 let button = listItem.querySelector( 351 ".permission-popup-permission-remove-button" 352 ); 353 ok(BrowserTestUtils.isVisible(button), "Permission remove button is visible"); 354 button.click(); 355 is( 356 Services.perms.testExactPermissionFromPrincipal(principal, "cookie"), 357 Services.perms.UNKNOWN_ACTION, 358 "Button click should remove cookie pref." 359 ); 360 ok(!listItem.classList.contains("allowed"), "Has removed the allowed class"); 361 362 BrowserTestUtils.removeTab(tab); 363 364 Services.prefs.clearUserPref(TPC_PREF); 365 }); 366 367 add_task(async function testCookiesSubViewAllowedHeuristic() { 368 Services.prefs.setIntPref( 369 TPC_PREF, 370 Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER 371 ); 372 Services.prefs.setBoolPref( 373 "privacy.restrict3rdpartystorage.heuristic.exclude_third_party_trackers", 374 false 375 ); 376 let principal = 377 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 378 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 379 "http://not-tracking.example.com/" 380 ); 381 382 // Pretend that the tracker has already been interacted with 383 let trackerPrincipal = 384 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 385 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 386 "http://trackertest.org/" 387 ); 388 Services.perms.addFromPrincipal( 389 trackerPrincipal, 390 "storageAccessAPI", 391 Services.perms.ALLOW_ACTION 392 ); 393 394 let promise = BrowserTestUtils.openNewForegroundTab({ 395 url: COOKIE_PAGE, 396 gBrowser, 397 }); 398 let [tab] = await Promise.all([promise, waitForContentBlockingEvent(5)]); 399 let browser = tab.linkedBrowser; 400 401 let popup; 402 let windowCreated = TestUtils.topicObserved( 403 "chrome-document-global-created", 404 subject => { 405 popup = subject; 406 return true; 407 } 408 ); 409 let permChanged = TestUtils.topicObserved("perm-changed", (subject, data) => { 410 return ( 411 subject && 412 subject.QueryInterface(Ci.nsIPermission).type == 413 "3rdPartyStorage^http://trackertest.org" && 414 subject.principal.origin == principal.origin && 415 data == "added" 416 ); 417 }); 418 419 await SpecialPowers.spawn(browser, [], function () { 420 content.postMessage("window-open", "*"); 421 }); 422 await Promise.all([windowCreated, permChanged]); 423 424 await new Promise(resolve => waitForFocus(resolve, popup)); 425 await new Promise(resolve => waitForFocus(resolve, window)); 426 427 await openProtectionsPanel(); 428 429 let categoryItem = document.getElementById( 430 "protections-popup-category-cookies" 431 ); 432 433 // Explicitly waiting for the category item becoming visible. 434 await TestUtils.waitForCondition(() => { 435 return BrowserTestUtils.isVisible(categoryItem); 436 }); 437 438 ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible"); 439 let cookiesView = document.getElementById("protections-popup-cookiesView"); 440 let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown"); 441 categoryItem.click(); 442 await viewShown; 443 444 ok(true, "Cookies view was shown"); 445 446 let listItems = cookiesView.querySelectorAll(".protections-popup-list-item"); 447 is(listItems.length, 1, "We have 1 cookie in the list"); 448 449 let listItem = listItems[0]; 450 let label = listItem.querySelector(".protections-popup-list-host-label"); 451 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 452 is(label.value, "http://trackertest.org", "has an item for trackertest.org"); 453 ok(BrowserTestUtils.isVisible(listItem), "list item is visible"); 454 ok( 455 listItem.classList.contains("allowed"), 456 "indicates whether the cookie was blocked or allowed" 457 ); 458 459 let button = listItem.querySelector( 460 ".permission-popup-permission-remove-button" 461 ); 462 ok(BrowserTestUtils.isVisible(button), "Permission remove button is visible"); 463 button.click(); 464 is( 465 Services.perms.testExactPermissionFromPrincipal( 466 principal, 467 "3rdPartyStorage^http://trackertest.org" 468 ), 469 Services.perms.UNKNOWN_ACTION, 470 "Button click should remove the storage pref." 471 ); 472 ok(!listItem.classList.contains("allowed"), "Has removed the allowed class"); 473 474 await SpecialPowers.spawn(browser, [], function () { 475 content.postMessage("window-close", "*"); 476 }); 477 478 BrowserTestUtils.removeTab(tab); 479 480 Services.prefs.clearUserPref(TPC_PREF); 481 Services.prefs.clearUserPref( 482 "privacy.restrict3rdpartystorage.heuristic.exclude_third_party_trackers" 483 ); 484 }); 485 486 add_task(async function testCookiesSubViewBlockedDoublyNested() { 487 requestLongerTimeout(2); 488 489 Services.prefs.setIntPref( 490 TPC_PREF, 491 Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER 492 ); 493 494 let promise = BrowserTestUtils.openNewForegroundTab({ 495 url: CONTAINER_PAGE, 496 gBrowser, 497 }); 498 let [tab] = await Promise.all([promise, waitForContentBlockingEvent(3)]); 499 500 await openProtectionsPanel(); 501 502 let categoryItem = document.getElementById( 503 "protections-popup-category-cookies" 504 ); 505 506 // Explicitly waiting for the category item becoming visible. 507 await TestUtils.waitForCondition(() => { 508 return BrowserTestUtils.isVisible(categoryItem); 509 }); 510 511 ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible"); 512 let cookiesView = document.getElementById("protections-popup-cookiesView"); 513 let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown"); 514 categoryItem.click(); 515 await viewShown; 516 517 ok(true, "Cookies view was shown"); 518 519 let listItems = cookiesView.querySelectorAll(".protections-popup-list-item"); 520 is(listItems.length, 1, "We have 1 cookie in the list"); 521 522 let listItem = listItems[0]; 523 let label = listItem.querySelector(".protections-popup-list-host-label"); 524 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 525 is(label.value, "http://trackertest.org", "has an item for trackertest.org"); 526 ok(BrowserTestUtils.isVisible(listItem), "list item is visible"); 527 ok( 528 !listItem.classList.contains("allowed"), 529 "indicates whether the cookie was blocked or allowed" 530 ); 531 532 let button = listItem.querySelector( 533 ".permission-popup-permission-remove-button" 534 ); 535 ok(!button, "Permission remove button doesn't exist"); 536 537 BrowserTestUtils.removeTab(tab); 538 539 Services.prefs.clearUserPref(TPC_PREF); 540 });