From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../browser/browser_storageAccessDoorHanger.js | 374 +++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js (limited to 'toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js') diff --git a/toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js b/toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js new file mode 100644 index 0000000000..c922234ed2 --- /dev/null +++ b/toolkit/components/antitracking/test/browser/browser_storageAccessDoorHanger.js @@ -0,0 +1,374 @@ +/* eslint-disable mozilla/no-arbitrary-setTimeout */ +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/browser/modules/test/browser/head.js", + this +); + +const BLOCK = 0; +const ALLOW = 1; + +async function testDoorHanger( + choice, + showPrompt, + useEscape, + topPage, + maxConcurrent, + disableWebcompat = false +) { + info( + `Running doorhanger test with choice #${choice}, showPrompt: ${showPrompt} and ` + + `useEscape: ${useEscape}, topPage: ${topPage}, maxConcurrent: ${maxConcurrent}` + ); + + if (!showPrompt) { + is(choice, ALLOW, "When not showing a prompt, we can only auto-grant"); + ok( + !useEscape, + "When not showing a prompt, we should not be trying to use the Esc key" + ); + } + + await SpecialPowers.flushPrefEnv(); + await SpecialPowers.pushPrefEnv({ + set: [ + ["privacy.antitracking.enableWebcompat", !disableWebcompat], + ["dom.storage_access.auto_grants", true], + ["dom.storage_access.auto_grants.delayed", false], + ["dom.storage_access.enabled", true], + ["dom.storage_access.max_concurrent_auto_grants", maxConcurrent], + ["dom.storage_access.prompt.testing", false], + [ + "network.cookie.cookieBehavior", + Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER, + ], + [ + "network.cookie.cookieBehavior.pbmode", + Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER, + ], + ["privacy.trackingprotection.enabled", false], + ["privacy.trackingprotection.pbmode.enabled", false], + ["privacy.trackingprotection.annotate_channels", true], + [ + "privacy.restrict3rdpartystorage.userInteractionRequiredForHosts", + "tracking.example.com,tracking.example.org", + ], + // Bug 1617611: Fix all the tests broken by "cookies SameSite=lax by default" + ["network.cookie.sameSite.laxByDefault", false], + ], + }); + + await UrlClassifierTestUtils.addTestTrackers(); + + let tab = BrowserTestUtils.addTab(gBrowser, topPage); + gBrowser.selectedTab = tab; + + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + + async function runChecks() { + // We need to repeat this constant here since runChecks is stringified + // and sent to the content process. + const BLOCK = 0; + + await new Promise(resolve => { + addEventListener( + "message", + function onMessage(e) { + if (e.data.startsWith("choice:")) { + window.choice = e.data.split(":")[1]; + window.useEscape = e.data.split(":")[3]; + removeEventListener("message", onMessage); + resolve(); + } + }, + false + ); + parent.postMessage("getchoice", "*"); + }); + + /* import-globals-from storageAccessAPIHelpers.js */ + await noStorageAccessInitially(); + + is(document.cookie, "", "No cookies for me"); + document.cookie = "name=value"; + is(document.cookie, "", "No cookies for me"); + + await fetch("server.sjs") + .then(r => r.text()) + .then(text => { + is(text, "cookie-not-present", "We should not have cookies"); + }); + // Let's do it twice. + await fetch("server.sjs") + .then(r => r.text()) + .then(text => { + is(text, "cookie-not-present", "We should not have cookies"); + }); + + is(document.cookie, "", "Still no cookies for me"); + + /* import-globals-from storageAccessAPIHelpers.js */ + await callRequestStorageAccess(); + + if (choice == BLOCK) { + // We've said no, so cookies are still blocked + is(document.cookie, "", "Still no cookies for me"); + document.cookie = "name=value"; + is(document.cookie, "", "No cookies for me"); + } else { + // We've said yes, so cookies are allowed now + is(document.cookie, "", "No cookies for me"); + document.cookie = "name=value"; + is(document.cookie, "name=value", "I have the cookies!"); + } + } + + let permChanged; + // Only create the promise when we're going to click one of the allow buttons. + if (choice != BLOCK) { + permChanged = TestUtils.topicObserved("perm-changed", (subject, data) => { + let result; + if (choice == ALLOW) { + result = + subject && + subject + .QueryInterface(Ci.nsIPermission) + .type.startsWith("3rdPartyFrameStorage^") && + subject.principal.origin == new URL(topPage).origin && + data == "added"; + } + return result; + }); + } + let shownPromise = BrowserTestUtils.waitForEvent( + PopupNotifications.panel, + "popupshown" + ); + shownPromise.then(async _ => { + if (topPage != gBrowser.currentURI.spec) { + return; + } + ok(showPrompt, "We shouldn't show the prompt when we don't intend to"); + let notification = await new Promise(function poll(resolve) { + let notification = PopupNotifications.getNotification( + "storage-access", + browser + ); + if (notification) { + resolve(notification); + return; + } + setTimeout(poll, 10); + }); + Assert.ok(notification, "Should have gotten the notification"); + + if (choice == BLOCK) { + if (useEscape) { + info("hitting escape"); + EventUtils.synthesizeKey("KEY_Escape", {}, window); + } else { + await clickSecondaryAction(); + } + } else if (choice == ALLOW) { + await clickMainAction(); + } + if (choice != BLOCK) { + await permChanged; + } + }); + + let url = TEST_3RD_PARTY_PAGE + "?disableWaitUntilPermission"; + let ct = SpecialPowers.spawn( + browser, + [{ page: url, callback: runChecks.toString(), choice, useEscape }], + async function (obj) { + 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(obj.callback, "*"); + }; + + 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; + } + + if (event.data == "getchoice") { + ifr.contentWindow.postMessage( + "choice:" + obj.choice + ":useEscape:" + obj.useEscape, + "*" + ); + return; + } + + ok(false, "Unknown message"); + }); + + content.document.body.appendChild(ifr); + ifr.src = obj.page; + }); + } + ); + if (showPrompt) { + await Promise.all([ct, shownPromise]); + } else { + await Promise.all([ct, permChanged]); + } + + let permissionPopupPromise = BrowserTestUtils.waitForEvent( + window, + "popupshown", + true, + event => event.target == gPermissionPanel._permissionPopup + ); + gPermissionPanel._identityPermissionBox.click(); + await permissionPopupPromise; + let permissionItem = document.querySelector( + ".permission-popup-permission-item-3rdPartyFrameStorage" + ); + ok(permissionItem, "Permission item exists"); + ok( + BrowserTestUtils.isVisible(permissionItem), + "Permission item visible in the identity panel" + ); + let permissionLearnMoreLink = document.getElementById( + "permission-popup-storage-access-permission-learn-more" + ); + ok(permissionLearnMoreLink, "Permission learn more link exists"); + ok( + BrowserTestUtils.isVisible(permissionLearnMoreLink), + "Permission learn more link is visible in the identity panel" + ); + permissionPopupPromise = BrowserTestUtils.waitForEvent( + gPermissionPanel._permissionPopup, + "popuphidden" + ); + gPermissionPanel._permissionPopup.hidePopup(); + await permissionPopupPromise; + + BrowserTestUtils.removeTab(tab); + + UrlClassifierTestUtils.cleanupTestTrackers(); +} + +async function preparePermissionsFromOtherSites(topPage) { + info("Faking permissions from other sites"); + let type = "3rdPartyFrameStorage^https://example.org"; + let permission = Services.perms.ALLOW_ACTION; + let expireType = Services.perms.EXPIRE_SESSION; + if (topPage == TEST_TOP_PAGE) { + // For the first page, don't do anything + } else if (topPage == TEST_TOP_PAGE_2) { + // For the second page, only add the permission from the first page + PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0); + } else if (topPage == TEST_TOP_PAGE_3) { + // For the third page, add the permissions from the first two pages + PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_2, type, permission, expireType, 0); + } else if (topPage == TEST_TOP_PAGE_4) { + // For the fourth page, add the permissions from the first three pages + PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_2, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_3, type, permission, expireType, 0); + } else if (topPage == TEST_TOP_PAGE_5) { + // For the fifth page, add the permissions from the first four pages + PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_2, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_3, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_4, type, permission, expireType, 0); + } else if (topPage == TEST_TOP_PAGE_6) { + // For the sixth page, add the permissions from the first five pages + PermissionTestUtils.add(TEST_DOMAIN, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_2, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_3, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_4, type, permission, expireType, 0); + PermissionTestUtils.add(TEST_DOMAIN_5, type, permission, expireType, 0); + } else { + ok(false, "Unexpected top page: " + topPage); + } +} + +async function cleanUp() { + info("Cleaning up."); + SpecialPowers.clearUserPref("network.cookie.sameSite.laxByDefault"); + await new Promise(resolve => { + Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => + resolve() + ); + }); +} + +async function runRound(topPage, showPrompt, maxConcurrent, disableWebcompat) { + info("Starting round"); + if (showPrompt) { + await preparePermissionsFromOtherSites(topPage); + await testDoorHanger( + BLOCK, + showPrompt, + true, + topPage, + maxConcurrent, + disableWebcompat + ); + await cleanUp(); + await preparePermissionsFromOtherSites(topPage); + await testDoorHanger( + BLOCK, + showPrompt, + false, + topPage, + maxConcurrent, + disableWebcompat + ); + await cleanUp(); + await preparePermissionsFromOtherSites(topPage); + await testDoorHanger( + ALLOW, + showPrompt, + false, + topPage, + maxConcurrent, + disableWebcompat + ); + await cleanUp(); + } else { + await preparePermissionsFromOtherSites(topPage); + await testDoorHanger( + ALLOW, + showPrompt, + false, + topPage, + maxConcurrent, + disableWebcompat + ); + } + await cleanUp(); +} + +add_task(async function test_combinations() { + await runRound(TEST_TOP_PAGE, false, 1); + await runRound(TEST_TOP_PAGE_2, true, 1); + await runRound(TEST_TOP_PAGE, false, 5); + await runRound(TEST_TOP_PAGE_2, false, 5); + await runRound(TEST_TOP_PAGE_3, false, 5); + await runRound(TEST_TOP_PAGE_4, false, 5); + await runRound(TEST_TOP_PAGE_5, false, 5); + await runRound(TEST_TOP_PAGE_6, true, 5); +}); + +add_task(async function test_disableWebcompat() { + await runRound(TEST_TOP_PAGE, true, 5, true); +}); -- cgit v1.2.3