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_ext_contextMenus_targetUrlPatterns.js | 313 +++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 browser/components/extensions/test/browser/browser_ext_contextMenus_targetUrlPatterns.js (limited to 'browser/components/extensions/test/browser/browser_ext_contextMenus_targetUrlPatterns.js') diff --git a/browser/components/extensions/test/browser/browser_ext_contextMenus_targetUrlPatterns.js b/browser/components/extensions/test/browser/browser_ext_contextMenus_targetUrlPatterns.js new file mode 100644 index 0000000000..480703e0c5 --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_contextMenus_targetUrlPatterns.js @@ -0,0 +1,313 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +add_task(async function unsupportedSchemes() { + const testcases = [ + { + // Link to URL with query string parameters only. + testUrl: "magnet:?xt=urn:btih:somesha1hash&dn=displayname.txt", + matchingPatterns: [ + "magnet:*", + "magnet:?xt=*", + "magnet:?xt=*txt", + "magnet:*?xt=*txt", + ], + nonmatchingPatterns: [ + // Although matches unsupported schemes in Chromium, + // we have specified that only matches all supported + // schemes. To match any scheme, an extension should not set the + // targetUrlPatterns field - this is checked below in subtest + // unsupportedSchemeWithoutTargetUrlPatterns. + "", + "agnet:*", + "magne:*", + ], + }, + { + // Link to bookmarklet. + testUrl: "javascript:-URL", + matchingPatterns: ["javascript:*", "javascript:*URL", "javascript:-URL"], + nonmatchingPatterns: [ + "", + "javascript://-URL", + "javascript:javascript:-URL", + ], + }, + { + // Link to bookmarklet with comment. + testUrl: "javascript://-URL", + matchingPatterns: [ + "javascript:*", + "javascript://-URL", + "javascript:*URL", + ], + nonmatchingPatterns: ["", "javascript:-URL"], + }, + { + // Link to data-URI. + testUrl: "data:application/foo,bar", + matchingPatterns: [ + "", + "data:application/foo,bar", + "data:*,*", + "data:*", + ], + nonmatchingPatterns: ["data:,bar", "data:application/foo,"], + }, + { + // Extension page. + testUrl: "moz-extension://uuid/manifest.json", + matchingPatterns: ["moz-extension://*/*"], + nonmatchingPatterns: [ + "", + "moz-extension://uuid/not/manifest.json*", + ], + }, + { + // While the scheme is supported, the URL is invalid. + testUrl: "http://", + matchingPatterns: [], + nonmatchingPatterns: ["http://*/*", ""], + }, + ]; + + async function testScript(testcases) { + let testcase; + + browser.contextMenus.onShown.addListener(({ menuIds, linkUrl }) => { + browser.test.assertEq(testcase.testUrl, linkUrl, "Expected linkUrl"); + for (let pattern of testcase.matchingPatterns) { + browser.test.assertTrue( + menuIds.includes(pattern), + `Menu item with targetUrlPattern="${pattern}" should be shown at ${testcase.testUrl}` + ); + } + for (let pattern of testcase.nonmatchingPatterns) { + browser.test.assertFalse( + menuIds.includes(pattern), + `Menu item with targetUrlPattern="${pattern}" should not be shown at ${testcase.testUrl}` + ); + } + testcase = null; + browser.test.sendMessage("onShown_checked"); + }); + + browser.test.onMessage.addListener(async (msg, params) => { + browser.test.assertEq("setupTest", msg, "Expected message"); + + // Save test case in global variable for use in the onShown event. + testcase = params; + browser.test.log(`Running test for link with URL: ${testcase.testUrl}`); + document.getElementById("test_link_element").href = testcase.testUrl; + await browser.contextMenus.removeAll(); + for (let targetUrlPattern of [ + ...testcase.matchingPatterns, + ...testcase.nonmatchingPatterns, + ]) { + await new Promise(resolve => { + browser.test.log(`Creating menu with "${targetUrlPattern}"`); + browser.contextMenus.create( + { + id: targetUrlPattern, + contexts: ["link"], + title: "Some menu item", + targetUrlPatterns: [targetUrlPattern], + }, + resolve + ); + }); + } + browser.test.sendMessage("setupTest_ready"); + }); + browser.test.sendMessage("ready"); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["contextMenus"], + }, + background() { + browser.tabs.create({ url: "testrunner.html" }); + }, + files: { + "testrunner.js": `(${testScript})()`, + "testrunner.html": ` + + + Test link + + + `, + }, + }); + + await extension.startup(); + await extension.awaitMessage("ready"); + for (let testcase of testcases) { + extension.sendMessage("setupTest", testcase); + await extension.awaitMessage("setupTest_ready"); + + await openExtensionContextMenu("#test_link_element"); + await extension.awaitMessage("onShown_checked"); + await closeContextMenu(); + } + await extension.unload(); +}); + +async function testLinkMenuWithoutTargetUrlPatterns(linkUrl) { + function background(expectedLinkUrl) { + let menuId; + browser.contextMenus.onShown.addListener(({ menuIds, linkUrl }) => { + browser.test.assertEq(1, menuIds.length, "Expected number of menus"); + browser.test.assertEq(menuId, menuIds[0], "Expected menu ID"); + browser.test.assertEq(expectedLinkUrl, linkUrl, "Expected linkUrl"); + browser.test.sendMessage("done"); + }); + menuId = browser.contextMenus.create( + { + contexts: ["link"], + title: "Test menu item without targetUrlPattern", + }, + () => { + browser.tabs.create({ url: "testpage.html" }); + } + ); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["contextMenus"], + }, + background: `(${background})("${linkUrl}")`, + files: { + "testpage.js": `browser.test.sendMessage("ready")`, + "testpage.html": ` + + Test link + + `, + }, + }); + + await extension.startup(); + await extension.awaitMessage("ready"); + await openExtensionContextMenu("#test_link_element"); + await extension.awaitMessage("done"); + await closeContextMenu(); + + await extension.unload(); +} + +// Tests that a menu item is shown on links with an unsupported scheme if +// targetUrlPatterns is not set. +add_task(async function unsupportedSchemeWithoutPattern() { + await testLinkMenuWithoutTargetUrlPatterns("unsupported-scheme:data"); +}); + +// Tests that a menu item is shown on links with an invalid http:-URL if +// targetUrlPatterns is not set. +add_task(async function invalidHttpUrlWithoutPattern() { + await testLinkMenuWithoutTargetUrlPatterns("http://"); +}); + +add_task(async function privileged_are_allowed_to_use_restrictedSchemes() { + let privilegedExtension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + manifest: { + permissions: ["tabs", "contextMenus", "mozillaAddons"], + }, + async background() { + browser.contextMenus.create({ + id: "privileged-extension", + title: "Privileged Extension", + contexts: ["page"], + documentUrlPatterns: ["about:reader*"], + }); + + browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { + if ( + changeInfo.status === "complete" && + tab.url.startsWith("about:reader") + ) { + browser.test.sendMessage("readerModeEntered"); + } + }); + + browser.test.onMessage.addListener(async msg => { + if (msg !== "enterReaderMode") { + browser.test.fail(`Received unexpected test message: ${msg}`); + return; + } + + browser.tabs.toggleReaderMode(); + }); + }, + }); + + let nonPrivilegedExtension = ExtensionTestUtils.loadExtension({ + isPrivileged: false, + manifest: { + permissions: ["contextMenus", "mozillaAddons"], + }, + async background() { + browser.contextMenus.create({ + id: "non-privileged-extension", + title: "Non Privileged Extension", + contexts: ["page"], + documentUrlPatterns: ["about:reader*"], + }); + }, + }); + + const baseUrl = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" + ); + const url = `${baseUrl}/readerModeArticle.html`; + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + url, + true, + true + ); + + await Promise.all([ + privilegedExtension.startup(), + nonPrivilegedExtension.startup(), + ]); + + privilegedExtension.sendMessage("enterReaderMode"); + await privilegedExtension.awaitMessage("readerModeEntered"); + + const contextMenu = await openContextMenu("body > h1"); + + let item = contextMenu.getElementsByAttribute( + "label", + "Privileged Extension" + ); + is( + item.length, + 1, + "Privileged extension's contextMenu item found as expected" + ); + + item = contextMenu.getElementsByAttribute( + "label", + "Non Privileged Extension" + ); + is( + item.length, + 0, + "Non privileged extension's contextMenu not found as expected" + ); + + await closeContextMenu(); + + BrowserTestUtils.removeTab(tab); + + await Promise.all([ + privilegedExtension.unload(), + nonPrivilegedExtension.unload(), + ]); +}); -- cgit v1.2.3