summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_ext_script_filenames.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_script_filenames.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_ext_script_filenames.js366
1 files changed, 366 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_script_filenames.js b/toolkit/components/extensions/test/xpcshell/test_ext_script_filenames.js
new file mode 100644
index 0000000000..8e2f6c7b0d
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_script_filenames.js
@@ -0,0 +1,366 @@
+"use strict";
+
+// There is a rejection emitted when a JS file fails to load. On Android,
+// extensions run on the main process and this rejection causes test failures,
+// which is essentially why we need to allow the rejection below.
+PromiseTestUtils.allowMatchingRejectionsGlobally(
+ /Unable to load script.*content_script/
+);
+
+const server = createHttpServer();
+server.registerDirectory("/data/", do_get_file("data"));
+
+const BASE_URL = `http://localhost:${server.identity.primaryPort}/data`;
+
+function computeSHA256Hash(text) {
+ const hasher = Cc["@mozilla.org/security/hash;1"].createInstance(
+ Ci.nsICryptoHash
+ );
+ hasher.init(Ci.nsICryptoHash.SHA256);
+ hasher.update(
+ text.split("").map(c => c.charCodeAt(0)),
+ text.length
+ );
+ return hasher.finish(true);
+}
+
+// This function represents a dummy content or background script that the test
+// cases below should attempt to load but it shouldn't be loaded because we
+// check the extensions of JavaScript files in `nsJARChannel`.
+function scriptThatShouldNotBeLoaded() {
+ browser.test.fail("this should not be executed");
+}
+
+function scriptThatAlwaysRuns() {
+ browser.test.sendMessage("content-script-loaded");
+}
+
+// We use these variables in combination with `scriptThatAlwaysRuns()` to send a
+// signal to the extension and avoid the page to be closed too soon.
+const alwaysRunsFileName = "always_run.js";
+const alwaysRunsContentScript = {
+ matches: ["<all_urls>"],
+ js: [alwaysRunsFileName],
+ run_at: "document_start",
+};
+
+add_task(async function test_content_script_filename_without_extension() {
+ // Filenames without any extension should not be loaded.
+ let invalidFileName = "content_script";
+ let extensionData = {
+ manifest: {
+ content_scripts: [
+ alwaysRunsContentScript,
+ {
+ matches: ["<all_urls>"],
+ js: [invalidFileName],
+ },
+ ],
+ },
+ files: {
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ [alwaysRunsFileName]: scriptThatAlwaysRuns,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ let contentPage = await ExtensionTestUtils.loadContentPage(
+ `${BASE_URL}/file_sample.html`
+ );
+
+ await extension.awaitMessage("content-script-loaded");
+
+ await contentPage.close();
+ await extension.unload();
+});
+
+add_task(async function test_content_script_filename_with_invalid_extension() {
+ let validFileName = "content_script.js";
+ let invalidFileName = "content_script.xyz";
+ let extensionData = {
+ manifest: {
+ content_scripts: [
+ alwaysRunsContentScript,
+ {
+ matches: ["<all_urls>"],
+ js: [validFileName, invalidFileName],
+ },
+ ],
+ },
+ files: {
+ // This makes sure that, when one of the content scripts fails to load,
+ // none of the content scripts are executed.
+ [validFileName]: scriptThatShouldNotBeLoaded,
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ [alwaysRunsFileName]: scriptThatAlwaysRuns,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ let contentPage = await ExtensionTestUtils.loadContentPage(
+ `${BASE_URL}/file_sample.html`
+ );
+
+ await extension.awaitMessage("content-script-loaded");
+
+ await contentPage.close();
+ await extension.unload();
+});
+
+add_task(async function test_bg_script_injects_script_with_invalid_ext() {
+ function backgroundScript() {
+ browser.test.sendMessage("background-script-loaded");
+ }
+
+ let validFileName = "background.js";
+ let invalidFileName = "invalid_background.xyz";
+ let extensionData = {
+ background() {
+ const script = document.createElement("script");
+ script.src = "./invalid_background.xyz";
+ document.head.appendChild(script);
+
+ const validScript = document.createElement("script");
+ validScript.src = "./background.js";
+ document.head.appendChild(validScript);
+ },
+ files: {
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ [validFileName]: backgroundScript,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ await extension.awaitMessage("background-script-loaded");
+
+ await extension.unload();
+});
+
+add_task(async function test_background_scripts() {
+ function backgroundScript() {
+ browser.test.sendMessage("background-script-loaded");
+ }
+
+ let validFileName = "background.js";
+ let invalidFileName = "invalid_background.xyz";
+ let extensionData = {
+ manifest: {
+ background: {
+ scripts: [invalidFileName, validFileName],
+ },
+ },
+ files: {
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ [validFileName]: backgroundScript,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ await extension.awaitMessage("background-script-loaded");
+
+ await extension.unload();
+});
+
+add_task(async function test_background_page_injects_scripts_inline() {
+ function injectedBackgroundScript() {
+ browser.test.log(
+ "inline script injectedBackgroundScript has been executed"
+ );
+ browser.test.sendMessage("background-script-loaded");
+ }
+
+ let backgroundHtmlPage = "background_page.html";
+ let validFileName = "injected_background.js";
+ let invalidFileName = "invalid_background.xyz";
+
+ let inlineScript = `(${function () {
+ const script = document.createElement("script");
+ script.src = "./invalid_background.xyz";
+ document.head.appendChild(script);
+ const validScript = document.createElement("script");
+ validScript.src = "./injected_background.js";
+ document.head.appendChild(validScript);
+ }})()`;
+
+ const inlineScriptSHA256 = computeSHA256Hash(inlineScript);
+
+ info(
+ `Computed sha256 for the inline script injectedBackgroundScript: ${inlineScriptSHA256}`
+ );
+
+ let extensionData = {
+ manifest: {
+ background: { page: backgroundHtmlPage },
+ content_security_policy: [
+ "script-src",
+ "'self'",
+ `'sha256-${inlineScriptSHA256}'`,
+ ";",
+ ].join(" "),
+ },
+ files: {
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ [validFileName]: injectedBackgroundScript,
+ "pre-script.js": () => {
+ window.onsecuritypolicyviolation = evt => {
+ const { violatedDirective, originalPolicy } = evt;
+ browser.test.fail(
+ `Unexpected csp violation: ${JSON.stringify({
+ violatedDirective,
+ originalPolicy,
+ })}`
+ );
+ // Let the test to fail immediately when an unexpected csp violation
+ // prevented the inline script from being executed successfully.
+ browser.test.sendMessage("background-script-loaded");
+ };
+ },
+ [backgroundHtmlPage]: `
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8"></head>
+ <script src="pre-script.js"></script>
+ <script>${inlineScript}</script>
+ </head>
+ </html>`,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ await extension.awaitMessage("background-script-loaded");
+
+ await extension.unload();
+});
+
+add_task(async function test_background_page_injects_scripts() {
+ // This is the initial background script loaded in the HTML page.
+ function backgroundScript() {
+ const script = document.createElement("script");
+ script.src = "./invalid_background.xyz";
+ document.head.appendChild(script);
+
+ const validScript = document.createElement("script");
+ validScript.src = "./injected_background.js";
+ document.head.appendChild(validScript);
+ }
+
+ // This is the script injected by the script defined in `backgroundScript()`.
+ function injectedBackgroundScript() {
+ browser.test.sendMessage("background-script-loaded");
+ }
+
+ let backgroundHtmlPage = "background_page.html";
+ let validFileName = "injected_background.js";
+ let invalidFileName = "invalid_background.xyz";
+ let extensionData = {
+ manifest: {
+ background: { page: backgroundHtmlPage },
+ },
+ files: {
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ [validFileName]: injectedBackgroundScript,
+ [backgroundHtmlPage]: `
+ <html>
+ <head>
+ <meta charset="utf-8"></head>
+ <script src="./background.js"></script>
+ </head>
+ </html>`,
+ "background.js": backgroundScript,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ await extension.awaitMessage("background-script-loaded");
+
+ await extension.unload();
+});
+
+add_task(async function test_background_script_registers_content_script() {
+ let invalidFileName = "content_script";
+ let extensionData = {
+ manifest: {
+ permissions: ["<all_urls>"],
+ },
+ async background() {
+ await browser.contentScripts.register({
+ js: [{ file: "/content_script" }],
+ matches: ["<all_urls>"],
+ });
+ browser.test.sendMessage("background-script-loaded");
+ },
+ files: {
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ let contentPage = await ExtensionTestUtils.loadContentPage(
+ `${BASE_URL}/file_sample.html`
+ );
+
+ await extension.awaitMessage("background-script-loaded");
+
+ await contentPage.close();
+ await extension.unload();
+});
+
+add_task(async function test_web_accessible_resources() {
+ function contentScript() {
+ const script = document.createElement("script");
+ script.src = browser.runtime.getURL("content_script.css");
+ script.onerror = () => {
+ browser.test.sendMessage("second-content-script-loaded");
+ };
+
+ document.head.appendChild(script);
+ }
+
+ let contentScriptFileName = "content_script.js";
+ let invalidFileName = "content_script.css";
+ let extensionData = {
+ manifest: {
+ web_accessible_resources: [invalidFileName],
+ content_scripts: [
+ alwaysRunsContentScript,
+ {
+ matches: ["<all_urls>"],
+ js: [contentScriptFileName],
+ },
+ ],
+ },
+ files: {
+ [invalidFileName]: scriptThatShouldNotBeLoaded,
+ [contentScriptFileName]: contentScript,
+ [alwaysRunsFileName]: scriptThatAlwaysRuns,
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ let contentPage = await ExtensionTestUtils.loadContentPage(
+ `${BASE_URL}/file_sample.html`
+ );
+
+ await extension.awaitMessage("content-script-loaded");
+ await extension.awaitMessage("second-content-script-loaded");
+
+ await contentPage.close();
+ await extension.unload();
+});