diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /toolkit/components/alerts/test | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | toolkit/components/alerts/test/browser.ini | 5 | ||||
-rw-r--r-- | toolkit/components/alerts/test/browser_bug1682866.js | 56 | ||||
-rw-r--r-- | toolkit/components/alerts/test/file_bug1682866.html | 9 | ||||
-rw-r--r-- | toolkit/components/alerts/test/image.gif | bin | 0 -> 60901 bytes | |||
-rw-r--r-- | toolkit/components/alerts/test/image.png | bin | 0 -> 2531 bytes | |||
-rw-r--r-- | toolkit/components/alerts/test/image_server.sjs | 92 | ||||
-rw-r--r-- | toolkit/components/alerts/test/mochitest.ini | 18 | ||||
-rw-r--r-- | toolkit/components/alerts/test/test_alerts.html | 89 | ||||
-rw-r--r-- | toolkit/components/alerts/test/test_alerts_noobserve.html | 91 | ||||
-rw-r--r-- | toolkit/components/alerts/test/test_alerts_requireinteraction.html | 162 | ||||
-rw-r--r-- | toolkit/components/alerts/test/test_image.html | 117 | ||||
-rw-r--r-- | toolkit/components/alerts/test/test_multiple_alerts.html | 97 | ||||
-rw-r--r-- | toolkit/components/alerts/test/test_principal.html | 121 |
13 files changed, 857 insertions, 0 deletions
diff --git a/toolkit/components/alerts/test/browser.ini b/toolkit/components/alerts/test/browser.ini new file mode 100644 index 0000000000..6c4b032b92 --- /dev/null +++ b/toolkit/components/alerts/test/browser.ini @@ -0,0 +1,5 @@ +[browser_bug1682866.js] +skip-if = !fission +support-files = + file_bug1682866.html + diff --git a/toolkit/components/alerts/test/browser_bug1682866.js b/toolkit/components/alerts/test/browser_bug1682866.js new file mode 100644 index 0000000000..619f833934 --- /dev/null +++ b/toolkit/components/alerts/test/browser_bug1682866.js @@ -0,0 +1,56 @@ +const baseURL = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +const alertURL = `${baseURL}file_bug1682866.html`; + +add_task(async function testAlertForceClosed() { + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + alertURL, + true /* waitForLoad */ + ); + + // Open a second which is in the same process as tab + let secondTabIsLoaded = BrowserTestUtils.waitForNewTab( + gBrowser, + alertURL, + true, + false + ); + + let isSuspendedAfterAlert = await SpecialPowers.spawn( + tab.linkedBrowser.browsingContext, + [alertURL], + url => { + content.open(url); + var utils = SpecialPowers.getDOMWindowUtils(content); + return utils.isInputTaskManagerSuspended; + } + ); + + await secondTabIsLoaded; + + let secondTab = gBrowser.tabs[2]; + + is( + isSuspendedAfterAlert, + Services.prefs.getBoolPref("dom.input_events.canSuspendInBCG.enabled"), + "InputTaskManager should be suspended because alert is opened" + ); + + let alertClosed = BrowserTestUtils.waitForEvent( + tab.linkedBrowser, + "DOMModalDialogClosed" + ); + + BrowserTestUtils.loadURI(tab.linkedBrowser, "about:newtab"); + + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + + await alertClosed; + + gBrowser.removeTab(tab); + gBrowser.removeTab(secondTab); +}); diff --git a/toolkit/components/alerts/test/file_bug1682866.html b/toolkit/components/alerts/test/file_bug1682866.html new file mode 100644 index 0000000000..328edcbac5 --- /dev/null +++ b/toolkit/components/alerts/test/file_bug1682866.html @@ -0,0 +1,9 @@ +<html> + <body> + <script> + window.onload = function() { + alert("This is an alert"); + } + </script> + </body> +</html> diff --git a/toolkit/components/alerts/test/image.gif b/toolkit/components/alerts/test/image.gif Binary files differnew file mode 100644 index 0000000000..053b4d9261 --- /dev/null +++ b/toolkit/components/alerts/test/image.gif diff --git a/toolkit/components/alerts/test/image.png b/toolkit/components/alerts/test/image.png Binary files differnew file mode 100644 index 0000000000..430c3c5e65 --- /dev/null +++ b/toolkit/components/alerts/test/image.png diff --git a/toolkit/components/alerts/test/image_server.sjs b/toolkit/components/alerts/test/image_server.sjs new file mode 100644 index 0000000000..4caa21ce27 --- /dev/null +++ b/toolkit/components/alerts/test/image_server.sjs @@ -0,0 +1,92 @@ +const CC = Components.Constructor; + +let { setTimeout } = ChromeUtils.importESModule( + "resource://gre/modules/Timer.sys.mjs" +); + +const LocalFile = CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath"); + +const FileInputStream = CC( + "@mozilla.org/network/file-input-stream;1", + "nsIFileInputStream", + "init" +); + +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); + +function handleRequest(request, response) { + let params = parseQueryString(request.queryString); + + response.setStatusLine(request.httpVersion, 200, "OK"); + + // Compare and increment a cookie for this request. This is used to test + // private browsing mode; the cookie should not be set if the image is + // loaded anonymously. + if (params.has("c")) { + let expectedValue = parseInt(params.get("c"), 10); + let actualValue = !request.hasHeader("Cookie") + ? 0 + : parseInt( + request.getHeader("Cookie").replace(/^counter=(\d+)/, "$1"), + 10 + ); + if (actualValue != expectedValue) { + response.setStatusLine(request.httpVersion, 400, "Wrong counter value"); + return; + } + response.setHeader("Set-Cookie", `counter=${expectedValue + 1}`, false); + } + + // Wait to send the image if a timeout is given. + let timeout = parseInt(params.get("t"), 10); + if (timeout > 0) { + response.processAsync(); + setTimeout(() => { + respond(params, request, response); + response.finish(); + }, timeout * 1000); + return; + } + + respond(params, request, response); +} + +function parseQueryString(queryString) { + return queryString.split("&").reduce((params, param) => { + let [key, value] = param.split("=", 2); + params.set(key, value); + return params; + }, new Map()); +} + +function respond(params, request, response) { + if (params.has("s")) { + let statusCode = parseInt(params.get("s"), 10); + response.setStatusLine(request.httpVersion, statusCode, "Custom status"); + return; + } + var filename = params.get("f"); + writeFile(filename, response); +} + +function writeFile(name, response) { + var file = new LocalFile(getState("__LOCATION__")).parent; + file.append(name); + + let mimeType = Cc["@mozilla.org/uriloader/external-helper-app-service;1"] + .getService(Ci.nsIMIMEService) + .getTypeFromFile(file); + + let fileStream = new FileInputStream(file, 1, 0, false); + let binaryStream = new BinaryInputStream(fileStream); + + response.setHeader("Content-Type", mimeType, false); + response.bodyOutputStream.writeFrom(binaryStream, binaryStream.available()); + + binaryStream.close(); + fileStream.close(); +} diff --git a/toolkit/components/alerts/test/mochitest.ini b/toolkit/components/alerts/test/mochitest.ini new file mode 100644 index 0000000000..e2c22dfe4d --- /dev/null +++ b/toolkit/components/alerts/test/mochitest.ini @@ -0,0 +1,18 @@ +[DEFAULT] +skip-if = os == 'android' # We don't use XUL alerts on Android +support-files = + image.gif + image.png + image_server.sjs + +# Synchronous tests like test_alerts.html must come before +# asynchronous tests like test_alerts_noobserve.html! +[test_alerts.html] +(os == "win" && debug) # Bug 1407296 +[test_alerts_noobserve.html] +[test_alerts_requireinteraction.html] +skip-if = (verify && (os == 'linux')) +[test_image.html] +skip-if = verify +[test_multiple_alerts.html] +[test_principal.html] diff --git a/toolkit/components/alerts/test/test_alerts.html b/toolkit/components/alerts/test/test_alerts.html new file mode 100644 index 0000000000..84a5f20a3e --- /dev/null +++ b/toolkit/components/alerts/test/test_alerts.html @@ -0,0 +1,89 @@ +<!DOCTYPE HTML> +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<html> +<head> + <title>Test for Alerts Service</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> + +<body> +<p id="display"></p> + +<br>Alerts service, with observer "synchronous" case. +<br> +<br>Did a notification appear anywhere? +<br>If so, the test will finish once the notification disappears. + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var notifier; +var alertName = "fiorello"; + +var observer = { + alertShow: false, + observe(aSubject, aTopic, aData) { + is(aData, "foobarcookie", "Checking whether the alert cookie was passed correctly"); + if (aTopic == "alertclickcallback") { + todo(false, "Did someone click the notification while running mochitests? (Please don't.)"); + } else if (aTopic == "alertshow") { + ok(!this.alertShow, "Alert should not be shown more than once"); + this.alertShow = true; + + // Notifications are native on OS X 10.8 and later, GNOME Shell with + // libnotify (bug 1236036) and Windows >= 8. These notifications persist + // in the Notification Center, and only fire the `alertfinished` event + // when closed. For platforms where native notifications may be used, we + // need to close explicitly to avoid a hang. This also works for XUL + // notifications when running this test on OS X < 10.8, or a window + // manager like Ubuntu Unity with incomplete libnotify support. + notifier.closeAlert(alertName); + } else { + is(aTopic, "alertfinished", "Checking the topic for a finished notification"); + SimpleTest.finish(); + } + }, +}; + +function runTest() { + const Cc = SpecialPowers.Cc; + const Ci = SpecialPowers.Ci; + + if (!("@mozilla.org/alerts-service;1" in Cc)) { + todo(false, "Alerts service does not exist in this application"); + return; + } + + ok(true, "Alerts service exists in this application"); + + try { + notifier = Cc["@mozilla.org/alerts-service;1"]. + getService(Ci.nsIAlertsService); + ok(true, "Alerts service is available"); + } catch (ex) { + todo(false, + "Alerts service is not available.", ex); + return; + } + + try { + SimpleTest.waitForExplicitFinish(); + notifier.showAlertNotification(null, "Notification test", + "Surprise! I'm here to test notifications!", + false, "foobarcookie", observer, alertName); + ok(true, "showAlertNotification() succeeded. Waiting for notification..."); + } catch (ex) { + todo(false, "showAlertNotification() failed.", ex); + SimpleTest.finish(); + } +} + +SimpleTest.requestCompleteLog(); // Bug 1407296 +runTest(); + +</script> +</pre> +</body> +</html> diff --git a/toolkit/components/alerts/test/test_alerts_noobserve.html b/toolkit/components/alerts/test/test_alerts_noobserve.html new file mode 100644 index 0000000000..6b759827cf --- /dev/null +++ b/toolkit/components/alerts/test/test_alerts_noobserve.html @@ -0,0 +1,91 @@ +<!DOCTYPE HTML> +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<html> +<head> + <title>Test for Alerts Service</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> + +<body> +<p id="display"></p> + +<br>Alerts service, without observer "asynchronous" case. +<br> +<br>A notification should soon appear somewhere. +<br>If there has been no crash when the notification (later) disappears, assume all is good. + +<pre id="test"> +<script class="testbody" type="text/javascript"> +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +const chromeScript = SpecialPowers.loadChromeScript(_ => { + /* eslint-env mozilla/chrome-script */ + const {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm"); + + function anyXULAlertsVisible() { + var windows = Services.wm.getEnumerator("alert:alert"); + return windows.hasMoreElements(); + } + + addMessageListener("anyXULAlertsVisible", anyXULAlertsVisible); + + addMessageListener("waitForAlerts", function waitForAlerts() { + if (anyXULAlertsVisible()) { + setTimeout(waitForAlerts, 1000); + } else { + sendAsyncMessage("waitedForAlerts"); + } + }); +}); + +function waitForAlertsThenFinish() { + chromeScript.addMessageListener("waitedForAlerts", function waitedForAlerts() { + chromeScript.removeMessageListener("waitedForAlerts", waitedForAlerts); + ok(true, "Alert disappeared."); + SimpleTest.finish(); + }); + chromeScript.sendAsyncMessage("waitForAlerts"); +} + +async function runTest() { + var alertsVisible = await chromeScript.sendQuery("anyXULAlertsVisible"); + ok(!alertsVisible, "Alerts should not be present at the start of the test."); + + if (!("@mozilla.org/alerts-service;1" in Cc)) { + todo(false, "Alerts service does not exist in this application"); + } else { + ok(true, "Alerts service exists in this application"); + + var notifier; + try { + notifier = Cc["@mozilla.org/alerts-service;1"]. + getService(Ci.nsIAlertsService); + ok(true, "Alerts service is available"); + } catch (ex) { + todo(false, "Alerts service is not available.", ex); + } + + if (notifier) { + try { + notifier.showAlertNotification(null, "Notification test", + "This notification has no observer"); + ok(true, "showAlertNotification() succeeded"); + } catch (ex) { + todo(false, "showAlertNotification() failed.", ex); + } + } + } +} + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +runTest(); +setTimeout(waitForAlertsThenFinish, 1000); +</script> +</pre> +</body> +</html> diff --git a/toolkit/components/alerts/test/test_alerts_requireinteraction.html b/toolkit/components/alerts/test/test_alerts_requireinteraction.html new file mode 100644 index 0000000000..c8dc02f621 --- /dev/null +++ b/toolkit/components/alerts/test/test_alerts_requireinteraction.html @@ -0,0 +1,162 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for alerts with requireInteraction</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +const chromeScript = SpecialPowers.loadChromeScript(_ => { + /* eslint-env mozilla/chrome-script */ + const {clearTimeout, setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm"); + + addMessageListener("waitForXULAlert", function() { + var timer = setTimeout(function() { + Services.ww.unregisterNotification(windowObserver); + sendAsyncMessage("waitForXULAlert", false); + }, 2000); + + var windowObserver = function(win, aTopic, aData) { + if (aTopic != "domwindowopened") { + return; + } + + win.addEventListener("load", function() { + let windowType = win.document.documentElement.getAttribute("windowtype"); + if (windowType == "alert:alert") { + clearTimeout(timer); + Services.ww.unregisterNotification(windowObserver); + + sendAsyncMessage("waitForXULAlert", true); + } + }, {once: true}); + }; + + Services.ww.registerNotification(windowObserver); + }); +}); + +var cookie = 0; +function promiseCreateXULAlert(alertService, listener, name) { + return new Promise(resolve => { + chromeScript.addMessageListener("waitForXULAlert", function waitedForAlert(result) { + chromeScript.removeMessageListener("waitForXULAlert", waitedForAlert); + resolve(result); + }); + + chromeScript.sendAsyncMessage("waitForXULAlert"); + alertService.showAlertNotification(null, "title", "body", + true, cookie++, listener, name, null, null, null, + null, false, true); + }); +} + +add_task(async function test_require_interaction() { + if (!("@mozilla.org/alerts-service;1" in Cc)) { + todo(false, "Alerts service does not exist in this application."); + return; + } + + ok(true, "Alerts service exists in this application."); + + var alertService; + try { + alertService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); + ok(true, "Alerts service is available."); + } catch (ex) { + todo(false, "Alerts service is not available."); + return; + } + + await SpecialPowers.pushPrefEnv({"set": [ + [ "dom.webnotifications.requireinteraction.enabled", true ], + [ "dom.webnotifications.requireinteraction.count", 2 ], + ]}); + + var expectedSequence = [ + "first show", + "second show", + "second finished", + "second replacement show", + "third finished", + "first finished", + "third replacement show", + "second replacement finished", + "third replacement finished", + ]; + + var actualSequence = []; + + function createAlertListener(name, showCallback, finishCallback) { + return (subject, topic, data) => { + if (topic == "alertshow") { + actualSequence.push(name + " show"); + if (showCallback) { + showCallback(); + } + } else if (topic == "alertfinished") { + actualSequence.push(name + " finished"); + if (finishCallback) { + finishCallback(); + } + } + }; + } + + var xulAlertCreated = await promiseCreateXULAlert(alertService, + createAlertListener("first"), "first"); + if (!xulAlertCreated) { + ok(true, "Platform does not use XUL alerts."); + alertService.closeAlert("first"); + return; + } + + xulAlertCreated = await promiseCreateXULAlert(alertService, + createAlertListener("second"), "second"); + ok(xulAlertCreated, "Create XUL alert"); + + // Replace second alert + xulAlertCreated = await promiseCreateXULAlert(alertService, + createAlertListener("second replacement"), "second"); + ok(xulAlertCreated, "Create XUL alert"); + + var testFinishResolve; + var testFinishPromise = new Promise((resolve) => { testFinishResolve = resolve; }); + + xulAlertCreated = await promiseCreateXULAlert(alertService, + createAlertListener("third"), "third"); + ok(!xulAlertCreated, "XUL alert should not be visible"); + + // Replace the not-yet-visible third alert. + xulAlertCreated = await promiseCreateXULAlert(alertService, + createAlertListener("third replacement", + function showCallback() { + alertService.closeAlert("second"); + alertService.closeAlert("third"); + }, + function finishCallback() { + // Check actual sequence of alert events compared to expected sequence. + for (var i = 0; i < actualSequence.length; i++) { + is(actualSequence[i], expectedSequence[i], + "Alert callback at index " + i + " should be in expected order."); + } + + testFinishResolve(); + }), "third"); + + ok(!xulAlertCreated, "XUL alert should not be visible"); + + alertService.closeAlert("first"); + + await testFinishPromise; +}); + +</script> +</pre> +</body> +</html> diff --git a/toolkit/components/alerts/test/test_image.html b/toolkit/components/alerts/test/test_image.html new file mode 100644 index 0000000000..3928529c13 --- /dev/null +++ b/toolkit/components/alerts/test/test_image.html @@ -0,0 +1,117 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 1233086</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> + +<body> +<p id="display"></p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; +const Services = SpecialPowers.Services; + +const imageServerURL = "http://mochi.test:8888/tests/toolkit/components/alerts/test/image_server.sjs"; + +function makeAlert(...params) { + var alert = Cc["@mozilla.org/alert-notification;1"] + .createInstance(Ci.nsIAlertNotification); + alert.init(...params); + return alert; +} + +function promiseImage(alert, timeout = 0, userData = null) { + return new Promise(resolve => { + var isDone = false; + function done(value) { + ok(!isDone, "Should call the image listener once"); + isDone = true; + resolve(value); + } + alert.loadImage(timeout, SpecialPowers.wrapCallbackObject({ + onImageReady(aUserData, aRequest) { + done([true, aRequest, aUserData]); + }, + onImageMissing(aUserData) { + done([false, aUserData]); + }, + }), SpecialPowers.wrap(userData)); + }); +} + +add_task(async function testContext() { + var inUserData = Cc["@mozilla.org/supports-PRInt64;1"] + .createInstance(Ci.nsISupportsPRInt64); + inUserData.data = 123; + + var alert = makeAlert(null, imageServerURL + "?f=image.png"); + var [ready, , userData] = await promiseImage(alert, 0, inUserData); + ok(ready, "Should load requested image"); + is(userData.QueryInterface(Ci.nsISupportsPRInt64).data, 123, + "Should pass user data for loaded image"); + + alert = makeAlert(null, imageServerURL + "?s=404"); + [ready, userData] = await promiseImage(alert, 0, inUserData); + ok(!ready, "Should not load missing image"); + is(userData.QueryInterface(Ci.nsISupportsPRInt64).data, 123, + "Should pass user data for missing image"); +}); + +add_task(async function testTimeout() { + var alert = makeAlert(null, imageServerURL + "?f=image.png&t=3"); + var [ready] = await promiseImage(alert, 1000); + ok(!ready, "Should cancel request if timeout fires"); + + [ready] = await promiseImage(alert, 45000); + ok(ready, "Should load image if request finishes before timeout"); +}); + +add_task(async function testAnimatedGIF() { + var alert = makeAlert(null, imageServerURL + "?f=image.gif"); + var [ready, request] = await promiseImage(alert); + ok(ready, "Should load first animated GIF frame"); + is(request.mimeType, "image/gif", "Should report correct GIF MIME type"); + is(request.image.width, 256, "GIF width should be 256px"); + is(request.image.height, 256, "GIF height should be 256px"); +}); + +add_task(async function testCancel() { + var alert = makeAlert(null, imageServerURL + "?f=image.gif&t=180"); + await new Promise((resolve, reject) => { + var request = alert.loadImage(0, SpecialPowers.wrapCallbackObject({ + onImageReady() { + reject(new Error("Should not load cancelled request")); + }, + onImageMissing() { + resolve(); + }, + }), null); + request.cancel(SpecialPowers.Cr.NS_BINDING_ABORTED); + }); +}); + +add_task(async function testMixedContent() { + // Loading principal is HTTPS; image URL is HTTP. + var origin = "https://mochi.test:8888"; + var principal = Services.scriptSecurityManager + .createContentPrincipalFromOrigin(origin); + + var alert = makeAlert(null, imageServerURL + "?f=image.png", + null, null, false, null, null, null, + null, principal); + var [ready, request] = await promiseImage(alert); + ok(ready, "Should load cross-protocol image"); + is(request.mimeType, "image/png", "Should report correct MIME type"); + is(request.image.width, 32, "Width should be 32px"); + is(request.image.height, 32, "Height should be 32px"); +}); + +</script> +</pre> +</body> +</html> diff --git a/toolkit/components/alerts/test/test_multiple_alerts.html b/toolkit/components/alerts/test/test_multiple_alerts.html new file mode 100644 index 0000000000..38989db99f --- /dev/null +++ b/toolkit/components/alerts/test/test_multiple_alerts.html @@ -0,0 +1,97 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for multiple alerts</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +const chromeScript = SpecialPowers.loadChromeScript(_ => { + /* eslint-env mozilla/chrome-script */ + const {clearTimeout, setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm"); + + const alertService = Cc["@mozilla.org/alerts-service;1"] + .getService(Ci.nsIAlertsService); + + addMessageListener("waitForPosition", function() { + var timer = setTimeout(function() { + Services.ww.unregisterNotification(windowObserver); + sendAsyncMessage("waitedForPosition", null); + }, 2000); + + var windowObserver = function(win, aTopic, aData) { + if (aTopic != "domwindowopened") { + return; + } + + // Alerts are implemented using XUL. + clearTimeout(timer); + + Services.ww.unregisterNotification(windowObserver); + + win.addEventListener("pageshow", function() { + var x = win.screenX; + var y = win.screenY; + + win.addEventListener("pagehide", function() { + sendAsyncMessage("waitedForPosition", { x, y }); + }, {once: true}); + + alertService.closeAlert(); + }, {once: true}); + }; + + Services.ww.registerNotification(windowObserver); + }); +}); + +function promiseAlertPosition(alertService) { + return new Promise(resolve => { + chromeScript.addMessageListener("waitedForPosition", function waitedForPosition(result) { + chromeScript.removeMessageListener("waitedForPosition", waitedForPosition); + resolve(result); + }); + chromeScript.sendAsyncMessage("waitForPosition"); + + alertService.showAlertNotification(null, "title", "body"); + ok(true, "Alert shown."); + }); +} + +add_task(async function test_multiple_alerts() { + if (!("@mozilla.org/alerts-service;1" in Cc)) { + todo(false, "Alerts service does not exist in this application."); + return; + } + + ok(true, "Alerts service exists in this application."); + + var alertService; + try { + alertService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); + ok(true, "Alerts service is available."); + } catch (ex) { + todo(false, "Alerts service is not available."); + return; + } + + var firstAlertPosition = await promiseAlertPosition(alertService); + if (!firstAlertPosition) { + ok(true, "Platform does not use XUL alerts."); + return; + } + + var secondAlertPosition = await promiseAlertPosition(alertService); + is(secondAlertPosition.x, firstAlertPosition.x, "Second alert should be opened in the same position."); + is(secondAlertPosition.y, firstAlertPosition.y, "Second alert should be opened in the same position."); +}); + +</script> +</pre> +</body> +</html> diff --git a/toolkit/components/alerts/test/test_principal.html b/toolkit/components/alerts/test/test_principal.html new file mode 100644 index 0000000000..f912d0d348 --- /dev/null +++ b/toolkit/components/alerts/test/test_principal.html @@ -0,0 +1,121 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 1202933</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> + +<body> +<p id="display"></p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; +const Services = SpecialPowers.Services; + +const notifier = Cc["@mozilla.org/alerts-service;1"] + .getService(Ci.nsIAlertsService); + +const chromeScript = SpecialPowers.loadChromeScript(_ => { + /* eslint-env mozilla/chrome-script */ + addMessageListener("anyXULAlertsVisible", function() { + var windows = Services.wm.getEnumerator("alert:alert"); + return windows.hasMoreElements(); + }); + + addMessageListener("getAlertSource", function() { + var alertWindows = Services.wm.getEnumerator("alert:alert"); + if (!alertWindows) { + return null; + } + var alertWindow = alertWindows.getNext(); + return alertWindow.document.getElementById("alertSourceLabel").getAttribute("value"); + }); +}); + +function notify(alertName, principal) { + return new Promise((resolve, reject) => { + var source; + async function observe(subject, topic, data) { + if (topic == "alertclickcallback") { + reject(new Error("Alerts should not be clicked during test")); + } else if (topic == "alertshow") { + source = await chromeScript.sendQuery("getAlertSource"); + notifier.closeAlert(alertName); + } else { + is(topic, "alertfinished", "Should hide alert"); + resolve(source); + } + } + notifier.showAlertNotification(null, "Notification test", + "Surprise! I'm here to test notifications!", + false, alertName, observe, alertName, + null, null, null, principal); + if (SpecialPowers.Services.appinfo.OS == "Darwin") { + notifier.closeAlert(alertName); + } + }); +} + +async function testNoPrincipal() { + var source = await notify("noPrincipal", null); + ok(!source, "Should omit source without principal"); +} + +async function testSystemPrincipal() { + var principal = Services.scriptSecurityManager.getSystemPrincipal(); + var source = await notify("systemPrincipal", principal); + ok(!source, "Should omit source for system principal"); +} + +async function testNullPrincipal() { + var principal = Services.scriptSecurityManager.createNullPrincipal({}); + var source = await notify("nullPrincipal", principal); + ok(!source, "Should omit source for null principal"); +} + +async function testNodePrincipal() { + var principal = SpecialPowers.wrap(document).nodePrincipal; + var source = await notify("nodePrincipal", principal); + + var stringBundle = Services.strings.createBundle( + "chrome://alerts/locale/alert.properties" + ); + var localizedSource = stringBundle.formatStringFromName( + "source.label", [principal.hostPort]); + is(source, localizedSource, "Should include source for node principal"); +} + +function runTest() { + if (!("@mozilla.org/alerts-service;1" in Cc)) { + todo(false, "Alerts service does not exist in this application"); + return; + } + + if ("@mozilla.org/system-alerts-service;1" in Cc) { + todo(false, "Native alerts service exists in this application"); + return; + } + + ok(true, "Alerts service exists in this application"); + + // sendSyncMessage returns an array of arrays. See the comments in + // test_alerts_noobserve.html and test_SpecialPowersLoadChromeScript.html. + add_task(async () => { + var alertsVisible = await chromeScript.sendQuery("anyXULAlertsVisible"); + ok(!alertsVisible, "Alerts should not be present at the start of the test."); + }); + + add_task(testNoPrincipal); + add_task(testSystemPrincipal); + add_task(testNullPrincipal); + add_task(testNodePrincipal); +} + +runTest(); +</script> +</pre> +</body> +</html> |