test_ext_tabs_executeScript.html (9470B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tabs executeScript Test</title> 6 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 7 <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script> 8 <script type="text/javascript" src="head.js"></script> 9 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 10 </head> 11 <body> 12 13 <script type="text/javascript"> 14 "use strict"; 15 16 add_task(async function testExecuteScript() { 17 await SpecialPowers.pushPrefEnv({ 18 set: [["dom.security.https_first", false]], 19 }); 20 const BASE = "http://mochi.test:8888/tests/mobile/shared/components/extensions/test/mochitest/"; 21 const URL = BASE + "file_iframe_document.html"; 22 23 const win = window.open(URL); 24 await new Promise(resolve => win.addEventListener("load", resolve, {once: true})); 25 26 async function background() { 27 try { 28 const [tab] = await browser.tabs.query({active: true, currentWindow: true}); 29 const frames = await browser.webNavigation.getAllFrames({tabId: tab.id}); 30 31 browser.test.log(`FRAMES: ${frames[1].frameId} ${JSON.stringify(frames)}\n`); 32 await Promise.all([ 33 browser.tabs.executeScript({ 34 code: "42", 35 }).then(result => { 36 browser.test.assertEq(1, result.length, "Expected one callback result"); 37 browser.test.assertEq(42, result[0], "Expected callback result"); 38 }), 39 40 browser.tabs.executeScript({ 41 file: "script.js", 42 code: "42", 43 }).then(() => { 44 browser.test.fail("Expected not to be able to execute a script with both file and code"); 45 }, error => { 46 browser.test.assertTrue(/a 'code' or a 'file' property, but not both/.test(error.message), 47 "Got expected error"); 48 }), 49 50 browser.tabs.executeScript({ 51 file: "script.js", 52 }).then(result => { 53 browser.test.assertEq(1, result.length, "Expected one callback result"); 54 browser.test.assertEq(undefined, result[0], "Expected callback result"); 55 }), 56 57 browser.tabs.executeScript({ 58 file: "script2.js", 59 }).then(result => { 60 browser.test.assertEq(1, result.length, "Expected one callback result"); 61 browser.test.assertEq(27, result[0], "Expected callback result"); 62 }), 63 64 browser.tabs.executeScript({ 65 code: "location.href;", 66 allFrames: true, 67 }).then(result => { 68 browser.test.assertTrue(Array.isArray(result), "Result is an array"); 69 70 browser.test.assertEq(2, result.length, "Result has correct length"); 71 72 browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct"); 73 browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct"); 74 }), 75 76 browser.tabs.executeScript({ 77 code: "location.href;", 78 allFrames: true, 79 matchAboutBlank: true, 80 }).then(result => { 81 browser.test.assertTrue(Array.isArray(result), "Result is an array"); 82 83 browser.test.assertEq(3, result.length, "Result has correct length"); 84 85 browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct"); 86 browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct"); 87 browser.test.assertEq("about:blank", result[2], "Thirds result is correct"); 88 }), 89 90 browser.tabs.executeScript({ 91 code: "location.href;", 92 runAt: "document_end", 93 }).then(result => { 94 browser.test.assertEq(1, result.length, "Expected callback result"); 95 browser.test.assertEq("string", typeof result[0], "Result is a string"); 96 97 browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "Result is correct"); 98 }), 99 100 browser.tabs.executeScript({ 101 code: "window", 102 }).then(() => { 103 browser.test.fail("Expected error when returning non-structured-clonable object"); 104 }, error => { 105 browser.test.assertEq("<anonymous code>", error.fileName, "Got expected fileName"); 106 browser.test.assertEq("Script '<anonymous code>' result is non-structured-clonable data", 107 error.message, "Got expected error"); 108 }), 109 110 browser.tabs.executeScript({ 111 code: "Promise.resolve(window)", 112 }).then(() => { 113 browser.test.fail("Expected error when returning non-structured-clonable object"); 114 }, error => { 115 browser.test.assertEq("<anonymous code>", error.fileName, "Got expected fileName"); 116 browser.test.assertEq("Script '<anonymous code>' result is non-structured-clonable data", 117 error.message, "Got expected error"); 118 }), 119 120 browser.tabs.executeScript({ 121 file: "script3.js", 122 }).then(() => { 123 browser.test.fail("Expected error when returning non-structured-clonable object"); 124 }, error => { 125 const expected = /Script '.*script3.js' result is non-structured-clonable data/; 126 browser.test.assertTrue(expected.test(error.message), "Got expected error"); 127 browser.test.assertTrue(error.fileName.endsWith("script3.js"), "Got expected fileName"); 128 }), 129 130 browser.tabs.executeScript({ 131 frameId: Number.MAX_SAFE_INTEGER, 132 code: "42", 133 }).then(() => { 134 browser.test.fail("Expected error when specifying invalid frame ID"); 135 }, error => { 136 browser.test.assertEq( 137 `Invalid frame IDs: [${Number.MAX_SAFE_INTEGER}].`, 138 error.message, 139 "Got expected error" 140 ); 141 }), 142 143 browser.tabs.create({url: "http://example.net/", active: false}).then(async tab => { 144 await browser.tabs.executeScript(tab.id, { 145 code: "42", 146 }).then(() => { 147 browser.test.fail("Expected error when trying to execute on invalid domain"); 148 }, error => { 149 browser.test.assertEq(`Missing host permission for the tab`, 150 error.message, "Got expected error"); 151 }); 152 153 await browser.tabs.remove(tab.id); 154 }), 155 156 browser.tabs.executeScript({ 157 code: "Promise.resolve(42)", 158 }).then(result => { 159 browser.test.assertEq(42, result[0], "Got expected promise resolution value as result"); 160 }), 161 162 browser.tabs.executeScript({ 163 code: "location.href;", 164 runAt: "document_end", 165 allFrames: true, 166 }).then(result => { 167 browser.test.assertTrue(Array.isArray(result), "Result is an array"); 168 169 browser.test.assertEq(2, result.length, "Result has correct length"); 170 171 browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct"); 172 browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct"); 173 }), 174 175 browser.tabs.executeScript({ 176 code: "location.href;", 177 frameId: frames[0].frameId, 178 }).then(result => { 179 browser.test.assertEq(1, result.length, "Expected one result"); 180 browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), `Result for frameId[0] is correct: ${result[0]}`); 181 }), 182 183 browser.tabs.executeScript({ 184 code: "location.href;", 185 frameId: frames[1].frameId, 186 }).then(result => { 187 browser.test.assertEq(1, result.length, "Expected one result"); 188 browser.test.assertEq("http://mochi.test:8888/", result[0], "Result for frameId[1] is correct"); 189 }), 190 191 browser.tabs.create({url: "http://example.com/"}).then(async tab => { 192 const result = await browser.tabs.executeScript(tab.id, {code: "location.href"}); 193 194 browser.test.assertEq("http://example.com/", result[0], "Script executed correctly in new tab"); 195 196 await browser.tabs.remove(tab.id); 197 }), 198 199 // This currently does not work on Android. 200 /* 201 browser.tabs.create({url: "about:blank"}).then(async tab => { 202 const result = await browser.tabs.executeScript(tab.id, {code: "location.href", matchAboutBlank: true}); 203 browser.test.assertEq("about:blank", result[0], "Script executed correctly in new tab"); 204 await browser.tabs.remove(tab.id); 205 }), 206 */ 207 208 new Promise(resolve => { 209 browser.runtime.onMessage.addListener(message => { 210 browser.test.assertEq("script ran", message, "Expected runtime message"); 211 resolve(); 212 }); 213 }), 214 ]); 215 216 browser.test.notifyPass("executeScript"); 217 } catch (e) { 218 browser.test.fail(`Error: ${e} :: ${e.stack}`); 219 browser.test.notifyFail("executeScript"); 220 } 221 } 222 223 const extension = ExtensionTestUtils.loadExtension({ 224 manifest: { 225 "permissions": ["http://mochi.test/", "http://example.com/", "webNavigation"], 226 }, 227 228 background, 229 230 files: { 231 "script.js": function() { 232 browser.runtime.sendMessage("script ran"); 233 }, 234 235 "script2.js": "27", 236 237 "script3.js": "window", 238 }, 239 }); 240 241 await extension.startup(); 242 243 await extension.awaitFinish("executeScript"); 244 245 await extension.unload(); 246 247 win.close(); 248 }); 249 </script> 250 251 </body> 252 </html>