From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../extensions/test/mochitest/.eslintrc.js | 6 + .../extensions/test/mochitest/chrome.toml | 8 + .../extensions/test/mochitest/context.html | 24 + .../mochitest/context_tabs_onUpdated_iframe.html | 22 + .../mochitest/context_tabs_onUpdated_page.html | 21 + .../test/mochitest/file_bypass_cache.sjs | 13 + .../extensions/test/mochitest/file_dummy.html | 10 + .../test/mochitest/file_iframe_document.html | 11 + .../test/mochitest/file_slowed_document.sjs | 49 ++ .../components/extensions/test/mochitest/head.js | 73 +++ .../extensions/test/mochitest/mochitest.toml | 62 +++ .../test/mochitest/test_ext_all_apis.html | 51 +++ .../mochitest/test_ext_downloads_event_page.html | 102 +++++ .../test/mochitest/test_ext_options_ui.html | 498 +++++++++++++++++++++ .../mochitest/test_ext_tab_runtimeConnect.html | 89 ++++ .../mochitest/test_ext_tabs_autoDiscardable.html | 39 ++ .../test/mochitest/test_ext_tabs_create.html | 153 +++++++ .../test/mochitest/test_ext_tabs_events.html | 302 +++++++++++++ .../mochitest/test_ext_tabs_executeScript.html | 252 +++++++++++ .../mochitest/test_ext_tabs_executeScript_bad.html | 151 +++++++ .../test_ext_tabs_executeScript_no_create.html | 83 ++++ .../test_ext_tabs_executeScript_runAt.html | 128 ++++++ .../test/mochitest/test_ext_tabs_get.html | 36 ++ .../test/mochitest/test_ext_tabs_getCurrent.html | 70 +++ .../mochitest/test_ext_tabs_goBack_goForward.html | 134 ++++++ .../test/mochitest/test_ext_tabs_insertCSS.html | 124 +++++ .../test/mochitest/test_ext_tabs_lastAccessed.html | 64 +++ .../test/mochitest/test_ext_tabs_onUpdated.html | 187 ++++++++ .../test/mochitest/test_ext_tabs_query.html | 46 ++ .../test/mochitest/test_ext_tabs_reload.html | 66 +++ .../test_ext_tabs_reload_bypass_cache.html | 87 ++++ .../test/mochitest/test_ext_tabs_sendMessage.html | 277 ++++++++++++ .../test/mochitest/test_ext_tabs_update_url.html | 125 ++++++ .../test_ext_webNavigation_onCommitted.html | 50 +++ .../extensions/test/xpcshell/.eslintrc.js | 6 + .../components/extensions/test/xpcshell/head.js | 24 + .../test_ext_native_messaging_geckoview.js | 424 ++++++++++++++++++ .../test_ext_native_messaging_permissions.js | 167 +++++++ .../extensions/test/xpcshell/xpcshell.toml | 9 + 39 files changed, 4043 insertions(+) create mode 100644 mobile/android/components/extensions/test/mochitest/.eslintrc.js create mode 100644 mobile/android/components/extensions/test/mochitest/chrome.toml create mode 100644 mobile/android/components/extensions/test/mochitest/context.html create mode 100644 mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_iframe.html create mode 100644 mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_page.html create mode 100644 mobile/android/components/extensions/test/mochitest/file_bypass_cache.sjs create mode 100644 mobile/android/components/extensions/test/mochitest/file_dummy.html create mode 100644 mobile/android/components/extensions/test/mochitest/file_iframe_document.html create mode 100644 mobile/android/components/extensions/test/mochitest/file_slowed_document.sjs create mode 100644 mobile/android/components/extensions/test/mochitest/head.js create mode 100644 mobile/android/components/extensions/test/mochitest/mochitest.toml create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_all_apis.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_downloads_event_page.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_options_ui.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tab_runtimeConnect.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_autoDiscardable.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_create.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_bad.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_no_create.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_runAt.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_get.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_getCurrent.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_goBack_goForward.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_insertCSS.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_query.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload_bypass_cache.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_tabs_update_url.html create mode 100644 mobile/android/components/extensions/test/mochitest/test_ext_webNavigation_onCommitted.html create mode 100644 mobile/android/components/extensions/test/xpcshell/.eslintrc.js create mode 100644 mobile/android/components/extensions/test/xpcshell/head.js create mode 100644 mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js create mode 100644 mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_permissions.js create mode 100644 mobile/android/components/extensions/test/xpcshell/xpcshell.toml (limited to 'mobile/android/components/extensions/test') diff --git a/mobile/android/components/extensions/test/mochitest/.eslintrc.js b/mobile/android/components/extensions/test/mochitest/.eslintrc.js new file mode 100644 index 0000000000..7d6fe2eb1a --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/.eslintrc.js @@ -0,0 +1,6 @@ +"use strict"; + +module.exports = { + extends: + "../../../../../../toolkit/components/extensions/test/mochitest/.eslintrc.js", +}; diff --git a/mobile/android/components/extensions/test/mochitest/chrome.toml b/mobile/android/components/extensions/test/mochitest/chrome.toml new file mode 100644 index 0000000000..5a93353448 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/chrome.toml @@ -0,0 +1,8 @@ +[DEFAULT] +support-files = [ + "head.js", + "../../../../../../toolkit/components/extensions/test/mochitest/chrome_cleanup_script.js", +] +tags = "webextensions" + +["test_ext_options_ui.html"] diff --git a/mobile/android/components/extensions/test/mochitest/context.html b/mobile/android/components/extensions/test/mochitest/context.html new file mode 100644 index 0000000000..1e25c6e851 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/context.html @@ -0,0 +1,24 @@ + + + + + + just some text 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + + +

