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