Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

"use strict";
AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB();
// In this test, we want to check the behavior of extensions without private
// browsing access. Privileged add-ons automatically have private browsing
// access, so make sure that the test add-ons are not privileged.
AddonTestUtils.usePrivilegedSignatures = false;
add_task(async function setup() {
await ExtensionTestUtils.startAddonManager();
Services.prefs.setBoolPref("extensions.eventPages.enabled", true);
});
function createTestExtension({ privateAllowed }) {
return ExtensionTestUtils.loadExtension({
incognitoOverride: privateAllowed ? "spanning" : null,
manifest: {
permissions: ["cookies"],
host_permissions: ["https://example.com/"],
background: { persistent: false },
},
background() {
browser.cookies.onChanged.addListener(changeInfo => {
browser.test.sendMessage("cookie-event", changeInfo);
});
},
});
}
function addAndRemoveCookie({ isPrivate }) {
const cookie = {
name: "cookname",
value: "cookvalue",
domain: "example.com",
hostOnly: true,
path: "/",
secure: true,
httpOnly: false,
sameSite: "lax",
session: false,
firstPartyDomain: "",
partitionKey: null,
expirationDate: Date.now() + 3600000,
storeId: isPrivate ? "firefox-private" : "firefox-default",
};
const originAttributes = { privateBrowsingId: isPrivate ? 1 : 0 };
Services.cookies.add(
cookie.domain,
cookie.path,
cookie.name,
cookie.value,
cookie.secure,
cookie.httpOnly,
cookie.session,
cookie.expirationDate,
originAttributes,
Ci.nsICookie.SAMESITE_LAX,
Ci.nsICookie.SCHEME_HTTPS
);
Services.cookies.remove(
cookie.domain,
cookie.name,
cookie.path,
originAttributes
);
return cookie;
}
add_task(async function test_onChanged_event_page() {
let nonPrivateExtension = createTestExtension({ privateAllowed: false });
let privateExtension = createTestExtension({ privateAllowed: true });
await privateExtension.startup();
await nonPrivateExtension.startup();
assertPersistentListeners(privateExtension, "cookies", "onChanged", {
primed: false,
});
assertPersistentListeners(nonPrivateExtension, "cookies", "onChanged", {
primed: false,
});
// Suspend both event pages.
await privateExtension.terminateBackground();
assertPersistentListeners(privateExtension, "cookies", "onChanged", {
primed: true,
});
await nonPrivateExtension.terminateBackground();
assertPersistentListeners(nonPrivateExtension, "cookies", "onChanged", {
primed: true,
});
// Modifying a private cookie should wake up the private extension, but not
// the other one that does not have access to private browsing data.
let privateCookie = addAndRemoveCookie({ isPrivate: true });
Assert.deepEqual(
await privateExtension.awaitMessage("cookie-event"),
{ removed: false, cookie: privateCookie, cause: "explicit" },
"cookies.onChanged for private cookie creation"
);
Assert.deepEqual(
await privateExtension.awaitMessage("cookie-event"),
{ removed: true, cookie: privateCookie, cause: "explicit" },
"cookies.onChanged for private cookie removal"
);
// Private extension should have awakened...
assertPersistentListeners(privateExtension, "cookies", "onChanged", {
primed: false,
});
// ... but the non-private extension should still be sound asleep.
assertPersistentListeners(nonPrivateExtension, "cookies", "onChanged", {
primed: true,
});
// A non-private cookie modification should notify both extensions.
let nonPrivateCookie = addAndRemoveCookie({ isPrivate: false });
Assert.deepEqual(
await privateExtension.awaitMessage("cookie-event"),
{ removed: false, cookie: nonPrivateCookie, cause: "explicit" },
"cookies.onChanged for cookie creation in privateExtension"
);
Assert.deepEqual(
await privateExtension.awaitMessage("cookie-event"),
{ removed: true, cookie: nonPrivateCookie, cause: "explicit" },
"cookies.onChanged for cookie removal in privateExtension"
);
Assert.deepEqual(
await nonPrivateExtension.awaitMessage("cookie-event"),
{ removed: false, cookie: nonPrivateCookie, cause: "explicit" },
"cookies.onChanged for cookie creation in nonPrivateExtension"
);
Assert.deepEqual(
await nonPrivateExtension.awaitMessage("cookie-event"),
{ removed: true, cookie: nonPrivateCookie, cause: "explicit" },
"cookies.onChanged for cookie removal in nonPrivateCookie"
);
await privateExtension.unload();
await nonPrivateExtension.unload();
});