Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 var pass = chrome.test.callbackPass; | |
| 6 var fail = chrome.test.callbackFail; | |
| 7 var assertEq = chrome.test.assertEq; | |
| 8 var assertTrue = chrome.test.assertTrue; | |
| 9 var relativePath = '/extensions/api_test/executescript/frame_id/frames.html'; | |
| 10 var testOrigin = 'http://a.com:PORT'; | |
| 11 var testUrl = 'http://a.com:PORT' + relativePath; | |
| 12 | |
| 13 // Frame ID of every frame in this test, and the patterns of the frame URLs. | |
| 14 // All patterns are mutually exclusive. | |
| 15 | |
| 16 var tabId; | |
| 17 // Main frame. | |
| 18 var id_frame_top = 0; | |
|
Devlin
2016/01/25 19:36:40
nit: js style
robwu
2016/01/26 11:03:02
Done.
| |
| 19 var r_frame_top = /frames\.html/; | |
| 20 // Frame with (same-origin) about:srcdoc. | |
| 21 var id_frame_srcdoc; | |
| 22 var r_frame_srcdoc = /about:srcdoc/; | |
| 23 // Frame with (unique-origin) sandboxed about:blank. | |
| 24 var id_frame_unreachable; | |
| 25 var r_frame_unreachable = /about:blank/; | |
| 26 // Frame with same-origin page. | |
| 27 var id_frame_second; | |
| 28 var r_frame_second = /frame\.html/; | |
| 29 // Same-origin child frame of |frame_second|. | |
| 30 var id_frame_third; | |
| 31 var r_frame_third = /nested\.html/; | |
| 32 // Frame for which the extension does not have the right permissions. | |
| 33 var id_frame_nopermission; | |
| 34 var r_frame_nopermission = /empty\.html/; | |
| 35 | |
| 36 function matchesAny(urls, regex) { | |
| 37 return urls.some(function(url) { return regex.test(url); }); | |
| 38 } | |
| 39 | |
| 40 var g_cssCounter = 0; | |
| 41 // Calls chrome.tabs.insertCSS and invoke the callback with a list of affected | |
| 42 // URLs. This function assumes that the insertCSS call will succeed. | |
| 43 function insertCSS(tabId, injectDetails, callback) { | |
| 44 var marker = (++g_cssCounter) + 'px'; | |
| 45 injectDetails.code = 'body { min-width: ' + marker + ';}'; | |
| 46 chrome.tabs.insertCSS(tabId, injectDetails, function() { | |
| 47 chrome.test.assertNoLastError(); | |
| 48 chrome.tabs.executeScript( | |
| 49 tabId, { | |
| 50 code: '[getComputedStyle(document.body).minWidth, document.URL];', | |
| 51 allFrames: true, | |
| 52 matchAboutBlank: true | |
| 53 }, | |
| 54 function(results) { | |
| 55 chrome.test.assertNoLastError(); | |
| 56 results = results | |
| 57 .filter(function(result) { | |
| 58 return result && result[0] === marker; | |
| 59 }) | |
| 60 .map(function(result) { | |
| 61 return result[1]; // "document.URL" | |
| 62 }); | |
| 63 callback(results); | |
| 64 }); | |
| 65 }); | |
| 66 } | |
| 67 | |
| 68 chrome.test.getConfig(function(config) { | |
| 69 testOrigin = testOrigin.replace(/PORT/, config.testServer.port); | |
| 70 testUrl = testUrl.replace(/PORT/, config.testServer.port); | |
| 71 chrome.tabs.onUpdated.addListener(function(_, changeInfo, tab) { | |
| 72 if (changeInfo.status != 'complete' || tab.id !== tabId) | |
| 73 return; | |
| 74 | |
| 75 chrome.webNavigation.getAllFrames({tabId: tabId}, function(frames) { | |
| 76 function getFrameId(r_url) { | |
| 77 var filtered = | |
| 78 frames.filter(function(frame) { return r_url.test(frame.url); }); | |
| 79 // Sanity check. | |
| 80 chrome.test.assertEq(1, filtered.length); | |
| 81 chrome.test.assertTrue(filtered[0].frameId > 0); | |
| 82 return filtered[0].frameId; | |
| 83 } | |
| 84 | |
| 85 id_frame_srcdoc = getFrameId(r_frame_srcdoc); | |
| 86 id_frame_unreachable = getFrameId(r_frame_unreachable); | |
| 87 id_frame_second = getFrameId(r_frame_second); | |
| 88 id_frame_third = getFrameId(r_frame_third); | |
| 89 id_frame_nopermission = getFrameId(r_frame_nopermission); | |
| 90 | |
| 91 runTests(config); | |
| 92 }); | |
| 93 }); | |
| 94 | |
| 95 chrome.tabs.create({url: testUrl}, function(tab) { tabId = tab.id; }); | |
| 96 }); | |
| 97 | |
| 98 function runTests(config) { | |
| 99 chrome.test.runTests([ | |
| 100 function executeScriptFrameIdTop() { | |
| 101 chrome.tabs.executeScript( | |
| 102 tabId, {frameId: 0, code: 'document.URL'}, pass(function(results) { | |
| 103 assertEq(1, results.length); | |
| 104 assertTrue(matchesAny(results, r_frame_top)); | |
| 105 })); | |
| 106 }, | |
| 107 | |
| 108 function executeScriptFrameIdTopAllFrames() { | |
| 109 chrome.tabs.executeScript( | |
| 110 tabId, { | |
| 111 frameId: 0, | |
| 112 matchAboutBlank: true, | |
| 113 allFrames: true, | |
| 114 code: 'document.URL' | |
| 115 }, | |
| 116 pass(function(results) { | |
| 117 assertEq(4, results.length); | |
| 118 assertTrue(matchesAny(results, r_frame_top)); | |
| 119 assertTrue(matchesAny(results, r_frame_srcdoc)); | |
| 120 assertTrue(matchesAny(results, r_frame_second)); | |
| 121 assertTrue(matchesAny(results, r_frame_third)); | |
| 122 })); | |
| 123 }, | |
| 124 | |
| 125 function executeScriptFrameIdSrcdoc() { | |
| 126 chrome.tabs.executeScript( | |
| 127 tabId, { | |
| 128 frameId: id_frame_srcdoc, | |
| 129 matchAboutBlank: true, | |
| 130 code: 'document.URL' | |
| 131 }, | |
| 132 pass(function(results) { | |
| 133 assertEq(1, results.length); | |
| 134 assertTrue(matchesAny(results, r_frame_srcdoc)); | |
| 135 })); | |
| 136 }, | |
| 137 | |
| 138 function executeScriptFrameIdSrcdocWithoutMatchAboutBlank() { | |
| 139 // TODO(robwu): Why is the origin serialized as "about:blank" instead of | |
| 140 // "about:srcdoc"? | |
| 141 chrome.tabs.executeScript( | |
| 142 tabId, {frameId: id_frame_srcdoc, code: 'document.URL'}, | |
| 143 fail( | |
| 144 'Cannot access "about:blank" at origin "' + testOrigin + '". ' + | |
| 145 'Extension must have permission to access the frame\'s origin, ' + | |
| 146 'and matchAboutBlank must be true.')); | |
| 147 }, | |
| 148 | |
| 149 function executeScriptFrameIdSrcdocAllFrames() { | |
| 150 chrome.tabs.executeScript( | |
| 151 tabId, { | |
| 152 frameId: id_frame_srcdoc, | |
| 153 matchAboutBlank: true, | |
| 154 allFrames: true, | |
| 155 code: 'document.URL' | |
| 156 }, | |
| 157 pass(function(results) { | |
| 158 assertEq(1, results.length); | |
| 159 assertTrue(matchesAny(results, r_frame_srcdoc)); | |
| 160 })); | |
| 161 }, | |
| 162 | |
| 163 function executeScriptFrameIdSandboxedFrame() { | |
| 164 chrome.tabs.executeScript( | |
| 165 tabId, { | |
| 166 frameId: id_frame_unreachable, | |
| 167 matchAboutBlank: true, | |
| 168 code: 'document.URL' | |
| 169 }, | |
| 170 fail( | |
| 171 'Cannot access "about:blank" at origin "null". Extension must ' + | |
| 172 'have permission to access the frame\'s origin, and ' + | |
| 173 'matchAboutBlank must be true.')); | |
| 174 }, | |
| 175 | |
| 176 function executeScriptFrameIdSubframe() { | |
| 177 chrome.tabs.executeScript( | |
| 178 tabId, {frameId: id_frame_second, code: 'document.URL'}, | |
| 179 pass(function(results) { | |
| 180 assertEq(1, results.length); | |
| 181 assertTrue(matchesAny(results, r_frame_second)); | |
| 182 })); | |
| 183 }, | |
| 184 | |
| 185 function executeScriptFrameIdSubframeAllFrames() { | |
| 186 chrome.tabs.executeScript( | |
| 187 tabId, | |
| 188 {frameId: id_frame_second, allFrames: true, code: 'document.URL'}, | |
| 189 pass(function(results) { | |
| 190 assertEq(2, results.length); | |
| 191 assertTrue(matchesAny(results, r_frame_second)); | |
| 192 assertTrue(matchesAny(results, r_frame_third)); | |
| 193 })); | |
| 194 }, | |
| 195 | |
| 196 function executeScriptFrameIdNestedFrame() { | |
| 197 chrome.tabs.executeScript( | |
| 198 tabId, {frameId: id_frame_third, code: 'document.URL'}, | |
| 199 pass(function(results) { | |
| 200 assertEq(1, results.length); | |
| 201 assertTrue(matchesAny(results, r_frame_third)); | |
| 202 })); | |
| 203 }, | |
| 204 | |
| 205 function executeScriptFrameIdNestedFrame() { | |
| 206 chrome.tabs.executeScript( | |
| 207 tabId, | |
| 208 {frameId: id_frame_third, allFrames: true, code: 'document.URL'}, | |
| 209 pass(function(results) { | |
| 210 assertEq(1, results.length); | |
| 211 assertTrue(matchesAny(results, r_frame_third)); | |
| 212 })); | |
| 213 }, | |
| 214 | |
| 215 function executeScriptFrameIdNoPermission() { | |
| 216 chrome.tabs.executeScript( | |
| 217 tabId, {frameId: id_frame_nopermission, code: 'document.URL'}, | |
| 218 fail( | |
| 219 'Cannot access contents of url "http://c.com:' + | |
| 220 config.testServer.port + '/empty.html". Extension manifest ' + | |
| 221 'must request permission to access this host.')); | |
| 222 }, | |
| 223 | |
| 224 function executeScriptFrameIdNonExistent() { | |
| 225 chrome.tabs.executeScript( | |
| 226 tabId, {frameId: 999999999, code: 'document.URL'}, | |
| 227 fail('No frame with id 999999999 in tab ' + tabId + '.')); | |
| 228 }, | |
| 229 | |
| 230 function executeScriptFrameIdNegative() { | |
| 231 try { | |
| 232 chrome.tabs.executeScript( | |
| 233 tabId, {frameId: -1, code: 'document.URL'}, function() { | |
| 234 chrome.test.fail( | |
| 235 'executeScript should never have been executed!'); | |
| 236 }); | |
| 237 } catch (e) { | |
| 238 assertEq( | |
| 239 'Invalid value for argument 2. Property \'frameId\': ' + | |
| 240 'Value must not be less than 0.', | |
| 241 e.message); | |
| 242 chrome.test.succeed(); | |
| 243 } | |
| 244 }, | |
| 245 | |
| 246 function insertCSSFrameIdTop() { | |
| 247 insertCSS(tabId, {frameId: 0}, pass(function(results) { | |
| 248 assertEq(1, results.length); | |
| 249 assertTrue(matchesAny(results, r_frame_top)); | |
| 250 })); | |
| 251 }, | |
| 252 | |
| 253 function insertCSSFrameIdTopAllFrames() { | |
| 254 insertCSS( | |
| 255 tabId, {frameId: 0, matchAboutBlank: true, allFrames: true}, | |
| 256 pass(function(results) { | |
| 257 assertEq(4, results.length); | |
| 258 assertTrue(matchesAny(results, r_frame_top)); | |
| 259 assertTrue(matchesAny(results, r_frame_srcdoc)); | |
| 260 assertTrue(matchesAny(results, r_frame_second)); | |
| 261 assertTrue(matchesAny(results, r_frame_third)); | |
| 262 })); | |
| 263 }, | |
| 264 | |
| 265 function insertCSSFrameIdSrcdoc() { | |
| 266 insertCSS( | |
| 267 tabId, {frameId: id_frame_srcdoc, matchAboutBlank: true}, | |
| 268 pass(function(results) { | |
| 269 assertEq(1, results.length); | |
| 270 assertTrue(matchesAny(results, r_frame_srcdoc)); | |
| 271 })); | |
| 272 }, | |
| 273 | |
| 274 function insertCSSFrameIdSrcdocWithoutMatchAboutBlank() { | |
| 275 // TODO(robwu): Why is the origin serialized as "about:blank" instead of | |
| 276 // "about:srcdoc"? | |
| 277 chrome.tabs.insertCSS( | |
| 278 tabId, {frameId: id_frame_srcdoc, code: 'body{color:red;}'}, | |
| 279 fail( | |
| 280 'Cannot access "about:blank" at origin "' + testOrigin + '". ' + | |
| 281 'Extension must have permission to access the frame\'s origin, ' + | |
| 282 'and matchAboutBlank must be true.')) | |
| 283 }, | |
| 284 | |
| 285 function insertCSSFrameIdSrcdocAllFrames() { | |
| 286 insertCSS( | |
| 287 tabId, | |
| 288 {frameId: id_frame_srcdoc, matchAboutBlank: true, allFrames: true}, | |
| 289 pass(function(results) { | |
| 290 assertEq(1, results.length); | |
| 291 assertTrue(matchesAny(results, r_frame_srcdoc)); | |
| 292 })); | |
| 293 }, | |
| 294 | |
| 295 function insertCSSFrameIdSandboxedFrame() { | |
| 296 chrome.tabs.insertCSS( | |
| 297 tabId, { | |
| 298 frameId: id_frame_unreachable, | |
| 299 matchAboutBlank: true, | |
| 300 code: 'body{color:red}' | |
| 301 }, | |
| 302 fail( | |
| 303 'Cannot access "about:blank" at origin "null". Extension must ' + | |
| 304 'have permission to access the frame\'s origin, and ' + | |
| 305 'matchAboutBlank must be true.')) | |
| 306 }, | |
| 307 | |
| 308 function insertCSSFrameIdSubframe() { | |
| 309 insertCSS(tabId, {frameId: id_frame_second}, pass(function(results) { | |
| 310 assertEq(1, results.length); | |
| 311 assertTrue(matchesAny(results, r_frame_second)); | |
| 312 })); | |
| 313 }, | |
| 314 | |
| 315 function insertCSSFrameIdSubframeAllFrames() { | |
| 316 insertCSS( | |
| 317 tabId, {frameId: id_frame_second, allFrames: true}, | |
| 318 pass(function(results) { | |
| 319 assertEq(2, results.length); | |
| 320 assertTrue(matchesAny(results, r_frame_second)); | |
| 321 assertTrue(matchesAny(results, r_frame_third)); | |
| 322 })); | |
| 323 }, | |
| 324 | |
| 325 function insertCSSFrameIdNestedFrame() { | |
| 326 insertCSS(tabId, {frameId: id_frame_third}, pass(function(results) { | |
| 327 assertEq(1, results.length); | |
| 328 assertTrue(matchesAny(results, r_frame_third)); | |
| 329 })); | |
| 330 }, | |
| 331 | |
| 332 function insertCSSFrameIdNestedFrame() { | |
| 333 insertCSS( | |
| 334 tabId, {frameId: id_frame_third, allFrames: true}, | |
| 335 pass(function(results) { | |
| 336 assertEq(1, results.length); | |
| 337 assertTrue(matchesAny(results, r_frame_third)); | |
| 338 })); | |
| 339 }, | |
| 340 | |
| 341 function insertCSSFrameIdNoPermission() { | |
| 342 chrome.tabs.insertCSS( | |
| 343 tabId, {frameId: id_frame_nopermission, code: 'body{color:red}'}, | |
| 344 fail( | |
| 345 'Cannot access contents of url "http://c.com:' + | |
| 346 config.testServer.port + '/empty.html". Extension manifest ' + | |
| 347 'must request permission to access this host.')); | |
| 348 }, | |
| 349 | |
| 350 function insertCSSFrameIdNonExistent() { | |
| 351 chrome.tabs.insertCSS( | |
| 352 tabId, {frameId: 999999999, code: 'body{color:red}'}, | |
| 353 fail('No frame with id 999999999 in tab ' + tabId + '.')); | |
| 354 }, | |
| 355 | |
| 356 function insertCSSFrameIdNegative() { | |
| 357 try { | |
| 358 chrome.tabs.insertCSS( | |
| 359 tabId, {frameId: -1, code: 'body{color:red}'}, function() { | |
| 360 chrome.test.fail('insertCSS should never have been executed!'); | |
| 361 }); | |
| 362 } catch (e) { | |
| 363 assertEq( | |
| 364 'Invalid value for argument 2. Property \'frameId\': ' + | |
| 365 'Value must not be less than 0.', | |
| 366 e.message); | |
| 367 chrome.test.succeed(); | |
| 368 } | |
| 369 }, | |
| 370 | |
| 371 ]); | |
| 372 } | |
| OLD | NEW |