diff options
Diffstat (limited to 'dom/base/test/browser_multiple_popups.js')
-rw-r--r-- | dom/base/test/browser_multiple_popups.js | 296 |
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..c50c246644 --- /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 = "https://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, + }); + }); +}); |