From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser/browser_ext_browserAction_popup.js | 370 +++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 browser/components/extensions/test/browser/browser_ext_browserAction_popup.js (limited to 'browser/components/extensions/test/browser/browser_ext_browserAction_popup.js') diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_popup.js b/browser/components/extensions/test/browser/browser_ext_browserAction_popup.js new file mode 100644 index 0000000000..136f30eb41 --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_browserAction_popup.js @@ -0,0 +1,370 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +function getBrowserAction(extension) { + const { + global: { browserActionFor }, + } = Management; + + let ext = WebExtensionPolicy.getByID(extension.id)?.extension; + return browserActionFor(ext); +} + +async function assertViewCount(extension, count, waitForPromise) { + let ext = WebExtensionPolicy.getByID(extension.id).extension; + + if (waitForPromise) { + await waitForPromise; + } + + is( + ext.views.size, + count, + "Should have the expected number of extension views" + ); +} + +function promiseExtensionPageClosed(extension, viewType) { + return new Promise(resolve => { + const policy = WebExtensionPolicy.getByID(extension.id); + + const listener = (evtType, context) => { + if (context.viewType === viewType) { + policy.extension.off("extension-proxy-context-load", listener); + + context.callOnClose({ + close: resolve, + }); + } + }; + policy.extension.on("extension-proxy-context-load", listener); + }); +} + +let scriptPage = url => + `${url}`; + +async function testInArea(area) { + let extension = ExtensionTestUtils.loadExtension({ + background() { + let middleClickShowPopup = false; + browser.browserAction.onClicked.addListener((tabs, info) => { + browser.test.sendMessage("browserAction-onClicked"); + if (info.button === 1 && middleClickShowPopup) { + browser.browserAction.openPopup(); + } + }); + + browser.test.onMessage.addListener(async msg => { + if (msg.type === "setBrowserActionPopup") { + let opts = { popup: msg.popup }; + if (msg.onCurrentWindowId) { + let { id } = await browser.windows.getCurrent(); + opts = { ...opts, windowId: id }; + } else if (msg.onActiveTabId) { + let [{ id }] = await browser.tabs.query({ + active: true, + currentWindow: true, + }); + opts = { ...opts, tabId: id }; + } + await browser.browserAction.setPopup(opts); + browser.test.sendMessage("setBrowserActionPopup:done"); + } else if (msg.type === "setMiddleClickShowPopup") { + middleClickShowPopup = msg.show; + browser.test.sendMessage("setMiddleClickShowPopup:done"); + } + }); + + browser.test.sendMessage("background-page-ready"); + }, + manifest: { + browser_action: { + default_popup: "popup-a.html", + browser_style: true, + }, + }, + + files: { + "popup-a.html": scriptPage("popup-a.js"), + "popup-a.js": function () { + browser.test.onMessage.addListener(msg => { + if (msg == "close-popup-using-window.close") { + window.close(); + } + }); + + window.onload = () => { + let color = window.getComputedStyle(document.body).color; + browser.test.assertEq("rgb(34, 36, 38)", color); + browser.test.sendMessage("from-popup", "popup-a"); + }; + }, + + "data/popup-b.html": scriptPage("popup-b.js"), + "data/popup-b.js": function () { + window.onload = () => { + browser.test.sendMessage("from-popup", "popup-b"); + }; + }, + + "data/popup-c.html": scriptPage("popup-c.js"), + "data/popup-c.js": function () { + // Close the popup before the document is fully-loaded to make sure that + // we handle this case sanely. + browser.test.sendMessage("from-popup", "popup-c"); + window.close(); + }, + }, + }); + + await Promise.all([ + extension.startup(), + extension.awaitMessage("background-page-ready"), + ]); + + let widget = getBrowserActionWidget(extension); + + // Move the browserAction widget to the area targeted by this test. + CustomizableUI.addWidgetToArea(widget.id, area); + + async function setBrowserActionPopup(opts) { + extension.sendMessage({ type: "setBrowserActionPopup", ...opts }); + await extension.awaitMessage("setBrowserActionPopup:done"); + } + + async function setShowPopupOnMiddleClick(show) { + extension.sendMessage({ type: "setMiddleClickShowPopup", show }); + await extension.awaitMessage("setMiddleClickShowPopup:done"); + } + + async function runTest({ + actionType, + waitForPopupLoaded, + expectPopup, + expectOnClicked, + closePopup, + }) { + const oncePopupPageClosed = promiseExtensionPageClosed(extension, "popup"); + const oncePopupLoaded = waitForPopupLoaded + ? awaitExtensionPanel(extension) + : undefined; + + if (actionType === "click") { + clickBrowserAction(extension); + } else if (actionType === "trigger") { + getBrowserAction(extension).triggerAction(window); + } else if (actionType === "middleClick") { + clickBrowserAction(extension, window, { button: 1 }); + } + + if (expectOnClicked) { + await extension.awaitMessage("browserAction-onClicked"); + } + + if (expectPopup) { + info(`Waiting for popup: ${expectPopup}`); + is( + await extension.awaitMessage("from-popup"), + expectPopup, + "expected popup opened" + ); + } + + await oncePopupLoaded; + + if (closePopup) { + info("Closing popup"); + await closeBrowserAction(extension); + await assertViewCount(extension, 1, oncePopupPageClosed); + } + + return { oncePopupPageClosed }; + } + + // Run the sequence of test cases. + const tests = [ + async () => { + info(`Click browser action, expect popup "a".`); + + await runTest({ + actionType: "click", + expectPopup: "popup-a", + closePopup: true, + }); + }, + async () => { + info(`Click browser action again, expect popup "a".`); + + await runTest({ + actionType: "click", + expectPopup: "popup-a", + waitForPopupLoaded: true, + closePopup: true, + }); + }, + async () => { + info(`Call triggerAction, expect popup "a" again. Leave popup open.`); + + const { oncePopupPageClosed } = await runTest({ + actionType: "trigger", + expectPopup: "popup-a", + waitForPopupLoaded: true, + }); + + await assertViewCount(extension, 2); + + info(`Call triggerAction again. Expect remaining popup closed.`); + getBrowserAction(extension).triggerAction(window); + + await assertViewCount(extension, 1, oncePopupPageClosed); + }, + async () => { + info(`Call triggerAction again. Expect popup "a" again.`); + + await runTest({ + actionType: "trigger", + expectPopup: "popup-a", + closePopup: true, + }); + }, + async () => { + info(`Set popup to "c" and click browser action. Expect popup "c".`); + + await setBrowserActionPopup({ popup: "data/popup-c.html" }); + + const { oncePopupPageClosed } = await runTest({ + actionType: "click", + expectPopup: "popup-c", + }); + + await assertViewCount(extension, 1, oncePopupPageClosed); + }, + async () => { + info(`Set popup to "b" and click browser action. Expect popup "b".`); + + await setBrowserActionPopup({ popup: "data/popup-b.html" }); + + await runTest({ + actionType: "click", + expectPopup: "popup-b", + closePopup: true, + }); + }, + async () => { + info(`Click browser action again, expect popup "b".`); + + await runTest({ + actionType: "click", + expectPopup: "popup-b", + closePopup: true, + }); + }, + async () => { + info(`Middle-click browser action, expect an event only.`); + + await setShowPopupOnMiddleClick(false); + + await runTest({ + actionType: "middleClick", + expectOnClicked: true, + }); + }, + async () => { + info( + `Middle-click browser action again, expect a click event then a popup.` + ); + + await setShowPopupOnMiddleClick(true); + + await runTest({ + actionType: "middleClick", + expectOnClicked: true, + expectPopup: "popup-b", + closePopup: true, + }); + }, + async () => { + info(`Clear popup URL. Click browser action. Expect click event.`); + + await setBrowserActionPopup({ popup: "" }); + + await runTest({ + actionType: "click", + expectOnClicked: true, + }); + }, + async () => { + info(`Click browser action again. Expect another click event.`); + + await runTest({ + actionType: "click", + expectOnClicked: true, + }); + }, + async () => { + info(`Call triggerAction. Expect click event.`); + + await runTest({ + actionType: "trigger", + expectOnClicked: true, + }); + }, + async () => { + info( + `Set window-specific popup to "b" and click browser action. Expect popup "b".` + ); + + await setBrowserActionPopup({ + popup: "data/popup-b.html", + onCurrentWindowId: true, + }); + + await runTest({ + actionType: "click", + expectPopup: "popup-b", + closePopup: true, + }); + }, + async () => { + info( + `Set tab-specific popup to "a" and click browser action. Expect popup "a", and leave open.` + ); + + await setBrowserActionPopup({ + popup: "/popup-a.html", + onActiveTabId: true, + }); + + const { oncePopupPageClosed } = await runTest({ + actionType: "click", + expectPopup: "popup-a", + }); + assertViewCount(extension, 2); + + info(`Tell popup "a" to call window.close(). Expect popup closed.`); + extension.sendMessage("close-popup-using-window.close"); + + await assertViewCount(extension, 1, oncePopupPageClosed); + }, + ]; + + for (let test of tests) { + await test(); + } + + // Unload the extension and verify that the browserAction widget is gone. + await extension.unload(); + + let view = document.getElementById(widget.viewId); + is(view, null, "browserAction view removed from document"); +} + +add_task(async function testBrowserActionInToolbar() { + await testInArea(CustomizableUI.AREA_NAVBAR); +}); + +add_task(async function testBrowserActionInPanel() { + await testInArea(getCustomizableUIPanelID()); +}); -- cgit v1.2.3