418 lines
13 KiB
HTML
418 lines
13 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Test for notifications</title>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
|
|
<script type="text/javascript" src="/tests/dom/notification/test/mochitest/MockAlertsService.js"></script>
|
|
<script src="head.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
</head>
|
|
<body>
|
|
|
|
<script type="text/javascript">
|
|
"use strict";
|
|
|
|
// A 1x1 PNG image.
|
|
// Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
|
|
let image = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
|
|
"ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
|
|
const IMAGE_ARRAYBUFFER = Uint8Array.from(image, byte => byte.charCodeAt(0)).buffer;
|
|
|
|
add_setup(async function setup_mock_alert_service() {
|
|
await MockAlertsService.register();
|
|
});
|
|
|
|
add_task(async function test_notification() {
|
|
async function background() {
|
|
let opts = {
|
|
type: "basic",
|
|
title: "Testing Notification",
|
|
message: "Carry on",
|
|
};
|
|
|
|
let id = await browser.notifications.create(opts);
|
|
|
|
browser.test.sendMessage("running", id);
|
|
browser.test.notifyPass("background test passed");
|
|
}
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
});
|
|
await extension.startup();
|
|
let x = await extension.awaitMessage("running");
|
|
is(x, "0", "got correct id from notifications.create");
|
|
await extension.awaitFinish();
|
|
await extension.unload();
|
|
});
|
|
|
|
add_task(async function test_notification_events() {
|
|
async function background() {
|
|
let opts = {
|
|
type: "basic",
|
|
title: "Testing Notification",
|
|
message: "Carry on",
|
|
};
|
|
|
|
let createdId = "98";
|
|
|
|
// Test an ignored listener.
|
|
browser.notifications.onButtonClicked.addListener(function() {});
|
|
|
|
// We cannot test onClicked listener without a mock
|
|
// but we can attempt to add a listener.
|
|
browser.notifications.onClicked.addListener(async function(id) {
|
|
browser.test.assertEq(createdId, id, "onClicked has the expected ID");
|
|
browser.test.sendMessage("notification-event", "clicked");
|
|
});
|
|
|
|
browser.notifications.onShown.addListener(async function listener(id) {
|
|
browser.test.assertEq(createdId, id, "onShown has the expected ID");
|
|
browser.test.sendMessage("notification-event", "shown");
|
|
});
|
|
|
|
browser.test.onMessage.addListener(async function(msg, expectedCount) {
|
|
if (msg === "create-again") {
|
|
let newId = await browser.notifications.create(createdId, opts);
|
|
browser.test.assertEq(createdId, newId, "create returned the expected id.");
|
|
browser.test.sendMessage("notification-created-twice");
|
|
} else if (msg === "check-count") {
|
|
let notifications = await browser.notifications.getAll();
|
|
let ids = Object.keys(notifications);
|
|
browser.test.assertEq(expectedCount, ids.length, `getAll() = ${ids}`);
|
|
browser.test.sendMessage("check-count-result");
|
|
}
|
|
});
|
|
|
|
// Test onClosed listener.
|
|
browser.notifications.onClosed.addListener(function listener(id) {
|
|
browser.test.assertEq(createdId, id, "onClosed received the expected id.");
|
|
browser.test.sendMessage("notification-event", "closed");
|
|
});
|
|
|
|
await browser.notifications.create(createdId, opts);
|
|
|
|
browser.test.sendMessage("notification-created-once");
|
|
}
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
});
|
|
|
|
await extension.startup();
|
|
|
|
async function waitForNotificationEvent(name) {
|
|
info(`Waiting for notification event: ${name}`);
|
|
is(name, await extension.awaitMessage("notification-event"),
|
|
"Expected notification event");
|
|
}
|
|
async function checkNotificationCount(expectedCount) {
|
|
extension.sendMessage("check-count", expectedCount);
|
|
await extension.awaitMessage("check-count-result");
|
|
}
|
|
|
|
await extension.awaitMessage("notification-created-once");
|
|
await waitForNotificationEvent("shown");
|
|
await checkNotificationCount(1);
|
|
|
|
// On most platforms, clicking the notification closes it.
|
|
// But on macOS, the notification can repeatedly be clicked without closing.
|
|
await MockAlertsService.clickNotificationsWithoutClose();
|
|
await waitForNotificationEvent("clicked");
|
|
await checkNotificationCount(1);
|
|
await MockAlertsService.clickNotificationsWithoutClose();
|
|
await waitForNotificationEvent("clicked");
|
|
await checkNotificationCount(1);
|
|
await MockAlertsService.clickNotifications();
|
|
await waitForNotificationEvent("clicked");
|
|
await waitForNotificationEvent("closed");
|
|
await checkNotificationCount(0);
|
|
|
|
extension.sendMessage("create-again");
|
|
await extension.awaitMessage("notification-created-twice");
|
|
await waitForNotificationEvent("shown");
|
|
await checkNotificationCount(1);
|
|
|
|
await MockAlertsService.closeNotifications();
|
|
await waitForNotificationEvent("closed");
|
|
await checkNotificationCount(0);
|
|
|
|
await extension.unload();
|
|
});
|
|
|
|
add_task(async function test_notifications_events_in_event_page() {
|
|
function background() {
|
|
browser.notifications.onClicked.addListener(id => {
|
|
browser.test.sendMessage("onClicked", id);
|
|
});
|
|
browser.notifications.onShown.addListener(id => {
|
|
browser.test.sendMessage("onShown", id);
|
|
});
|
|
browser.notifications.onClosed.addListener(id => {
|
|
browser.test.sendMessage("onClosed", id);
|
|
});
|
|
}
|
|
async function tabScript() {
|
|
let id = await browser.notifications.create({
|
|
type: "basic",
|
|
title: "Testing Notification",
|
|
message: "Carry on",
|
|
});
|
|
browser.test.sendMessage("created_notification", id);
|
|
}
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
// Manifest V3 defaults to using event pages by default.
|
|
manifest_version: 3,
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
files: {
|
|
"page.js": tabScript,
|
|
"page.html": `<!DOCTYPE html><script src="page.js"><\/script>`,
|
|
},
|
|
});
|
|
await extension.startup();
|
|
await extension.terminateBackground();
|
|
|
|
let tab = await AppTestDelegate.openNewForegroundTab(
|
|
window,
|
|
`moz-extension://${extension.uuid}/page.html`
|
|
);
|
|
let id = await extension.awaitMessage("created_notification");
|
|
ok(id, "Created notification");
|
|
let shownId = await extension.awaitMessage("onShown");
|
|
is(shownId, id, "onShown should wake up event page");
|
|
|
|
await extension.terminateBackground();
|
|
|
|
await MockAlertsService.clickNotificationsWithoutClose();
|
|
let clickedId = await extension.awaitMessage("onClicked");
|
|
is(clickedId, id, "onClicked should wake up event page");
|
|
|
|
await extension.terminateBackground();
|
|
|
|
// On most platforms, clicking the notification closes it.
|
|
// MockAlertsService.clickNotificationsWithoutClose() was used above to
|
|
// simulate clicking without closing across all platforms, so here we can
|
|
// simulate closing all (=the only one notification) without clicking:
|
|
await MockAlertsService.closeNotifications();
|
|
let closedId = await extension.awaitMessage("onClosed");
|
|
is(closedId, id, "onClosed should wake up event page");
|
|
|
|
// The above confirms the behavior from the API perspective; for completeness
|
|
// also verify the internal state, like all other tests that check persistent
|
|
// listeners:
|
|
await assertPersistentListeners(
|
|
extension,
|
|
"notifications",
|
|
["onClicked", "onClosed", "onShown"],
|
|
{ primed: false }
|
|
);
|
|
await extension.terminateBackground();
|
|
await assertPersistentListeners(
|
|
extension,
|
|
"notifications",
|
|
["onClicked", "onClosed", "onShown"],
|
|
{ primed: true }
|
|
);
|
|
|
|
await AppTestDelegate.removeTab(window, tab);
|
|
await extension.unload();
|
|
});
|
|
|
|
add_task(async function test_notification_clear() {
|
|
function background() {
|
|
let opts = {
|
|
type: "basic",
|
|
title: "Testing Notification",
|
|
message: "Carry on",
|
|
};
|
|
|
|
let createdId = "99";
|
|
|
|
browser.notifications.onShown.addListener(async id => {
|
|
browser.test.assertEq(createdId, id, "onShown received the expected id.");
|
|
let wasCleared = await browser.notifications.clear(id);
|
|
browser.test.assertTrue(wasCleared, "notifications.clear returned true.");
|
|
});
|
|
|
|
browser.notifications.onClosed.addListener(id => {
|
|
browser.test.assertEq(createdId, id, "onClosed received the expected id.");
|
|
browser.test.notifyPass("background test passed");
|
|
});
|
|
|
|
browser.notifications.create(createdId, opts);
|
|
}
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
});
|
|
|
|
await extension.startup();
|
|
await extension.awaitFinish();
|
|
await extension.unload();
|
|
});
|
|
|
|
add_task(async function test_notifications_empty_getAll() {
|
|
async function background() {
|
|
let notifications = await browser.notifications.getAll();
|
|
|
|
browser.test.assertEq("object", typeof notifications, "getAll() returned an object");
|
|
browser.test.assertEq(0, Object.keys(notifications).length, "the object has no properties");
|
|
browser.test.notifyPass("getAll empty");
|
|
}
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
});
|
|
await extension.startup();
|
|
await extension.awaitFinish("getAll empty");
|
|
await extension.unload();
|
|
});
|
|
|
|
add_task(async function test_notifications_populated_getAll() {
|
|
async function background() {
|
|
let opts = {
|
|
type: "basic",
|
|
iconUrl: "a.png",
|
|
title: "Testing Notification",
|
|
message: "Carry on",
|
|
};
|
|
|
|
await browser.notifications.create("p1", opts);
|
|
await browser.notifications.create("p2", opts);
|
|
let notifications = await browser.notifications.getAll();
|
|
|
|
browser.test.assertEq("object", typeof notifications, "getAll() returned an object");
|
|
browser.test.assertEq(2, Object.keys(notifications).length, "the object has 2 properties");
|
|
|
|
for (let notificationId of ["p1", "p2"]) {
|
|
for (let key of Object.keys(opts)) {
|
|
browser.test.assertEq(
|
|
opts[key],
|
|
notifications[notificationId][key],
|
|
`the notification has the expected value for option: ${key}`
|
|
);
|
|
}
|
|
}
|
|
|
|
browser.test.notifyPass("getAll populated");
|
|
}
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
files: {
|
|
"a.png": IMAGE_ARRAYBUFFER,
|
|
},
|
|
});
|
|
await extension.startup();
|
|
await extension.awaitFinish("getAll populated");
|
|
await extension.unload();
|
|
});
|
|
|
|
add_task(async function test_buttons_unsupported() {
|
|
function background() {
|
|
let opts = {
|
|
type: "basic",
|
|
title: "Testing Notification",
|
|
message: "Carry on",
|
|
buttons: [{title: "Button title"}],
|
|
};
|
|
|
|
let exception = {};
|
|
try {
|
|
browser.notifications.create(opts);
|
|
} catch (e) {
|
|
exception = e;
|
|
}
|
|
|
|
browser.test.assertTrue(
|
|
String(exception).includes('Property "buttons" is unsupported by Firefox'),
|
|
"notifications.create with buttons option threw an expected exception"
|
|
);
|
|
browser.test.notifyPass("buttons-unsupported");
|
|
}
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
});
|
|
await extension.startup();
|
|
await extension.awaitFinish("buttons-unsupported");
|
|
await extension.unload();
|
|
});
|
|
|
|
add_task(async function test_notifications_different_contexts() {
|
|
async function background() {
|
|
let opts = {
|
|
type: "basic",
|
|
title: "Testing Notification",
|
|
message: "Carry on",
|
|
};
|
|
|
|
let id = await browser.notifications.create(opts);
|
|
|
|
browser.runtime.onMessage.addListener(async (message, sender) => {
|
|
await browser.tabs.remove(sender.tab.id);
|
|
|
|
// We should be able to clear the notification after creating and
|
|
// destroying the tab.html page.
|
|
let wasCleared = await browser.notifications.clear(id);
|
|
browser.test.assertTrue(wasCleared, "The notification was cleared.");
|
|
browser.test.notifyPass("notifications");
|
|
});
|
|
|
|
browser.tabs.create({url: browser.runtime.getURL("/tab.html")});
|
|
}
|
|
|
|
async function tabScript() {
|
|
// We should be able to see the notification created in the background page
|
|
// in this page.
|
|
let notifications = await browser.notifications.getAll();
|
|
browser.test.assertEq(1, Object.keys(notifications).length,
|
|
"One notification found.");
|
|
browser.runtime.sendMessage("continue-test");
|
|
}
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
manifest: {
|
|
permissions: ["notifications"],
|
|
},
|
|
background,
|
|
files: {
|
|
"tab.js": tabScript,
|
|
"tab.html": `<!DOCTYPE html><html><head>
|
|
<meta charset="utf-8">
|
|
<script src="tab.js"><\/script>
|
|
</head></html>`,
|
|
},
|
|
});
|
|
|
|
await extension.startup();
|
|
await extension.awaitFinish("notifications");
|
|
await extension.unload();
|
|
});
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|