summaryrefslogtreecommitdiffstats
path: root/dom/base/test/browser_multiple_popups.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/test/browser_multiple_popups.js')
-rw-r--r--dom/base/test/browser_multiple_popups.js296
1 files changed, 296 insertions, 0 deletions
diff --git a/dom/base/test/browser_multiple_popups.js b/dom/base/test/browser_multiple_popups.js
new file mode 100644
index 0000000000..2e72cdce81
--- /dev/null
+++ b/dom/base/test/browser_multiple_popups.js
@@ -0,0 +1,296 @@
+/**
+ * In this test, we check that the content can't open more than one popup at a
+ * time (depending on "dom.allow_mulitple_popups" preference value).
+ */
+
+const TEST_DOMAIN = "http://example.net";
+const TEST_PATH = "/browser/dom/base/test/";
+const CHROME_DOMAIN = "chrome://mochitests/content";
+
+requestLongerTimeout(2);
+
+function promisePopups(count) {
+ let windows = [];
+ return new Promise(resolve => {
+ if (count == 0) {
+ resolve([]);
+ return;
+ }
+
+ let windowObserver = function(aSubject, aTopic, aData) {
+ if (aTopic != "domwindowopened") {
+ return;
+ }
+ windows.push(aSubject);
+ if (--count == 0) {
+ Services.ww.unregisterNotification(windowObserver);
+ SimpleTest.executeSoon(() => resolve(windows));
+ }
+ };
+ Services.ww.registerNotification(windowObserver);
+ });
+}
+
+async function withTestPage(popupCount, optionsOrCallback, callback) {
+ let options = optionsOrCallback;
+ if (!callback) {
+ callback = optionsOrCallback;
+ options = {};
+ }
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["dom.block_multiple_popups", true],
+ ["dom.disable_open_during_load", true],
+ ],
+ });
+
+ let domain = options.chrome ? CHROME_DOMAIN : TEST_DOMAIN;
+ let tab = BrowserTestUtils.addTab(
+ gBrowser,
+ domain + TEST_PATH + "browser_multiple_popups.html" + (options.query || "")
+ );
+ gBrowser.selectedTab = tab;
+
+ let browser = gBrowser.getBrowserForTab(tab);
+ await BrowserTestUtils.browserLoaded(browser);
+
+ let obs = promisePopups(popupCount);
+
+ await callback(browser);
+
+ let windows = await obs;
+ ok(true, `We had ${popupCount} windows.`);
+ for (let win of windows) {
+ if (win.document.readyState !== "complete") {
+ await BrowserTestUtils.waitForEvent(win, "load");
+ }
+ await BrowserTestUtils.closeWindow(win);
+ }
+ BrowserTestUtils.removeTab(tab);
+}
+
+function promisePopupsBlocked(browser, expectedCount) {
+ return SpecialPowers.spawn(browser, [expectedCount], count => {
+ return new content.Promise(resolve => {
+ content.addEventListener("DOMPopupBlocked", function cb() {
+ if (--count == 0) {
+ content.removeEventListener("DOMPopupBlocked", cb);
+ ok(true, "The popup has been blocked");
+ resolve();
+ }
+ });
+ });
+ });
+}
+
+function startOpeningTwoPopups(browser) {
+ return SpecialPowers.spawn(browser.browsingContext, [], () => {
+ let p = content.document.createElement("p");
+ p.setAttribute("id", "start");
+ content.document.body.appendChild(p);
+ });
+}
+
+add_task(async _ => {
+ info("All opened if the pref is off");
+ await withTestPage(2, async function(browser) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["dom.block_multiple_popups", false],
+ ["dom.disable_open_during_load", true],
+ ],
+ });
+
+ await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, browser);
+ });
+});
+
+add_task(async _ => {
+ info("2 window.open()s in a click event allowed because whitelisted domain.");
+
+ const uri = Services.io.newURI(TEST_DOMAIN);
+ const principal = Services.scriptSecurityManager.createContentPrincipal(
+ uri,
+ {}
+ );
+
+ Services.perms.addFromPrincipal(
+ principal,
+ "popup",
+ Services.perms.ALLOW_ACTION
+ );
+
+ await withTestPage(2, async function(browser) {
+ await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, browser);
+ });
+
+ await new Promise(resolve => {
+ Services.clearData.deleteData(
+ Ci.nsIClearDataService.CLEAR_PERMISSIONS,
+ value => {
+ Assert.equal(value, 0);
+ resolve();
+ }
+ );
+ });
+});
+
+add_task(async _ => {
+ info(
+ "2 window.open()s in a mouseup event allowed because whitelisted domain."
+ );
+
+ const uri = Services.io.newURI(TEST_DOMAIN);
+ const principal = Services.scriptSecurityManager.createContentPrincipal(
+ uri,
+ {}
+ );
+
+ Services.perms.addFromPrincipal(
+ principal,
+ "popup",
+ Services.perms.ALLOW_ACTION
+ );
+
+ await withTestPage(2, async function(browser) {
+ await BrowserTestUtils.synthesizeMouseAtCenter("#input", {}, browser);
+ });
+
+ await new Promise(aResolve => {
+ Services.clearData.deleteData(
+ Ci.nsIClearDataService.CLEAR_PERMISSIONS,
+ value => {
+ Assert.equal(value, 0);
+ aResolve();
+ }
+ );
+ });
+});
+
+add_task(async _ => {
+ info(
+ "2 window.open()s in a single click event: only the first one is allowed."
+ );
+
+ await withTestPage(1, async function(browser) {
+ let p = promisePopupsBlocked(browser, 1);
+ await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, browser);
+ await p;
+ });
+});
+
+add_task(async _ => {
+ info(
+ "2 window.open()s in a single mouseup event: only the first one is allowed."
+ );
+
+ await withTestPage(1, async function(browser) {
+ let p = promisePopupsBlocked(browser, 1);
+ await BrowserTestUtils.synthesizeMouseAtCenter("#input", {}, browser);
+ await p;
+ });
+});
+
+add_task(async _ => {
+ info("2 window.open()s by non-event code: no windows allowed.");
+
+ await withTestPage(0, { query: "?openPopups" }, async function(browser) {
+ let p = promisePopupsBlocked(browser, 2);
+ await startOpeningTwoPopups(browser);
+ await p;
+ });
+});
+
+add_task(async _ => {
+ info("2 window.open()s by non-event code allowed by permission");
+ const uri = Services.io.newURI(TEST_DOMAIN);
+ const principal = Services.scriptSecurityManager.createContentPrincipal(
+ uri,
+ {}
+ );
+
+ Services.perms.addFromPrincipal(
+ principal,
+ "popup",
+ Services.perms.ALLOW_ACTION
+ );
+
+ await withTestPage(2, { query: "?openPopups" }, async function(browser) {
+ await startOpeningTwoPopups(browser);
+ });
+
+ await new Promise(aResolve => {
+ Services.clearData.deleteData(
+ Ci.nsIClearDataService.CLEAR_PERMISSIONS,
+ value => {
+ Assert.equal(value, 0);
+ aResolve();
+ }
+ );
+ });
+});
+
+add_task(async _ => {
+ info(
+ "1 window.open() executing another window.open(): only the first one is allowed."
+ );
+
+ await withTestPage(1, async function(browser) {
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#openNestedPopups",
+ {},
+ browser
+ );
+ });
+});
+
+add_task(async _ => {
+ info("window.open() and .click() on the element opening the window.");
+
+ await withTestPage(1, async function(browser) {
+ let p = promisePopupsBlocked(browser, 1);
+
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#openPopupAndClick",
+ {},
+ browser
+ );
+
+ await p;
+ });
+});
+
+add_task(async _ => {
+ info("All opened from chrome.");
+ await withTestPage(2, { chrome: true }, async function(browser) {
+ await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, browser);
+ });
+});
+
+add_task(async function test_bug_1685056() {
+ info(
+ "window.open() from a blank iframe window during an event dispatched at the parent page: window should be allowed"
+ );
+
+ await withTestPage(1, async function(browser) {
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#openPopupInFrame",
+ {},
+ browser
+ );
+ });
+});
+
+add_task(async function test_bug_1689853() {
+ info("window.open() from a js bookmark (LOAD_FLAGS_ALLOW_POPUPS)");
+ await withTestPage(1, async function(browser) {
+ const URI =
+ "javascript:void(window.open('empty.html', '_blank', 'width=100,height=100'));";
+ window.openTrustedLinkIn(URI, "current", {
+ allowPopups: true,
+ inBackground: false,
+ allowInheritPrincipal: true,
+ });
+ });
+});