Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
const PAGE_URL = `${getRootDirectory(gTestPath).replace(
)}file_empty.html`;
const SHOWN_TOPIC = "web-notification-shown";
const CLOSED_TOPIC = "web-notification-closed";
// The system backend does not deliver alertshow/alertfinished on every
// platform, and cannot be driven from a test. The XUL backend is a real
// consumer of the same listener contract, so capture is exercised through it.
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["alerts.useSystemBackend", false]],
});
});
function captureNext(topic) {
return new Promise(resolve => {
Services.obs.addObserver(function observer(subject, observedTopic, data) {
Services.obs.removeObserver(observer, observedTopic);
resolve({ subject, data });
}, topic);
});
}
async function withNotificationPage(task) {
await BrowserTestUtils.withNewTab(PAGE_URL, async browser => {
await SpecialPowers.spawn(browser, [], async () => {
await SpecialPowers.pushPermissions([
{
type: "desktop-notification",
allow: SpecialPowers.Services.perms.ALLOW_ACTION,
context: content.document,
},
]);
});
await task(browser);
});
}
function showNotification(browser, title, options = {}) {
return SpecialPowers.spawn(browser, [title, options], async (t, opts) => {
const notification = new content.Notification(t, opts);
const { promise, resolve, reject } = Promise.withResolvers();
notification.onshow = () => resolve();
notification.onerror = () => reject(new Error("onerror"));
content.wrappedJSObject.notification = notification;
return promise;
});
}
add_task(async function show_is_captured() {
await withNotificationPage(async browser => {
const shown = captureNext(SHOWN_TOPIC);
await showNotification(browser, "hello", { body: "world", tag: "t1" });
const alert = (await shown).subject.QueryInterface(Ci.nsIAlertNotification);
is(alert.title, "hello", "Alert carries the title");
is(alert.text, "world", "Alert carries the body");
is(
alert.principal.origin,
"Alert carries the origin principal"
);
await SpecialPowers.spawn(browser, [], () =>
content.wrappedJSObject.notification.close()
);
});
});
add_task(async function close_is_captured() {
await withNotificationPage(async browser => {
const shown = captureNext(SHOWN_TOPIC);
await showNotification(browser, "bye", { tag: "t2" });
const name = (await shown).subject.QueryInterface(
Ci.nsIAlertNotification
).name;
const closed = captureNext(CLOSED_TOPIC);
await SpecialPowers.spawn(browser, [], () =>
content.wrappedJSObject.notification.close()
);
is(
(await closed).subject.QueryInterface(Ci.nsIAlertNotification).name,
name,
"Close reports the same notification"
);
});
});
add_task(async function kill_switch_suppresses_capture() {
await SpecialPowers.pushPrefEnv({
set: [["browser.alerts.capture.enabled", false]],
});
let fired = false;
const observer = () => {
fired = true;
};
Services.obs.addObserver(observer, SHOWN_TOPIC);
await withNotificationPage(async browser => {
await showNotification(browser, "quiet", { tag: "t3" });
ok(!fired, "No capture topic fired while the kill switch is off");
await SpecialPowers.spawn(browser, [], () =>
content.wrappedJSObject.notification.close()
);
});
Services.obs.removeObserver(observer, SHOWN_TOPIC);
await SpecialPowers.popPrefEnv();
});