gecko-dev/toolkit/components/antitracking/test/browser/storageAccessAPIHelpers.js
Tim Huang 3fd8634816 Bug 1695050 - Part 3: Update current test cases and add a new test case. r=dimi
This patch updates the pref for existing content blocking tests. And it
also adds a new test to verify that the cookieBehavior in regular
windowa and private window are both correct.

Differential Revision: https://phabricator.services.mozilla.com/D109046
2021-03-29 11:01:51 +00:00

200 lines
5.5 KiB
JavaScript

/* global allowListed */
async function hasStorageAccessInitially() {
let hasAccess = await document.hasStorageAccess();
ok(hasAccess, "Has storage access");
}
async function noStorageAccessInitially() {
let hasAccess = await document.hasStorageAccess();
ok(!hasAccess, "Doesn't yet have storage access");
}
async function callRequestStorageAccess(callback, expectFail) {
let dwu = SpecialPowers.getDOMWindowUtils(window);
let helper = dwu.setHandlingUserInput(true);
let origin = new URL(location.href).origin;
let effectiveCookieBehavior = SpecialPowers.isContentWindowPrivate(window)
? SpecialPowers.Services.prefs.getIntPref(
"network.cookie.cookieBehavior.pbmode"
)
: SpecialPowers.Services.prefs.getIntPref("network.cookie.cookieBehavior");
let success = true;
// We only grant storage exceptions when the reject tracker behavior is enabled.
let rejectTrackers =
[
SpecialPowers.Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
SpecialPowers.Ci.nsICookieService
.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
].includes(effectiveCookieBehavior) && !isOnContentBlockingAllowList();
const TEST_ANOTHER_3RD_PARTY_ORIGIN = SpecialPowers.useRemoteSubframes
? "http://another-tracking.example.net"
: "https://another-tracking.example.net";
// With another-tracking.example.net, we're same-eTLD+1, so the first try succeeds.
if (origin != TEST_ANOTHER_3RD_PARTY_ORIGIN) {
if (rejectTrackers) {
let p;
let threw = false;
try {
p = document.requestStorageAccess();
} catch (e) {
threw = true;
} finally {
helper.destruct();
}
ok(!threw, "requestStorageAccess should not throw");
try {
if (callback) {
if (expectFail) {
await p.catch(_ => callback(dwu));
success = false;
} else {
await p.then(_ => callback(dwu));
}
} else {
await p;
}
} catch (e) {
success = false;
}
ok(!success, "Should not have worked without user interaction");
await noStorageAccessInitially();
await interactWithTracker();
helper = dwu.setHandlingUserInput(true);
}
if (
effectiveCookieBehavior ==
SpecialPowers.Ci.nsICookieService.BEHAVIOR_ACCEPT &&
!isOnContentBlockingAllowList()
) {
try {
if (callback) {
if (expectFail) {
await document.requestStorageAccess().catch(_ => callback(dwu));
success = false;
} else {
await document.requestStorageAccess().then(_ => callback(dwu));
}
} else {
await document.requestStorageAccess();
}
} catch (e) {
success = false;
} finally {
helper.destruct();
}
ok(success, "Should not have thrown");
await hasStorageAccessInitially();
await interactWithTracker();
helper = dwu.setHandlingUserInput(true);
}
}
let p;
let threw = false;
try {
p = document.requestStorageAccess();
} catch (e) {
threw = true;
} finally {
helper.destruct();
}
let rejected = false;
try {
if (callback) {
if (expectFail) {
await p.catch(_ => callback(dwu));
rejected = true;
} else {
await p.then(_ => callback(dwu));
}
} else {
await p;
}
} catch (e) {
rejected = true;
}
success = !threw && !rejected;
let hasAccess = await document.hasStorageAccess();
is(
hasAccess,
success,
"Should " + (success ? "" : "not ") + "have storage access now"
);
if (
success &&
rejectTrackers &&
window.location.search != "?disableWaitUntilPermission" &&
origin != TEST_ANOTHER_3RD_PARTY_ORIGIN
) {
// Wait until the permission is visible in parent process to avoid race
// conditions. We don't need to wait the permission to be visible in content
// processes since the content process doesn't rely on the permission to
// know the storage access is updated.
await waitUntilPermission(
"http://example.net/browser/toolkit/components/antitracking/test/browser/page.html",
"3rdPartyStorage^" + window.origin
);
}
return [threw, rejected];
}
async function waitUntilPermission(url, name) {
let originAttributes = SpecialPowers.isContentWindowPrivate(window)
? { privateBrowsingId: 1 }
: {};
await new Promise(resolve => {
let id = setInterval(async _ => {
if (
await SpecialPowers.testPermission(
name,
SpecialPowers.Services.perms.ALLOW_ACTION,
{
url,
originAttributes,
}
)
) {
clearInterval(id);
resolve();
}
}, 0);
});
}
async function interactWithTracker() {
await new Promise(resolve => {
let orionmessage = onmessage;
onmessage = _ => {
onmessage = orionmessage;
resolve();
};
info("Let's interact with the tracker");
window.open(
"/browser/toolkit/components/antitracking/test/browser/3rdPartyOpenUI.html?messageme"
);
});
// Wait until the user interaction permission becomes visible in our process
await waitUntilPermission(window.origin, "storageAccessAPI");
}
function isOnContentBlockingAllowList() {
// We directly check the window.allowListed here instead of checking the
// permission. The allow list permission might not be available since it is
// not in the preload list.
return window.allowListed;
}