Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'linux' && os_version == '18.04' && asan OR os == 'linux' && os_version == '18.04' && tsan OR debug
- Manifest: toolkit/components/antitracking/test/browser/browser.toml
/* eslint-disable mozilla/no-arbitrary-setTimeout */
Services.scriptloader.loadSubScript(
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",
],
["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 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, () =>
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);
});