+ Some link +

+ +

+ + + +

+ +

+
+ +

+ + diff --git a/mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_iframe.html b/mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_iframe.html new file mode 100644 index 0000000000..1e2afec6fa --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_iframe.html @@ -0,0 +1,22 @@ + + + + + +

test iframe

+ + + diff --git a/mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_page.html b/mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_page.html new file mode 100644 index 0000000000..3fa93979fa --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/context_tabs_onUpdated_page.html @@ -0,0 +1,21 @@ + + + + + +

test page

+ + + + diff --git a/mobile/android/components/extensions/test/mochitest/file_bypass_cache.sjs b/mobile/android/components/extensions/test/mochitest/file_bypass_cache.sjs new file mode 100644 index 0000000000..eed8a6ef49 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/file_bypass_cache.sjs @@ -0,0 +1,13 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80 ft=javascript: */ +"use strict"; + +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/plain; charset=UTF-8", false); + + if (request.hasHeader("pragma") && request.hasHeader("cache-control")) { + response.write( + `${request.getHeader("pragma")}:${request.getHeader("cache-control")}` + ); + } +} diff --git a/mobile/android/components/extensions/test/mochitest/file_dummy.html b/mobile/android/components/extensions/test/mochitest/file_dummy.html new file mode 100644 index 0000000000..49ad37128d --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/file_dummy.html @@ -0,0 +1,10 @@ + + + +Dummy test page + + + +

Dummy test page

