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 --- .../extensions/test/browser/head_pageAction.js | 232 +++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 browser/components/extensions/test/browser/head_pageAction.js (limited to 'browser/components/extensions/test/browser/head_pageAction.js') diff --git a/browser/components/extensions/test/browser/head_pageAction.js b/browser/components/extensions/test/browser/head_pageAction.js new file mode 100644 index 0000000000..f80a6d3c98 --- /dev/null +++ b/browser/components/extensions/test/browser/head_pageAction.js @@ -0,0 +1,232 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +/* exported runTests */ +// This file is imported into the same scope as head.js. +/* import-globals-from head.js */ + +{ + // At the moment extension language negotiation is tied to Firefox language + // negotiation result. That means that to test an extension in `es-ES`, we need + // to mock `es-ES` being available in Firefox and then request it. + // + // In the future, we should provide some way for tests to decouple their + // language selection from that of Firefox. + const avLocales = Services.locale.availableLocales; + + Services.locale.availableLocales = ["en-US", "es-ES"]; + registerCleanupFunction(() => { + Services.locale.availableLocales = avLocales; + }); +} + +async function runTests(options) { + function background(getTests) { + let tests; + + // Gets the current details of the page action, and returns a + // promise that resolves to an object containing them. + async function getDetails(tabId) { + return { + title: await browser.pageAction.getTitle({ tabId }), + popup: await browser.pageAction.getPopup({ tabId }), + isShown: await browser.pageAction.isShown({ tabId }), + }; + } + + // Runs the next test in the `tests` array, checks the results, + // and passes control back to the outer test scope. + function nextTest() { + let test = tests.shift(); + + test(async expecting => { + let [tab] = await browser.tabs.query({ + active: true, + currentWindow: true, + }); + let { id: tabId, windowId, url } = tab; + + browser.test.log(`Get details: tab={id: ${tabId}, url: ${url}}`); + + // Check that the API returns the expected values, and then + // run the next test. + let details = await getDetails(tabId); + if (expecting) { + browser.test.assertEq( + expecting.title, + details.title, + "expected value from getTitle" + ); + + browser.test.assertEq( + expecting.popup, + details.popup, + "expected value from getPopup" + ); + } + + browser.test.assertEq( + !!expecting, + details.isShown, + "expected value from isShown" + ); + + // Check that the actual icon has the expected values, then + // run the next test. + browser.test.sendMessage("nextTest", expecting, windowId, tests.length); + }); + } + + async function runTests() { + let tabs = []; + let windows = []; + tests = getTests(tabs, windows); + + let resultTabs = await browser.tabs.query({ + active: true, + currentWindow: true, + }); + + tabs[0] = resultTabs[0].id; + windows[0] = resultTabs[0].windowId; + + nextTest(); + } + + browser.test.onMessage.addListener(msg => { + if (msg == "runTests") { + runTests(); + } else if (msg == "runNextTest") { + nextTest(); + } else { + browser.test.fail(`Unexpected message: ${msg}`); + } + }); + + runTests(); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: options.manifest, + + files: options.files || {}, + + background: `(${background})(${options.getTests})`, + }); + + let pageActionId; + let currentWindow = window; + let windows = []; + + async function waitForDetails(details, windowId) { + function check() { + let { document } = Services.wm.getOuterWindowWithId(windowId); + let image = document.getElementById(pageActionId); + if (details == null) { + return image == null || image.getAttribute("disabled") == "true"; + } + let title = details.title || options.manifest.name; + return ( + !!image && + getListStyleImage(image) == details.icon && + image.getAttribute("tooltiptext") == title && + image.getAttribute("aria-label") == title + ); + // TODO: Popup URL. If this is updated, modify also checkDetails. + } + + // eslint-disable-next-line no-async-promise-executor + return new Promise(async resolve => { + let maxCounter = 10; + while (!check() && --maxCounter > 0) { + info("checks left: " + maxCounter); + await promiseAnimationFrame(currentWindow); + } + resolve(); + }); + } + + function checkDetails(details, windowId) { + let { document } = Services.wm.getOuterWindowWithId(windowId); + let image = document.getElementById(pageActionId); + if (details == null) { + ok( + image == null || image.getAttribute("disabled") == "true", + "image is disabled" + ); + } else { + ok(image, "image exists"); + + is(getListStyleImage(image), details.icon, "icon URL is correct"); + + let title = details.title || options.manifest.name; + is(image.getAttribute("tooltiptext"), title, "image title is correct"); + is( + image.getAttribute("aria-label"), + title, + "image aria-label is correct" + ); + // TODO: Popup URL. If this is updated, modify also waitForDetails. + } + } + + let testNewWindows = 1; + + let awaitFinish = new Promise(resolve => { + extension.onMessage( + "nextTest", + async (expecting, windowId, testsRemaining) => { + if (!pageActionId) { + pageActionId = BrowserPageActions.urlbarButtonNodeIDForActionID( + makeWidgetId(extension.id) + ); + } + + await waitForDetails(expecting, windowId); + + checkDetails(expecting, windowId); + + if (testsRemaining) { + extension.sendMessage("runNextTest"); + } else if (testNewWindows) { + testNewWindows--; + + BrowserTestUtils.openNewBrowserWindow() + .then(window => { + windows.push(window); + currentWindow = window; + return focusWindow(window); + }) + .then(() => { + extension.sendMessage("runTests"); + }); + } else { + resolve(); + } + } + ); + }); + + let reqLoc = Services.locale.requestedLocales; + Services.locale.requestedLocales = ["es-ES"]; + + await extension.startup(); + + await awaitFinish; + + await extension.unload(); + + Services.locale.requestedLocales = reqLoc; + + let node = document.getElementById(pageActionId); + is(node, null, "pageAction image removed from document"); + + currentWindow = null; + for (let win of windows.splice(0)) { + node = win.document.getElementById(pageActionId); + is(node, null, "pageAction image removed from second document"); + + await BrowserTestUtils.closeWindow(win); + } +} -- cgit v1.2.3