+ + diff --git a/mobile/android/components/extensions/test/mochitest/file_iframe_document.html b/mobile/android/components/extensions/test/mochitest/file_iframe_document.html new file mode 100644 index 0000000000..3bb2bd5dcf --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/file_iframe_document.html @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/file_slowed_document.sjs b/mobile/android/components/extensions/test/mochitest/file_slowed_document.sjs new file mode 100644 index 0000000000..3816cf045b --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/file_slowed_document.sjs @@ -0,0 +1,49 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80 ft=javascript: */ +"use strict"; + +// This script slows the load of an HTML document so that we can reliably test +// all phases of the load cycle supported by the extension API. + +/* eslint-disable no-unused-vars */ + +const URL = "file_slowed_document.sjs"; + +const DELAY = 2 * 1000; // Delay one second before completing the request. + +const nsTimer = Components.Constructor( + "@mozilla.org/timer;1", + "nsITimer", + "initWithCallback" +); + +let timer; + +function handleRequest(request, response) { + response.processAsync(); + + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Cache-Control", "no-cache", false); + response.write(` + + + + + + + `); + + // Note: We need to store a reference to the timer to prevent it from being + // canceled when it's GCed. + timer = new nsTimer( + () => { + if (request.queryString.includes("with-iframe")) { + response.write(``); + } + response.write(``); + response.finish(); + }, + DELAY, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} diff --git a/mobile/android/components/extensions/test/mochitest/head.js b/mobile/android/components/extensions/test/mochitest/head.js new file mode 100644 index 0000000000..c240edd765 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/head.js @@ -0,0 +1,73 @@ +"use strict"; + +/* exported assertPersistentListeners, AppConstants, TEST_ICON_ARRAYBUFFER */ + +var { AppConstants } = SpecialPowers.ChromeUtils.importESModule( + "resource://gre/modules/AppConstants.sys.mjs" +); + +var TEST_ICON_DATA = + "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAC4klEQVRYhdWXLWzbQBSADQtDAwsHC1tUhUxqfL67lk2tdn+OJg0ODU0rLByqgqINBY6tmlbn7LMTJ5FaFVVBk1G0oUGjG2jT2Y7jxmmcbU/6iJ+f36fz+e5sGP9riCGm9hB37RG+scd4Yo/wsDXCZyIE2xuXsce4bY+wXkAsQtzYmExrfFgvkJkRbkzo1ehoxx5iXcgI/9iYUGt8WH9MqDXEcmNChmEYrRCf2SHWeYgQx3x0tLNRIeKQLTtEFyJEep4NTuhk8BC+yMrwEE3+iozo42d8gK7FAOkMsRiiN8QhW2ttSK5QTfRRV4QoymVeJMvPvDp7gCZigD613MN6yRFA3SWarow9QB9LCfG+NeF9qCtjAKOSQjCqVKhfVsiHEQ+grgx/lRGqUihAc1uL8EFD+KCRO+GrF4J61phcoRoPoEzkYhZYpykh5sMb7kOdIeY+jHKur4QI4Feh4AFX1nVeLxrAvQchGsBz5ls6wa2QdwcvIcE2863bTH79KOvsz/uUYJsp+J0pSzNlDckVqqVGUAF+n6uS7txcOl6wot4JVy70ufDLy4pWLUQVPE81pRI0mGe9oxLMHSeohHvMs/STUNaUK6vDPCvOyxMFDx4achehRDJmHnydnkPww5OFfLxrGIZBFDyYl4LpMzlTQFIP6AQx86w2UeYBccFpJrcKv5L9eGDtUAU6RIELqsB74uynjy/UBRF1gS5BTFxwQT1wTiXoUg9MH7m/3NZRRoi5IJytUbMgzv4Wc832+oQkiKgEehmyMkkpKsFkQV11QsRJL5rJYBLItQgRaUZEmnoZXsomz3vGiWw+I9KMF9SVFOqZEemZekli1jN3U/UOqhHHvC6oWWGElhfSpGdOk6+O9prdwvtLj5BjRsQxdRnot+Zeifpy/2/0stktKTRNLmbk0mwXyl8253fyojj+8rxOHNAhjjm5n0/5OOCGOKBzkrMO0Z75lvSAzKlrF32Z/3z8BqLAn+yMV7VhAAAAAElFTkSuQmCC"; + +var TEST_ICON_ARRAYBUFFER = Uint8Array.from(atob(TEST_ICON_DATA), byte => + byte.charCodeAt(0) +).buffer; + +async function assertPersistentListeners( + extWrapper, + apiNs, + apiEvents, + expected +) { + const stringErr = await SpecialPowers.spawnChrome( + [extWrapper.id, apiNs, apiEvents, expected], + async (id, apiNs, apiEvents, expected) => { + try { + const { ExtensionTestCommon } = ChromeUtils.importESModule( + "resource://testing-common/ExtensionTestCommon.sys.mjs" + ); + const ext = { id }; + for (const event of apiEvents) { + ExtensionTestCommon.testAssertions.assertPersistentListeners( + ext, + apiNs, + event, + { + primed: expected.primed, + persisted: expected.persisted, + primedListenersCount: expected.primedListenersCount, + } + ); + } + } catch (err) { + return String(err); + } + } + ); + ok( + stringErr == undefined, + stringErr ? stringErr : `Found expected primed and persistent listeners` + ); +} + +{ + const chromeScript = SpecialPowers.loadChromeScript( + SimpleTest.getTestFileURL("chrome_cleanup_script.js") + ); + + SimpleTest.registerCleanupFunction(async () => { + await new Promise(resolve => setTimeout(resolve, 0)); + + chromeScript.sendAsyncMessage("check-cleanup"); + + const results = await chromeScript.promiseOneMessage("cleanup-results"); + chromeScript.destroy(); + + if (results.extraWindows.length || results.extraTabs.length) { + ok( + false, + `Test left extra windows or tabs: ${JSON.stringify(results)}\n` + ); + } + }); +} diff --git a/mobile/android/components/extensions/test/mochitest/mochitest.toml b/mobile/android/components/extensions/test/mochitest/mochitest.toml new file mode 100644 index 0000000000..f3e5922cc4 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/mochitest.toml @@ -0,0 +1,62 @@ +[DEFAULT] +support-files = [ + "../../../../../../toolkit/components/extensions/test/mochitest/test_ext_all_apis.js", + "../../../../../../toolkit/components/extensions/test/mochitest/file_sample.html", + "../../../../../../toolkit/components/extensions/test/mochitest/chrome_cleanup_script.js", + "context.html", + "context_tabs_onUpdated_iframe.html", + "context_tabs_onUpdated_page.html", + "file_bypass_cache.sjs", + "file_dummy.html", + "file_iframe_document.html", + "file_slowed_document.sjs", + "head.js", +] +tags = "webextensions" +prefs = ["javascript.options.asyncstack_capture_debuggee_only=false"] + +["test_ext_all_apis.html"] + +["test_ext_downloads_event_page.html"] + +["test_ext_tab_runtimeConnect.html"] + +["test_ext_tabs_autoDiscardable.html"] + +["test_ext_tabs_create.html"] + +["test_ext_tabs_events.html"] +skip-if = ["fission"] # Bug 1827754 + +["test_ext_tabs_executeScript.html"] + +["test_ext_tabs_executeScript_bad.html"] + +["test_ext_tabs_executeScript_no_create.html"] + +["test_ext_tabs_executeScript_runAt.html"] + +["test_ext_tabs_get.html"] + +["test_ext_tabs_getCurrent.html"] + +["test_ext_tabs_goBack_goForward.html"] + +["test_ext_tabs_insertCSS.html"] + +["test_ext_tabs_lastAccessed.html"] +skip-if = ["true"] # tab.lastAccessed not implemented + +["test_ext_tabs_onUpdated.html"] + +["test_ext_tabs_query.html"] + +["test_ext_tabs_reload.html"] + +["test_ext_tabs_reload_bypass_cache.html"] + +["test_ext_tabs_sendMessage.html"] + +["test_ext_tabs_update_url.html"] + +["test_ext_webNavigation_onCommitted.html"] diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_all_apis.html b/mobile/android/components/extensions/test/mochitest/test_ext_all_apis.html new file mode 100644 index 0000000000..3ad239b093 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_all_apis.html @@ -0,0 +1,51 @@ + + + + WebExtension test + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_downloads_event_page.html b/mobile/android/components/extensions/test/mochitest/test_ext_downloads_event_page.html new file mode 100644 index 0000000000..78691114df --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_downloads_event_page.html @@ -0,0 +1,102 @@ + + + + + Downloads Events Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_options_ui.html b/mobile/android/components/extensions/test/mochitest/test_ext_options_ui.html new file mode 100644 index 0000000000..138bb054a9 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_options_ui.html @@ -0,0 +1,498 @@ + + + + + PageAction Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tab_runtimeConnect.html b/mobile/android/components/extensions/test/mochitest/test_ext_tab_runtimeConnect.html new file mode 100644 index 0000000000..48904c2990 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tab_runtimeConnect.html @@ -0,0 +1,89 @@ + + + + + Tabs runtimeConnect Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_autoDiscardable.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_autoDiscardable.html new file mode 100644 index 0000000000..63ea8337a7 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_autoDiscardable.html @@ -0,0 +1,39 @@ + + + + + autoDiscardable test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_create.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_create.html new file mode 100644 index 0000000000..027b231fa7 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_create.html @@ -0,0 +1,153 @@ + + + + + Tabs create Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html new file mode 100644 index 0000000000..cd708d942a --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html @@ -0,0 +1,302 @@ + + + + + Tabs Events Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html new file mode 100644 index 0000000000..09e42d73cf --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript.html @@ -0,0 +1,252 @@ + + + + + Tabs executeScript Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_bad.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_bad.html new file mode 100644 index 0000000000..da645ef738 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_bad.html @@ -0,0 +1,151 @@ + + + + + Tabs executeScript Bad Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_no_create.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_no_create.html new file mode 100644 index 0000000000..fa25568619 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_no_create.html @@ -0,0 +1,83 @@ + + + + + Tabs executeScript noCreate Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_runAt.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_runAt.html new file mode 100644 index 0000000000..2e82320f8c --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_executeScript_runAt.html @@ -0,0 +1,128 @@ + + + + + Tabs executeScript runAt Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_get.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_get.html new file mode 100644 index 0000000000..109ab8f65c --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_get.html @@ -0,0 +1,36 @@ + + + + + Tabs get Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_getCurrent.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_getCurrent.html new file mode 100644 index 0000000000..c32f93f44a --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_getCurrent.html @@ -0,0 +1,70 @@ + + + + + Tabs getCurrent Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_goBack_goForward.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_goBack_goForward.html new file mode 100644 index 0000000000..0d143e2ac6 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_goBack_goForward.html @@ -0,0 +1,134 @@ + + + + + Tabs goBack and goForward Test + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_insertCSS.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_insertCSS.html new file mode 100644 index 0000000000..718c2d6de4 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_insertCSS.html @@ -0,0 +1,124 @@ + + + + + Tabs executeScript Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html new file mode 100644 index 0000000000..5bb44ab645 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_lastAccessed.html @@ -0,0 +1,64 @@ + + + + + Tabs lastAccessed Test + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html new file mode 100644 index 0000000000..8d96e79cc2 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_onUpdated.html @@ -0,0 +1,187 @@ + + + + + Tabs onUpdated Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_query.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_query.html new file mode 100644 index 0000000000..9a907f47de --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_query.html @@ -0,0 +1,46 @@ + + + + + Tabs create Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload.html new file mode 100644 index 0000000000..30379f02a1 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload.html @@ -0,0 +1,66 @@ + + + + + Tabs reload Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload_bypass_cache.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload_bypass_cache.html new file mode 100644 index 0000000000..87f90ad855 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_reload_bypass_cache.html @@ -0,0 +1,87 @@ + + + + + Tabs executeScript bypassCache Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html new file mode 100644 index 0000000000..320ce4dde6 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_sendMessage.html @@ -0,0 +1,277 @@ + + + + + Tabs sendMessage Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_update_url.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_update_url.html new file mode 100644 index 0000000000..9332efd516 --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_update_url.html @@ -0,0 +1,125 @@ + + + + + Tabs update Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_webNavigation_onCommitted.html b/mobile/android/components/extensions/test/mochitest/test_ext_webNavigation_onCommitted.html new file mode 100644 index 0000000000..33f178492d --- /dev/null +++ b/mobile/android/components/extensions/test/mochitest/test_ext_webNavigation_onCommitted.html @@ -0,0 +1,50 @@ + + + + + WebNavigation onCommitted Test + + + + + + + + + + + diff --git a/mobile/android/components/extensions/test/xpcshell/.eslintrc.js b/mobile/android/components/extensions/test/xpcshell/.eslintrc.js new file mode 100644 index 0000000000..2e6d214f4b --- /dev/null +++ b/mobile/android/components/extensions/test/xpcshell/.eslintrc.js @@ -0,0 +1,6 @@ +"use strict"; + +module.exports = { + extends: + "../../../../../../toolkit/components/extensions/test/xpcshell/.eslintrc.js", +}; diff --git a/mobile/android/components/extensions/test/xpcshell/head.js b/mobile/android/components/extensions/test/xpcshell/head.js new file mode 100644 index 0000000000..e79781fba6 --- /dev/null +++ b/mobile/android/components/extensions/test/xpcshell/head.js @@ -0,0 +1,24 @@ +"use strict"; + +ChromeUtils.defineESModuleGetters(this, { + AddonTestUtils: "resource://testing-common/AddonTestUtils.sys.mjs", + ExtensionTestUtils: + "resource://testing-common/ExtensionXPCShellUtils.sys.mjs", +}); + +// Remove this pref once bug 1535365 is fixed. +Services.prefs.setBoolPref("extensions.webextensions.remote", false); + +// https_first automatically upgrades http to https, but the tests are not +// designed to expect that. And it is not easy to change that because +// nsHttpServer does not support https (bug 1742061). So disable https_first. +Services.prefs.setBoolPref("dom.security.https_first", false); + +ExtensionTestUtils.init(this); + +Services.io.offline = true; + +var createHttpServer = (...args) => { + AddonTestUtils.maybeInit(this); + return AddonTestUtils.createHttpServer(...args); +}; diff --git a/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js b/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js new file mode 100644 index 0000000000..3ba2e26139 --- /dev/null +++ b/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_geckoview.js @@ -0,0 +1,424 @@ +"use strict"; + +const server = createHttpServer({ hosts: ["example.com"] }); +server.registerPathHandler("/", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html; charset=utf-8", false); + response.write(""); +}); + +ChromeUtils.defineESModuleGetters(this, { + GeckoViewConnection: "resource://gre/modules/GeckoViewWebExtension.sys.mjs", +}); + +// Save reference to original implementations to restore later. +const { sendMessage, onConnect } = GeckoViewConnection.prototype; +add_setup(async () => { + // This file replaces the implementation of GeckoViewConnection; + // make sure that it is restored upon test completion. + registerCleanupFunction(() => { + GeckoViewConnection.prototype.sendMessage = sendMessage; + GeckoViewConnection.prototype.onConnect = onConnect; + }); +}); + +// Mock the embedder communication port +class EmbedderPort { + constructor(portId, messenger) { + this.id = portId; + this.messenger = messenger; + } + close() { + Assert.ok(false, "close not expected to be called"); + } + onPortDisconnect() { + Assert.ok(false, "onPortDisconnect not expected to be called"); + } + onPortMessage(holder) { + Assert.ok(false, "onPortMessage not expected to be called"); + } + triggerPortDisconnect() { + this.messenger.sendPortDisconnect(this.id); + } +} + +function stubConnectNative() { + let port; + const firstCallPromise = new Promise(resolve => { + let callCount = 0; + GeckoViewConnection.prototype.onConnect = (portId, messenger) => { + Assert.equal(++callCount, 1, "onConnect called once"); + port = new EmbedderPort(portId, messenger); + resolve(); + return port; + }; + }); + const triggerPortDisconnect = () => { + if (!port) { + Assert.ok(false, "Undefined port, connection must be established first"); + } + port.triggerPortDisconnect(); + }; + const restore = () => { + GeckoViewConnection.prototype.onConnect = onConnect; + }; + return { firstCallPromise, triggerPortDisconnect, restore }; +} + +function stubSendNativeMessage() { + let sendResponse; + const returnPromise = new Promise(resolve => { + sendResponse = resolve; + }); + const firstCallPromise = new Promise(resolve => { + let callCount = 0; + GeckoViewConnection.prototype.sendMessage = data => { + Assert.equal(++callCount, 1, "sendMessage called once"); + resolve(data); + return returnPromise; + }; + }); + const restore = () => { + GeckoViewConnection.prototype.sendMessage = sendMessage; + }; + return { firstCallPromise, sendResponse, restore }; +} + +function promiseExtensionEvent(wrapper, event) { + return new Promise(resolve => { + wrapper.extension.once(event, (...args) => resolve(args)); + }); +} + +// verify that when background sends a native message, +// the background will not be terminated to allow native messaging +add_task(async function test_sendNativeMessage_event_page() { + const extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + manifest: { + permissions: ["geckoViewAddons", "nativeMessaging"], + background: { persistent: false }, + }, + async background() { + const res = await browser.runtime.sendNativeMessage("fake", "msg"); + browser.test.assertEq("myResp", res, "expected response"); + browser.test.sendMessage("done"); + browser.runtime.onSuspend.addListener(async () => { + browser.test.assertFail("unexpected onSuspend"); + }); + }, + }); + + const stub = stubSendNativeMessage(); + await extension.startup(); + info("Wait for sendNativeMessage to be received"); + Assert.equal( + (await stub.firstCallPromise).deserialize({}), + "msg", + "expected message" + ); + + info("Trigger background script idle timeout and expect to be reset"); + const promiseResetIdle = promiseExtensionEvent( + extension, + "background-script-reset-idle" + ); + await extension.terminateBackground(); + info("Wait for 'background-script-reset-idle' event to be emitted"); + await promiseResetIdle; + + stub.sendResponse("myResp"); + + info("Wait for extension to verify sendNativeMessage response"); + await extension.awaitMessage("done"); + await extension.unload(); + + stub.restore(); +}); + +// verify that when an extension tab sends a native message, +// the background will terminate as expected +add_task(async function test_sendNativeMessage_tab() { + const extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + manifest: { + permissions: ["geckoViewAddons", "nativeMessaging"], + background: { persistent: false }, + }, + async background() { + browser.runtime.onSuspend.addListener(async () => { + browser.test.sendMessage("onSuspend_called"); + }); + }, + files: { + "tab.html": ` + + + `, + "tab.js": async () => { + const res = await browser.runtime.sendNativeMessage("fake", "msg"); + browser.test.assertEq("myResp", res, "expected response"); + browser.test.sendMessage("content_done"); + }, + }, + }); + + const stub = stubSendNativeMessage(); + await extension.startup(); + + const tab = await ExtensionTestUtils.loadContentPage( + `moz-extension://${extension.uuid}/tab.html?tab`, + { extension } + ); + + info("Wait for sendNativeMessage to be received"); + Assert.equal( + (await stub.firstCallPromise).deserialize({}), + "msg", + "expected message" + ); + + info("Terminate extension"); + await extension.terminateBackground(); + await extension.awaitMessage("onSuspend_called"); + + stub.sendResponse("myResp"); + + info("Wait for extension to verify sendNativeMessage response"); + await extension.awaitMessage("content_done"); + await tab.close(); + await extension.unload(); + + stub.restore(); +}); + +// verify that when a content script sends a native message, +// the background will terminate as expected +add_task(async function test_sendNativeMessage_content_script() { + const extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + manifest: { + permissions: [ + "geckoViewAddons", + "nativeMessaging", + "nativeMessagingFromContent", + ], + background: { persistent: false }, + content_scripts: [ + { + run_at: "document_end", + js: ["test.js"], + matches: ["http://example.com/"], + }, + ], + }, + files: { + "test.js": async () => { + const res = await browser.runtime.sendNativeMessage("fake", "msg"); + browser.test.assertEq("myResp", res, "expected response"); + browser.test.sendMessage("content_done"); + }, + }, + async background() { + browser.runtime.onSuspend.addListener(async () => { + browser.test.sendMessage("onSuspend_called"); + }); + }, + }); + + const stub = stubSendNativeMessage(); + await extension.startup(); + + info("Load content page"); + const page = await ExtensionTestUtils.loadContentPage("http://example.com/"); + + info("Wait for message from extension"); + Assert.equal( + (await stub.firstCallPromise).deserialize({}), + "msg", + "expected message" + ); + + info("Terminate extension"); + await extension.terminateBackground(); + await extension.awaitMessage("onSuspend_called"); + + stub.sendResponse("myResp"); + + info("Wait for extension to verify sendNativeMessage response"); + await extension.awaitMessage("content_done"); + await page.close(); + await extension.unload(); + + stub.restore(); +}); + +// verify that when native messaging ports are open, the background will not be terminated +// and once the ports disconnect, onSuspend can be called +add_task(async function test_connectNative_event_page() { + const extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + manifest: { + permissions: ["geckoViewAddons", "nativeMessaging"], + background: { persistent: false }, + }, + async background() { + const port = browser.runtime.connectNative("test"); + port.onDisconnect.addListener(() => { + browser.test.assertEq( + null, + port.error, + "port should be disconnected without errors" + ); + browser.test.sendMessage("port_disconnected"); + }); + + browser.runtime.onSuspend.addListener(async () => { + browser.test.sendMessage("onSuspend_called"); + }); + }, + }); + + const stub = stubConnectNative(); + await extension.startup(); + info("Waiting for connectNative request"); + await stub.firstCallPromise; + + info("Trigger background script idle timeout and expect to be reset"); + const promiseResetIdle = promiseExtensionEvent( + extension, + "background-script-reset-idle" + ); + + await extension.terminateBackground(); + info("Wait for 'background-script-reset-idle' event to be emitted"); + await promiseResetIdle; + + info("Trigger port disconnect, terminate background, and expect onSuspend()"); + stub.triggerPortDisconnect(); + await extension.awaitMessage("port_disconnected"); + + info("Terminate extension"); + await extension.terminateBackground(); + await extension.awaitMessage("onSuspend_called"); + + await extension.unload(); + stub.restore(); +}); + +// verify that when an extension tab opens native messaging ports, +// the background will terminate as expected +add_task(async function test_connectNative_tab() { + const extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + manifest: { + permissions: ["geckoViewAddons", "nativeMessaging"], + background: { persistent: false }, + }, + async background() { + browser.runtime.onSuspend.addListener(async () => { + browser.test.sendMessage("onSuspend_called"); + }); + }, + files: { + "tab.html": ` + + + `, + "tab.js": async () => { + const port = browser.runtime.connectNative("test"); + port.onDisconnect.addListener(() => { + browser.test.assertEq( + null, + port.error, + "port should be disconnected without errors" + ); + browser.test.sendMessage("port_disconnected"); + }); + browser.test.sendMessage("content_done"); + }, + }, + }); + + const stub = stubConnectNative(); + await extension.startup(); + + const tab = await ExtensionTestUtils.loadContentPage( + `moz-extension://${extension.uuid}/tab.html?tab`, + { extension } + ); + await extension.awaitMessage("content_done"); + await stub.firstCallPromise; + + info("Terminate extension"); + await extension.terminateBackground(); + await extension.awaitMessage("onSuspend_called"); + + stub.triggerPortDisconnect(); + await extension.awaitMessage("port_disconnected"); + await tab.close(); + await extension.unload(); + + stub.restore(); +}); + +// verify that when a content script opens native messaging ports, +// the background will terminate as expected +add_task(async function test_connectNative_content_script() { + const extension = ExtensionTestUtils.loadExtension({ + isPrivileged: true, + manifest: { + permissions: [ + "geckoViewAddons", + "nativeMessaging", + "nativeMessagingFromContent", + ], + background: { persistent: false }, + content_scripts: [ + { + run_at: "document_end", + js: ["test.js"], + matches: ["http://example.com/"], + }, + ], + }, + files: { + "test.js": async () => { + const port = browser.runtime.connectNative("test"); + port.onDisconnect.addListener(() => { + browser.test.assertEq( + null, + port.error, + "port should be disconnected without errors" + ); + browser.test.sendMessage("port_disconnected"); + }); + browser.test.sendMessage("content_done"); + }, + }, + async background() { + browser.runtime.onSuspend.addListener(async () => { + browser.test.sendMessage("onSuspend_called"); + }); + }, + }); + + const stub = stubConnectNative(); + await extension.startup(); + + info("Load content page"); + const page = await ExtensionTestUtils.loadContentPage("http://example.com/"); + await extension.awaitMessage("content_done"); + await stub.firstCallPromise; + + info("Terminate extension"); + await extension.terminateBackground(); + await extension.awaitMessage("onSuspend_called"); + + stub.triggerPortDisconnect(); + await extension.awaitMessage("port_disconnected"); + await page.close(); + await extension.unload(); + + stub.restore(); +}); diff --git a/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_permissions.js b/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_permissions.js new file mode 100644 index 0000000000..63f64b487e --- /dev/null +++ b/mobile/android/components/extensions/test/xpcshell/test_ext_native_messaging_permissions.js @@ -0,0 +1,167 @@ +"use strict"; + +const server = createHttpServer({ hosts: ["example.com"] }); +server.registerPathHandler("/dum", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html; charset=utf-8", false); + response.write(""); +}); + +async function testNativeMessaging({ + isPrivileged = false, + permissions, + testBackground, + testContent, +}) { + async function runTest(testFn, completionMessage) { + try { + dump(`Running test before sending ${completionMessage}\n`); + await testFn(); + } catch (e) { + browser.test.fail(`Unexpected error: ${e}`); + } + browser.test.sendMessage(completionMessage); + } + const extension = ExtensionTestUtils.loadExtension({ + isPrivileged, + background: `(${runTest})(${testBackground}, "background_done");`, + manifest: { + content_scripts: [ + { + run_at: "document_end", + js: ["test.js"], + matches: ["http://example.com/dummy"], + }, + ], + permissions, + }, + files: { + "test.js": `(${runTest})(${testContent}, "content_done");`, + }, + }); + + // Run background script. + await extension.startup(); + await extension.awaitMessage("background_done"); + + // Run content script. + const page = await ExtensionTestUtils.loadContentPage( + "http://example.com/dummy" + ); + await extension.awaitMessage("content_done"); + await page.close(); + + await extension.unload(); +} + +// Checks that unprivileged extensions cannot use any of the nativeMessaging +// APIs on Android. +add_task(async function test_nativeMessaging_unprivileged() { + function testScript() { + browser.test.assertEq( + browser.runtime.connectNative, + undefined, + "connectNative should not be available in unprivileged extensions" + ); + browser.test.assertEq( + browser.runtime.sendNativeMessage, + undefined, + "sendNativeMessage should not be available in unprivileged extensions" + ); + } + + const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { + await testNativeMessaging({ + isPrivileged: false, + permissions: [ + "geckoViewAddons", + "nativeMessaging", + "nativeMessagingFromContent", + ], + testBackground: testScript, + testContent: testScript, + }); + }); + AddonTestUtils.checkMessages(messages, { + expected: [ + { message: /Invalid extension permission: geckoViewAddons/ }, + { message: /Invalid extension permission: nativeMessaging/ }, + { message: /Invalid extension permission: nativeMessagingFromContent/ }, + ], + }); +}); + +// Checks that privileged extensions can still not use native messaging without +// the geckoViewAddons permission. +add_task(async function test_geckoViewAddons_missing() { + const ERROR_NATIVE_MESSAGE_FROM_BACKGROUND = + "Native manifests are not supported on android"; + const ERROR_NATIVE_MESSAGE_FROM_CONTENT = + /^Native messaging not allowed: \{.*"envType":"content_child","url":"http:\/\/example\.com\/dummy"\}$/; + + async function testBackground() { + await browser.test.assertRejects( + browser.runtime.sendNativeMessage("dummy_nativeApp", "DummyMsg"), + // Redacted error: ERROR_NATIVE_MESSAGE_FROM_BACKGROUND + "An unexpected error occurred", + "Background script cannot use nativeMessaging without geckoViewAddons" + ); + } + async function testContent() { + await browser.test.assertRejects( + browser.runtime.sendNativeMessage("dummy_nativeApp", "DummyMsg"), + // Redacted error: ERROR_NATIVE_MESSAGE_FROM_CONTENT + "An unexpected error occurred", + "Content script cannot use nativeMessaging without geckoViewAddons" + ); + } + + const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { + await testNativeMessaging({ + isPrivileged: true, + permissions: ["nativeMessaging", "nativeMessagingFromContent"], + testBackground, + testContent, + }); + }); + AddonTestUtils.checkMessages(messages, { + expected: [ + { errorMessage: ERROR_NATIVE_MESSAGE_FROM_BACKGROUND }, + { errorMessage: ERROR_NATIVE_MESSAGE_FROM_CONTENT }, + ], + }); +}); + +// Checks that privileged extensions cannot use native messaging from content +// without the nativeMessagingFromContent permission. +add_task(async function test_nativeMessagingFromContent_missing() { + const ERROR_NATIVE_MESSAGE_FROM_CONTENT_NO_PERM = + /^Unexpected messaging sender: \{.*"envType":"content_child","url":"http:\/\/example\.com\/dummy"\}$/; + function testBackground() { + // sendNativeMessage / connectNative are expected to succeed, but we + // are not testing that here because XpcshellTestRunnerService does not + // have a WebExtension.MessageDelegate that handles the message. + // There are plenty of mochitests that rely on connectNative, so we are + // not testing that here. + } + async function testContent() { + await browser.test.assertRejects( + browser.runtime.sendNativeMessage("dummy_nativeApp", "DummyMsg"), + // Redacted error: ERROR_NATIVE_MESSAGE_FROM_CONTENT_NO_PERM + "An unexpected error occurred", + "Trying to get through to native messaging but without luck" + ); + } + + const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { + await testNativeMessaging({ + isPrivileged: true, + permissions: ["geckoViewAddons", "nativeMessaging"], + testBackground, + testContent, + }); + }); + AddonTestUtils.checkMessages(messages, { + expected: [{ errorMessage: ERROR_NATIVE_MESSAGE_FROM_CONTENT_NO_PERM }], + }); +}); diff --git a/mobile/android/components/extensions/test/xpcshell/xpcshell.toml b/mobile/android/components/extensions/test/xpcshell/xpcshell.toml new file mode 100644 index 0000000000..c9486971a0 --- /dev/null +++ b/mobile/android/components/extensions/test/xpcshell/xpcshell.toml @@ -0,0 +1,9 @@ +[DEFAULT] +head = "head.js" +firefox-appdir = "browser" +tags = "webextensions in-process-webextensions" +run-if = ["os == 'android'"] + +["test_ext_native_messaging_geckoview.js"] + +["test_ext_native_messaging_permissions.js"] -- cgit v1.2.3