Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var defaultUrl = 'http://www.google.com'; | 5 var defaultUrl = 'http://www.google.com'; |
| 6 | 6 |
| 7 | |
| 8 // Utility function to open a URL in a new tab. If the useIncognito global is | 7 // Utility function to open a URL in a new tab. If the useIncognito global is |
| 9 // true, the URL is opened in a new incognito window, otherwise it is opened in | 8 // true, the URL is opened in a new incognito window, otherwise it is opened in |
| 10 // a new tab in the current window. Alternatively, whether to use incognito | 9 // a new tab in the current window. Alternatively, whether to use incognito |
| 11 // can be specified as a second argument which overrides the global setting. | 10 // can be specified as a second argument which overrides the global setting. |
| 12 var useIncognito = false; | 11 var useIncognito = false; |
| 13 function openTab(url, incognito) { | 12 function openTab(url, incognito) { |
| 14 if (incognito == undefined ? useIncognito : incognito) { | 13 if (incognito == undefined ? useIncognito : incognito) { |
| 15 chrome.windows.create({'url': url, 'incognito': true}); | 14 chrome.windows.create({'url': url, 'incognito': true}); |
| 16 } else { | 15 } else { |
| 17 window.open(url); | 16 window.open(url); |
| 18 } | 17 } |
| 19 } | 18 } |
| 20 | 19 |
| 21 // CHROME API TEST METHODS -- PUT YOUR TESTS BELOW HERE | 20 // CHROME API TEST METHODS -- PUT YOUR TESTS BELOW HERE |
| 22 //////////////////////////////////////////////////////////////////////////////// | 21 //////////////////////////////////////////////////////////////////////////////// |
| 23 | 22 |
| 24 // Makes an API call. | 23 // Makes an API call. |
| 25 function makeApiCall() { | 24 function makeApiCall() { |
| 25 resetStatus(); | |
| 26 chrome.cookies.set({ | 26 chrome.cookies.set({ |
| 27 'url': 'https://www.cnn.com', | 27 'url': 'https://www.cnn.com', |
| 28 'name': 'activity_log_test_cookie', | 28 'name': 'activity_log_test_cookie', |
| 29 'value': 'abcdefg' | 29 'value': 'abcdefg' |
| 30 }); | 30 }); |
| 31 setCompleted('makeApiCall'); | 31 appendCompleted('makeApiCall'); |
| 32 | |
| 32 } | 33 } |
| 33 | 34 |
| 34 // Makes an API call that has a custom binding. | 35 // Makes an API call that has a custom binding. |
| 35 function makeSpecialApiCalls() { | 36 function makeSpecialApiCalls() { |
| 37 resetStatus(); | |
| 36 var url = chrome.extension.getURL('image/cat.jpg'); | 38 var url = chrome.extension.getURL('image/cat.jpg'); |
| 37 var noparam = chrome.extension.getViews(); | 39 var noparam = chrome.extension.getViews(); |
| 38 setCompleted('makeSpecialApiCalls'); | 40 appendCompleted('makeSpecialApiCalls'); |
| 39 } | 41 } |
| 40 | 42 |
| 41 // Checks that we don't double-log calls that go through setHandleRequest | 43 // Checks that we don't double-log calls that go through setHandleRequest |
| 42 // *and* the ExtensionFunction machinery. | 44 // *and* the ExtensionFunction machinery. |
| 43 function checkNoDoubleLogging() { | 45 function checkNoDoubleLogging() { |
| 46 resetStatus(); | |
| 44 chrome.omnibox.setDefaultSuggestion({description: 'hello world'}); | 47 chrome.omnibox.setDefaultSuggestion({description: 'hello world'}); |
| 45 setCompleted('checkNoDoubleLogging'); | 48 appendCompleted('checkNoDoubleLogging'); |
| 46 } | 49 } |
| 47 | 50 |
| 48 // Check whether we log calls to chrome.app.*; | 51 // Check whether we log calls to chrome.app.*; |
| 49 function checkAppCalls() { | 52 function checkAppCalls() { |
| 53 resetStatus(); | |
| 50 var callback = function() {}; | 54 var callback = function() {}; |
| 51 chrome.app.getDetails(); | 55 chrome.app.getDetails(); |
| 52 var b = chrome.app.isInstalled; | 56 var b = chrome.app.isInstalled; |
| 53 var c = chrome.app.installState(callback); | 57 var c = chrome.app.installState(callback); |
| 54 setCompleted('checkAppCalls'); | 58 appendCompleted('checkAppCalls'); |
| 55 } | 59 } |
| 56 | 60 |
| 57 // Makes an API call that the extension doesn't have permission for. | 61 // Makes an API call that the extension doesn't have permission for. |
| 58 // Don't add the management permission or this test won't test the code path. | 62 // Don't add the management permission or this test won't test the code path. |
| 59 function makeBlockedApiCall() { | 63 function makeBlockedApiCall() { |
| 64 resetStatus(); | |
| 60 try { | 65 try { |
| 61 var allExtensions = chrome.management.getAll(); | 66 var allExtensions = chrome.management.getAll(); |
| 62 } catch (err) { } | 67 } catch (err) { } |
| 63 setCompleted('makeBlockedApiCall'); | 68 appendCompleted('makeBlockedApiCall'); |
| 64 } | 69 } |
| 65 | 70 |
| 66 // Injects a content script. | 71 function callObjectMethod() { |
| 67 function injectContentScript() { | 72 resetStatus(); |
| 68 chrome.tabs.onUpdated.addListener( | 73 var storageArea = chrome.storage.sync; |
| 69 function callback(tabId, changeInfo, tab) { | 74 storageArea.clear(); |
| 70 if (changeInfo['status'] === 'complete' && | 75 appendCompleted('callObjectMethod'); |
| 71 tab.url.match(/google\.com/g)) { | |
| 72 chrome.tabs.onUpdated.removeListener(callback); | |
| 73 chrome.tabs.executeScript( | |
| 74 tab.id, | |
| 75 {'file': 'google_cs.js'}, | |
| 76 function() { | |
| 77 chrome.tabs.remove(tabId); | |
| 78 setCompleted('injectContentScript'); | |
| 79 }); | |
| 80 } | |
| 81 } | |
| 82 ); | |
| 83 openTab(defaultUrl); | |
| 84 } | |
| 85 | |
| 86 // Injects a blob of script into a page. | |
| 87 function injectScriptBlob() { | |
| 88 chrome.tabs.onUpdated.addListener( | |
| 89 function callback(tabId, changeInfo, tab) { | |
| 90 if (changeInfo['status'] === 'complete' && | |
| 91 tab.url.match(/google\.com/g)) { | |
| 92 chrome.tabs.onUpdated.removeListener(callback); | |
| 93 chrome.tabs.executeScript( | |
| 94 tab.id, | |
| 95 {'code': 'document.write("g o o g l e");'}, | |
| 96 function() { | |
| 97 chrome.tabs.remove(tabId); | |
| 98 setCompleted('injectScriptBlob'); | |
| 99 }); | |
| 100 } | |
| 101 } | |
| 102 ); | |
| 103 openTab(defaultUrl); | |
| 104 } | 76 } |
| 105 | 77 |
| 106 // Modifies the headers sent and received in an HTTP request using the | 78 // Modifies the headers sent and received in an HTTP request using the |
| 107 // webRequest API. | 79 // webRequest API. |
| 108 function doWebRequestModifications() { | 80 function doWebRequestModifications() { |
| 81 resetStatus(); | |
| 109 // Install a webRequest handler that will add an HTTP header to the outgoing | 82 // Install a webRequest handler that will add an HTTP header to the outgoing |
| 110 // request for the main page. | 83 // request for the main page. |
| 111 function doModifyHeaders(details) { | 84 function doModifyHeaders(details) { |
| 112 var response = {}; | 85 var response = {}; |
| 113 | 86 |
| 114 var headers = details.requestHeaders; | 87 var headers = details.requestHeaders; |
| 115 if (headers === undefined) { | 88 if (headers === undefined) { |
| 116 headers = []; | 89 headers = []; |
| 117 } | 90 } |
| 118 headers.push({'name': 'X-Test-Activity-Log-Send', | 91 headers.push({'name': 'X-Test-Activity-Log-Send', |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 142 {'urls': ['http://*/*'], 'types': ['main_frame']}, | 115 {'urls': ['http://*/*'], 'types': ['main_frame']}, |
| 143 ['blocking', 'responseHeaders']); | 116 ['blocking', 'responseHeaders']); |
| 144 | 117 |
| 145 // Open a tab, then close it when it has finished loading--this should give | 118 // Open a tab, then close it when it has finished loading--this should give |
| 146 // the webRequest handler a chance to run. | 119 // the webRequest handler a chance to run. |
| 147 chrome.tabs.onUpdated.addListener( | 120 chrome.tabs.onUpdated.addListener( |
| 148 function closeTab(tabId, changeInfo, tab) { | 121 function closeTab(tabId, changeInfo, tab) { |
| 149 if (changeInfo['status'] === 'complete' && | 122 if (changeInfo['status'] === 'complete' && |
| 150 tab.url.match(/google\.com/g)) { | 123 tab.url.match(/google\.com/g)) { |
| 151 chrome.webRequest.onBeforeSendHeaders.removeListener(doModifyHeaders); | 124 chrome.webRequest.onBeforeSendHeaders.removeListener(doModifyHeaders); |
| 152 // TODO(karenlees): you added this line in debugging, make sure it is | |
| 153 // really needed. | |
| 154 chrome.webRequest.onHeadersReceived.removeListener(doModifyHeaders); | 125 chrome.webRequest.onHeadersReceived.removeListener(doModifyHeaders); |
| 155 chrome.tabs.onUpdated.removeListener(closeTab); | 126 chrome.tabs.onUpdated.removeListener(closeTab); |
| 156 chrome.tabs.remove(tabId); | 127 chrome.tabs.remove(tabId); |
| 157 setCompleted('doWebRequestModifications'); | 128 appendCompleted('doWebRequestModifications'); |
| 158 } | 129 } |
| 159 } | 130 } |
| 160 ); | 131 ); |
| 161 openTab(defaultUrl); | |
| 162 } | |
| 163 | |
| 164 function getSetObjectProperties() { | |
| 165 chrome.tabs.onUpdated.addListener( | |
| 166 function getTabProperties(tabId, changeInfo, tab) { | |
| 167 if (changeInfo['status'] === 'complete' && | |
| 168 tab.url.match(/google\.com/g)) { | |
| 169 console.log(tab.id + ' ' + tab.index + ' ' + tab.url); | |
| 170 tab.index = 3333333333333333333; | |
| 171 chrome.tabs.onUpdated.removeListener(getTabProperties); | |
| 172 chrome.tabs.remove(tabId); | |
| 173 setCompleted('getSetObjectProperties'); | |
| 174 } | |
| 175 } | |
| 176 ); | |
| 177 openTab(defaultUrl); | |
| 178 } | |
| 179 | |
| 180 function callObjectMethod() { | |
| 181 var storageArea = chrome.storage.sync; | |
| 182 storageArea.clear(); | |
| 183 setCompleted('callObjectMethod()'); | |
| 184 } | |
| 185 | |
| 186 function sendMessageToCS() { | |
| 187 chrome.tabs.onUpdated.addListener( | |
| 188 function messageCS(tabId, changeInfo, tab) { | |
| 189 if (changeInfo['status'] === 'complete' && | |
| 190 tab.url.match(/google\.com/g)) { | |
| 191 chrome.tabs.sendMessage(tabId, 'hellooooo!'); | |
| 192 chrome.tabs.onUpdated.removeListener(messageCS); | |
| 193 chrome.tabs.remove(tabId); | |
| 194 setCompleted('sendMessageToCS'); | |
| 195 } | |
| 196 } | |
| 197 ); | |
| 198 openTab(defaultUrl); | 132 openTab(defaultUrl); |
| 199 } | 133 } |
| 200 | 134 |
| 201 function sendMessageToSelf() { | 135 function sendMessageToSelf() { |
| 136 resetStatus(); | |
| 202 try { | 137 try { |
| 203 chrome.runtime.sendMessage('hello hello'); | 138 chrome.runtime.sendMessage('hello hello'); |
| 204 setCompleted('sendMessageToSelf'); | 139 appendCompleted('sendMessageToSelf'); |
| 205 } catch (err) { | 140 } catch (err) { |
| 206 setError(err + ' in function: sendMessageToSelf'); | 141 setError(err + ' in function: sendMessageToSelf'); |
| 207 } | 142 } |
| 208 } | 143 } |
| 209 | 144 |
| 210 function sendMessageToOther() { | 145 function sendMessageToOther() { |
| 146 resetStatus(); | |
| 211 try { | 147 try { |
| 212 chrome.runtime.sendMessage('ocacnieaapoflmkebkeaidpgfngocapl', | 148 chrome.runtime.sendMessage('ocacnieaapoflmkebkeaidpgfngocapl', |
| 213 'knock knock', | 149 'knock knock', |
| 214 function response() { | 150 function response() { |
| 215 console.log("who's there?"); | 151 console.log("who's there?"); |
| 152 appendCompleted('sendMessageToOther'); | |
| 216 }); | 153 }); |
| 217 setCompleted('sendMessageToOther'); | |
| 218 } catch (err) { | 154 } catch (err) { |
| 219 setError(err + ' in function: sendMessageToOther'); | 155 setError(err + ' in function: sendMessageToOther'); |
| 220 } | 156 } |
| 221 } | 157 } |
| 222 | 158 |
| 223 function connectToOther() { | 159 function connectToOther() { |
| 160 resetStatus(); | |
| 224 try { | 161 try { |
| 225 chrome.runtime.connect('ocacnieaapoflmkebkeaidpgfngocapl'); | 162 chrome.runtime.connect('ocacnieaapoflmkebkeaidpgfngocapl'); |
| 226 setCompleted('connectToOther'); | 163 appendCompleted('connectToOther'); |
| 227 } catch (err) { | 164 } catch (err) { |
| 228 setError(err + ' in function:connectToOther'); | 165 setError(err + ' in function:connectToOther'); |
| 229 } | 166 } |
| 230 } | 167 } |
| 231 | 168 |
| 232 function tabIdTranslation() { | 169 function tabIdTranslation() { |
| 170 resetStatus(); | |
| 233 var tabIds = [-1, -1]; | 171 var tabIds = [-1, -1]; |
| 234 | 172 |
| 235 // Test the case of a single int | 173 // Test the case of a single int |
| 236 chrome.tabs.onUpdated.addListener( | 174 chrome.tabs.onUpdated.addListener( |
| 237 function testSingleInt(tabId, changeInfo, tab) { | 175 function testSingleInt(tabId, changeInfo, tab) { |
| 238 if (changeInfo['status'] === 'complete' && | 176 if (changeInfo['status'] === 'complete' && |
| 239 tab.url.match(/google\.com/g)) { | 177 tab.url.match(/google\.com/g)) { |
| 240 chrome.tabs.executeScript( | 178 chrome.tabs.executeScript( |
| 241 //tab.id, | 179 tabId, |
| 242 {'file': 'google_cs.js'}, | 180 {'file': 'google_cs.js'}, |
| 243 function() { | 181 function() { |
| 244 chrome.tabs.onUpdated.removeListener(testSingleInt); | 182 chrome.tabs.onUpdated.removeListener(testSingleInt); |
| 245 tabIds[0] = tabId; | 183 tabIds[0] = tabId; |
| 246 openTab('http://www.google.be'); | 184 openTab('http://www.google.be'); |
| 247 }); | 185 }); |
| 248 } | 186 } |
| 249 } | 187 } |
| 250 ); | 188 ); |
| 251 | 189 |
| 252 // Test the case of arrays | 190 // Test the case of arrays |
| 253 chrome.tabs.onUpdated.addListener( | 191 chrome.tabs.onUpdated.addListener( |
| 254 function testArray(tabId, changeInfo, tab) { | 192 function testArray(tabId, changeInfo, tab) { |
| 255 if (changeInfo['status'] === 'complete' && tab.url.match(/google\.be/g)) { | 193 if (changeInfo['status'] === 'complete' && tab.url.match(/google\.be/g)) { |
| 256 //chrome.tabs.move(tabId, {'index': -1}); | 194 chrome.tabs.move(tabId, {'index': -1}); |
| 257 tabIds[1] = tabId; | 195 tabIds[1] = tabId; |
| 258 chrome.tabs.onUpdated.removeListener(testArray); | 196 chrome.tabs.onUpdated.removeListener(testArray); |
| 259 chrome.tabs.remove(tabIds); | 197 chrome.tabs.remove(tabIds); |
| 260 setCompleted('tabIdTranslation'); | 198 appendCompleted('tabIdTranslation'); |
| 261 } | 199 } |
| 262 } | 200 } |
| 263 ); | 201 ); |
| 264 | 202 |
| 265 openTab(defaultUrl); | 203 openTab(defaultUrl); |
| 266 } | 204 } |
| 267 | 205 |
| 268 // DOM API TEST METHODS -- PUT YOUR TESTS BELOW HERE | 206 function executeApiCallsOnTabUpdated() { |
| 269 //////////////////////////////////////////////////////////////////////////////// | 207 resetStatus(); |
| 270 | |
| 271 // Does an XHR from this [privileged] context. | |
| 272 function doBackgroundXHR() { | |
| 273 var request = new XMLHttpRequest(); | |
| 274 request.open('POST', defaultUrl, false); | |
| 275 request.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); | |
| 276 try { | |
| 277 request.send(); | |
| 278 } catch (err) { | |
| 279 // doesn't matter if it works or not; should be recorded either way | |
| 280 } | |
| 281 setCompleted('doBackgroundXHR'); | |
| 282 } | |
| 283 | |
| 284 // Does an XHR from inside a content script. | |
| 285 function doContentScriptXHR() { | |
| 286 var code = 'var request = new XMLHttpRequest(); ' + | |
| 287 'request.open("POST", "http://www.cnn.com", false); ' + | |
| 288 'request.setRequestHeader("Content-type", ' + | |
| 289 ' "text/plain;charset=UTF-8"); ' + | |
| 290 'request.send(); ' + | |
| 291 'document.write("sent an XHR");'; | |
| 292 chrome.tabs.onUpdated.addListener( | 208 chrome.tabs.onUpdated.addListener( |
| 293 function callback(tabId, changeInfo, tab) { | 209 function callback(tabId, changeInfo, tab) { |
| 294 if (changeInfo['status'] === 'complete' && | 210 if (changeInfo['status'] === 'complete' && |
| 295 tab.url.match(/google\.com/g)) { | 211 tab.url.match(/google\.com/g)) { |
| 296 chrome.tabs.onUpdated.removeListener(callback); | 212 chrome.tabs.onUpdated.removeListener(callback); |
| 213 | |
| 214 // Send a message. | |
| 215 chrome.tabs.sendMessage(tabId, 'hellooooo!'); | |
| 216 appendCompleted('sendMessageToCS'); | |
| 217 | |
| 218 // Inject a content script | |
| 297 chrome.tabs.executeScript( | 219 chrome.tabs.executeScript( |
| 298 tab.id, | 220 tab.id, |
| 299 {'code': code}, | 221 {'file': 'google_cs.js'}, |
| 300 function() { | 222 function() { |
| 223 appendCompleted('injectContentScript'); | |
| 224 }); | |
| 225 | |
| 226 // Injects a blob of script into a page and cleans up the tab when | |
| 227 // finished. | |
| 228 chrome.tabs.executeScript( | |
| 229 tab.id, | |
| 230 {'code': 'document.write("g o o g l e");'}, | |
| 231 function() { | |
| 232 appendCompleted('injectScriptBlob'); | |
| 301 chrome.tabs.remove(tabId); | 233 chrome.tabs.remove(tabId); |
| 302 setCompleted('doContentScriptXHR'); | |
| 303 }); | 234 }); |
| 304 } | 235 } |
| 305 } | 236 } |
| 306 ); | |
| 307 openTab(defaultUrl); | |
| 308 } | |
| 309 | |
| 310 // Accesses the Location object from inside a content script. | |
| 311 function doLocationAccess() { | |
| 312 var code = 'window.location = "http://www.google.com/#foo"; ' + | |
| 313 'document.location = "http://www.google.com/#bar"; ' + | |
| 314 'var loc = window.location; ' + | |
| 315 'loc.assign("http://www.google.com/#fo"); ' + | |
| 316 'loc.replace("http://www.google.com/#bar");'; | |
| 317 chrome.tabs.onUpdated.addListener( | |
| 318 function callback(tabId, changeInfo, tab) { | |
| 319 if (changeInfo['status'] === 'complete' && | |
| 320 tab.url.match(/google\.com/g)) { | |
| 321 chrome.tabs.onUpdated.removeListener(callback); | |
| 322 chrome.tabs.executeScript( | |
| 323 tab.id, | |
| 324 {'code': code}, | |
| 325 function() { | |
| 326 chrome.tabs.remove(tabId); | |
| 327 setCompleted('doLoctionAccess'); | |
| 328 }); | |
| 329 } | |
| 330 } | |
| 331 ); | |
| 332 openTab(defaultUrl); | |
| 333 } | |
| 334 | |
| 335 // Mutates the DOM tree from inside a content script. | |
| 336 function doDOMMutation1() { | |
| 337 var code = 'var d1 = document.createElement("div"); ' + | |
| 338 'var d2 = document.createElement("div"); ' + | |
| 339 'document.body.appendChild(d1); ' + | |
| 340 'document.body.insertBefore(d2, d1); ' + | |
| 341 'document.body.replaceChild(d1, d2);'; | |
| 342 chrome.tabs.onUpdated.addListener( | |
| 343 function callback(tabId, changeInfo, tab) { | |
| 344 if (changeInfo['status'] === 'complete' && | |
| 345 tab.url.match(/google\.com/g)) { | |
| 346 chrome.tabs.onUpdated.removeListener(callback); | |
| 347 chrome.tabs.executeScript( | |
| 348 tab.id, | |
| 349 {'code': code}, | |
| 350 function() { | |
| 351 chrome.tabs.remove(tabId); | |
| 352 setCompleted('doDOMMutation1'); | |
| 353 }); | |
| 354 } | |
| 355 } | |
| 356 ); | |
| 357 openTab(defaultUrl); | |
| 358 } | |
| 359 | |
| 360 function doDOMMutation2() { | |
| 361 var code = 'document.write("Hello using document.write"); ' + | |
| 362 'document.writeln("Hello using document.writeln"); ' + | |
| 363 'document.body.innerHTML = "Hello using innerHTML";'; | |
| 364 chrome.tabs.onUpdated.addListener( | |
| 365 function callback(tabId, changeInfo, tab) { | |
| 366 if (changeInfo['status'] === 'complete' && | |
| 367 tab.url.match(/google\.com/g)) { | |
| 368 chrome.tabs.onUpdated.removeListener(callback); | |
| 369 chrome.tabs.executeScript( | |
| 370 tab.id, | |
| 371 {'code': code}, | |
| 372 function() { | |
| 373 chrome.tabs.remove(tabId); | |
| 374 setCompleted('doDOMMutation2'); | |
| 375 }); | |
| 376 } | |
| 377 } | |
| 378 ); | |
| 379 openTab(defaultUrl); | |
| 380 } | |
| 381 | |
| 382 // Accesses the HTML5 Navigator API from inside a content script. | |
| 383 function doNavigatorAPIAccess() { | |
| 384 var code = 'var geo = navigator.geolocation; ' + | |
| 385 'var successCallback = function(x) { }; ' + | |
| 386 'var errorCallback = function(x) { }; ' + | |
| 387 'geo.getCurrentPosition(successCallback, errorCallback); '; | |
| 388 'var id = geo.watchPosition(successCallback, errorCallback);'; | |
| 389 chrome.tabs.onUpdated.addListener( | |
| 390 function callback(tabId, changeInfo, tab) { | |
| 391 if (changeInfo['status'] === 'complete' && | |
| 392 tab.url.match(/google\.com/g)) { | |
| 393 chrome.tabs.onUpdated.removeListener(callback); | |
| 394 chrome.tabs.executeScript( | |
| 395 tab.id, | |
| 396 {'code': code}, | |
| 397 function() { | |
| 398 chrome.tabs.remove(tabId); | |
| 399 setCompleted('doNavigatorAPIAccess'); | |
| 400 }); | |
| 401 } | |
| 402 } | |
| 403 ); | |
| 404 openTab(defaultUrl); | |
| 405 } | |
| 406 | |
| 407 // Accesses the HTML5 WebStorage API from inside a content script. | |
| 408 function doWebStorageAPIAccess1() { | |
| 409 var code = 'var store = window.sessionStorage; ' + | |
| 410 'store.setItem("foo", 42); ' + | |
| 411 'var val = store.getItem("foo"); ' + | |
| 412 'store.removeItem("foo"); ' + | |
| 413 'store.clear();'; | |
| 414 chrome.tabs.onUpdated.addListener( | |
| 415 function callback(tabId, changeInfo, tab) { | |
| 416 if (changeInfo['status'] === 'complete' && | |
| 417 tab.url.match(/google\.com/g)) { | |
| 418 chrome.tabs.onUpdated.removeListener(callback); | |
| 419 chrome.tabs.executeScript( | |
| 420 tab.id, | |
| 421 {'code': code}, | |
| 422 function() { | |
| 423 chrome.tabs.remove(tabId); | |
| 424 setCompleted('doWebStorageAPIAccess1'); | |
| 425 }); | |
| 426 } | |
| 427 } | |
| 428 ); | |
| 429 openTab(defaultUrl); | |
| 430 } | |
| 431 | |
| 432 function doWebStorageAPIAccess2() { | |
| 433 var code = 'var store = window.sessionStorage; ' + | |
| 434 'store.setItem("foo", 42); ' + | |
| 435 'var val = store.getItem("foo"); ' + | |
| 436 'store.removeItem("foo"); ' + | |
| 437 'store.clear();'; | |
| 438 chrome.tabs.onUpdated.addListener( | |
| 439 function callback(tabId, changeInfo, tab) { | |
| 440 if (changeInfo['status'] === 'complete' && | |
| 441 tab.url.match(/google\.com/g)) { | |
| 442 chrome.tabs.onUpdated.removeListener(callback); | |
| 443 chrome.tabs.executeScript( | |
| 444 tab.id, | |
| 445 {'code': code}, | |
| 446 function() { | |
| 447 chrome.tabs.remove(tabId); | |
| 448 setCompleted('doWebStorageAPIAccess2'); | |
| 449 }); | |
| 450 } | |
| 451 } | |
| 452 ); | 237 ); |
| 453 openTab(defaultUrl); | 238 openTab(defaultUrl); |
| 454 } | 239 } |
| 455 | 240 |
| 456 // Accesses the HTML5 Notification API from inside a content script. | 241 |
| 457 function doNotificationAPIAccess() { | 242 // DOM API TEST METHODS -- PUT YOUR TESTS BELOW HERE |
| 458 var code = 'try {' + | 243 //////////////////////////////////////////////////////////////////////////////// |
| 459 ' webkitNotifications.createNotification("myIcon.png", ' + | 244 |
| 460 ' "myTitle", ' + | 245 // Does an XHR from this [privileged] context. |
| 461 ' "myContent");' + | 246 function doBackgroundXHR() { |
| 462 '} catch (e) {}'; | 247 resetStatus(); |
| 463 chrome.tabs.onUpdated.addListener( | 248 var request = new XMLHttpRequest(); |
| 464 function callback(tabId, changeInfo, tab) { | 249 request.open('POST', defaultUrl, false); |
| 465 if (changeInfo['status'] === 'complete' && | 250 request.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); |
| 466 tab.url.match(/google\.com/g)) { | 251 try { |
| 467 chrome.tabs.onUpdated.removeListener(callback); | 252 request.send(); |
| 468 chrome.tabs.executeScript( | 253 } catch (err) { |
| 469 tab.id, | 254 // doesn't matter if it works or not; should be recorded either way |
| 470 {'code': code}, | 255 } |
| 471 function() { | 256 appendCompleted('doBackgroundXHR'); |
| 472 chrome.tabs.remove(tabId); | |
| 473 setCompleted('doNotifcationAPIAccess'); | |
| 474 }); | |
| 475 } | |
| 476 } | |
| 477 ); | |
| 478 openTab(defaultUrl); | |
| 479 } | 257 } |
| 480 | 258 |
| 481 // Accesses the HTML5 ApplicationCache API from inside a content script. | 259 function executeDOMChangesOnTabUpdated() { |
| 482 function doApplicationCacheAPIAccess() { | 260 resetStatus(); |
| 483 var code = 'var appCache = window.applicationCache;'; | 261 code = ''; |
| 262 | |
| 263 // Accesses the Location object from inside a content script. | |
| 264 code += 'window.location = "http://www.google.com/#foo"; ' + | |
| 265 'document.location = "http://www.google.com/#bar"; ' + | |
| 266 'var loc = window.location; ' + | |
| 267 'loc.assign("http://www.google.com/#fo"); ' + | |
| 268 'loc.replace("http://www.google.com/#bar");'; | |
| 269 | |
| 270 // Mutates the DOM tree from inside a content script. | |
| 271 code += 'var d1 = document.createElement("div"); ' + | |
| 272 'var d2 = document.createElement("div"); ' + | |
| 273 'document.body.appendChild(d1); ' + | |
| 274 'document.body.insertBefore(d2, d1); ' + | |
| 275 'document.body.replaceChild(d1, d2);'; | |
| 276 | |
| 277 code += 'document.write("Hello using document.write"); ' + | |
| 278 'document.writeln("Hello using document.writeln"); ' + | |
| 279 'document.body.innerHTML = "Hello using innerHTML";'; | |
| 280 | |
| 281 // Accesses the HTML5 Navigator API from inside a content script. | |
| 282 code += 'var geo = navigator.geolocation; ' + | |
| 283 'var successCallback = function(x) { }; ' + | |
| 284 'var errorCallback = function(x) { }; ' + | |
| 285 'geo.getCurrentPosition(successCallback, errorCallback); ' + | |
| 286 'var id = geo.watchPosition(successCallback, errorCallback);'; | |
| 287 | |
| 288 // Accesses the HTML5 WebStorage API from inside a content script. | |
| 289 code += 'var store = window.sessionStorage; ' + | |
| 290 'store.setItem("foo", 42); ' + | |
| 291 'var val = store.getItem("foo"); ' + | |
| 292 'store.removeItem("foo"); ' + | |
| 293 'store.clear();'; | |
| 294 code += 'var store = window.sessionStorage; ' + | |
| 295 'store.setItem("foo", 42); ' + | |
| 296 'var val = store.getItem("foo"); ' + | |
| 297 'store.removeItem("foo"); ' + | |
| 298 'store.clear();'; | |
| 299 | |
| 300 // Accesses the HTML5 Notification API from inside a content script. | |
| 301 code += 'try {' + | |
| 302 ' webkitNotifications.createNotification("myIcon.png", ' + | |
| 303 ' "myTitle", ' + | |
| 304 ' "myContent");' + | |
| 305 '} catch (e) {}'; | |
| 306 | |
| 307 // Accesses the HTML5 ApplicationCache API from inside a content script. | |
| 308 code += 'var appCache = window.applicationCache;'; | |
| 309 | |
| 310 // Accesses the HTML5 WebDatabase API from inside a content script. | |
| 311 code += 'var db = openDatabase("testdb", "1.0", "test database", ' + | |
| 312 ' 1024 * 1024);'; | |
| 313 | |
| 314 // Accesses the HTML5 Canvas API from inside a content script. | |
| 315 code += 'var testCanvas = document.createElement("canvas"); ' + | |
| 316 'var testContext = testCanvas.getContext("2d");'; | |
| 317 | |
| 318 // Does an XHR from inside a content script. | |
| 319 code += 'var request = new XMLHttpRequest(); ' + | |
| 320 'request.open("POST", "http://www.cnn.com", false); ' + | |
| 321 'request.setRequestHeader("Content-type", ' + | |
| 322 ' "text/plain;charset=UTF-8"); ' + | |
| 323 'request.send(); ' + | |
| 324 'document.write("sent an XHR");'; | |
|
felt
2013/07/11 19:44:20
I don't think the document.write is needed here an
karenlees
2013/07/11 21:25:21
Done.
| |
| 325 | |
| 484 chrome.tabs.onUpdated.addListener( | 326 chrome.tabs.onUpdated.addListener( |
| 485 function callback(tabId, changeInfo, tab) { | 327 function callback(tabId, changeInfo, tab) { |
| 486 if (changeInfo['status'] === 'complete' && | 328 if (changeInfo['status'] === 'complete' && |
| 487 tab.url.match(/google\.com/g)) { | 329 tab.url.match(/google\.com/g)) { |
| 488 chrome.tabs.onUpdated.removeListener(callback); | 330 chrome.tabs.onUpdated.removeListener(callback); |
| 489 chrome.tabs.executeScript( | 331 chrome.tabs.executeScript( |
| 490 tab.id, | 332 tabId, {'code': code}, |
| 491 {'code': code}, | 333 function() { |
| 492 function() { | 334 chrome.tabs.remove(tabId); |
| 493 chrome.tabs.remove(tabId); | 335 appendCompleted('executeDOMChangesOnTabUpdated'); |
| 494 setCompleted('doApplictionCacheAPIAccess'); | 336 }); |
| 495 }); | |
| 496 } | 337 } |
| 497 } | 338 } |
| 498 ); | 339 ); |
| 499 openTab(defaultUrl); | |
| 500 } | |
| 501 | |
| 502 // Accesses the HTML5 WebDatabase API from inside a content script. | |
| 503 function doWebDatabaseAPIAccess() { | |
| 504 var code = 'var db = openDatabase("testdb", "1.0", "test database", ' + | |
| 505 ' 1024 * 1024);'; | |
| 506 chrome.tabs.onUpdated.addListener( | |
| 507 function callback(tabId, changeInfo, tab) { | |
| 508 if (changeInfo['status'] === 'complete' && | |
| 509 tab.url.match(/google\.com/g)) { | |
| 510 chrome.tabs.onUpdated.removeListener(callback); | |
| 511 chrome.tabs.executeScript( | |
| 512 tab.id, | |
| 513 {'code': code}, | |
| 514 function() { | |
| 515 chrome.tabs.remove(tabId); | |
| 516 setCompleted('doWebDatabaseAPIAccess'); | |
| 517 }); | |
| 518 } | |
| 519 } | |
| 520 ); | |
| 521 openTab(defaultUrl); | |
| 522 } | |
| 523 | |
| 524 // Accesses the HTML5 Canvas API from inside a content script. | |
| 525 function doCanvasAPIAccess() { | |
| 526 var code = 'var testCanvas = document.createElement("canvas"); ' + | |
| 527 'var testContext = testCanvas.getContext("2d");'; | |
| 528 chrome.tabs.onUpdated.addListener( | |
| 529 function callback(tabId, changeInfo, tab) { | |
| 530 if (changeInfo['status'] === 'complete' && | |
| 531 tab.url.match(/google\.com/g)) { | |
| 532 chrome.tabs.onUpdated.removeListener(callback); | |
| 533 chrome.tabs.executeScript( | |
| 534 tab.id, | |
| 535 {'code': code}, | |
| 536 function() { | |
| 537 chrome.tabs.remove(tabId); | |
| 538 setCompleted('doCanvasAPIAccess'); | |
| 539 }); | |
| 540 } | |
| 541 } | |
| 542 ); | |
| 543 openTab(defaultUrl); | 340 openTab(defaultUrl); |
| 544 } | 341 } |
| 545 | 342 |
| 546 // ADD TESTS CASES TO THE MAP HERE. | 343 // ADD TESTS CASES TO THE MAP HERE. |
| 547 var fnMap = {}; | 344 var fnMap = {}; |
| 548 fnMap['api_call'] = makeApiCall; | 345 fnMap['api_call'] = makeApiCall; |
| 549 fnMap['special_call'] = makeSpecialApiCalls; | 346 fnMap['special_call'] = makeSpecialApiCalls; |
| 550 fnMap['blocked_call'] = makeBlockedApiCall; | |
| 551 fnMap['inject_cs'] = injectContentScript; | |
| 552 fnMap['inject_blob'] = injectScriptBlob; | |
| 553 fnMap['webrequest'] = doWebRequestModifications; | |
| 554 fnMap['double'] = checkNoDoubleLogging; | 347 fnMap['double'] = checkNoDoubleLogging; |
| 555 fnMap['app_bindings'] = checkAppCalls; | 348 fnMap['app_bindings'] = checkAppCalls; |
| 556 fnMap['object_properties'] = getSetObjectProperties; | 349 fnMap['blocked_call'] = makeBlockedApiCall; |
| 557 fnMap['object_methods'] = callObjectMethod; | 350 fnMap['object_methods'] = callObjectMethod; |
| 558 fnMap['message_cs'] = sendMessageToCS; | |
| 559 fnMap['message_self'] = sendMessageToSelf; | 351 fnMap['message_self'] = sendMessageToSelf; |
| 560 fnMap['message_other'] = sendMessageToOther; | 352 fnMap['message_other'] = sendMessageToOther; |
| 561 fnMap['connect_other'] = connectToOther; | 353 fnMap['connect_other'] = connectToOther; |
| 354 fnMap['background_xhr'] = doBackgroundXHR; | |
| 355 fnMap['webrequest'] = doWebRequestModifications; | |
| 562 fnMap['tab_ids'] = tabIdTranslation; | 356 fnMap['tab_ids'] = tabIdTranslation; |
| 563 fnMap['background_xhr'] = doBackgroundXHR; | 357 fnMap['dom_tab_updated'] = executeDOMChangesOnTabUpdated; |
| 564 fnMap['cs_xhr'] = doContentScriptXHR; | 358 fnMap['api_tab_updated'] = executeApiCallsOnTabUpdated; |
| 565 fnMap['location_access'] = doLocationAccess; | |
| 566 fnMap['dom_mutation1'] = doDOMMutation1; | |
| 567 fnMap['dom_mutation2'] = doDOMMutation2; | |
| 568 fnMap['navigator_access'] = doNavigatorAPIAccess; | |
| 569 fnMap['web_storage_access1'] = doWebStorageAPIAccess1; | |
| 570 fnMap['web_storage_access2'] = doWebStorageAPIAccess2; | |
| 571 fnMap['notification_access'] = doNotificationAPIAccess; | |
| 572 fnMap['application_cache_access'] = doApplicationCacheAPIAccess; | |
| 573 fnMap['web_database_access'] = doWebDatabaseAPIAccess; | |
| 574 fnMap['canvas_access'] = doCanvasAPIAccess; | |
| 575 | 359 |
| 576 // Setup function mapping for the automated tests. | 360 // Setup function mapping for the automated tests. |
| 577 try { | 361 try { |
| 578 chrome.runtime.onMessageExternal.addListener( | 362 chrome.runtime.onMessageExternal.addListener( |
| 579 function(message, sender, response) { | 363 function(message, sender, response) { |
| 580 useIncognito = false; | 364 useIncognito = false; |
| 581 if (message.match(/_incognito$/)) { | 365 if (message.match(/_incognito$/)) { |
| 582 // Enable incognito windows for this test, then strip the _incognito | 366 // Enable incognito windows for this test, then strip the _incognito |
| 583 // suffix for the lookup below. | 367 // suffix for the lookup below. |
| 584 useIncognito = true; | 368 useIncognito = true; |
| 585 message = message.slice(0, -10); | 369 message = message.slice(0, -10); |
| 586 } | 370 } |
| 587 if (fnMap.hasOwnProperty(message)) { | 371 if (fnMap.hasOwnProperty(message)) { |
| 588 fnMap[message](); | 372 fnMap[message](); |
| 589 } else { | 373 } else { |
| 590 console.log('UNKNOWN METHOD: ' + message); | 374 console.log('UNKNOWN METHOD: ' + message); |
| 591 } | 375 } |
| 592 } | 376 } |
| 593 ); | 377 ); |
| 594 } catch (err) { | 378 } catch (err) { |
| 595 console.log('Error while adding listeners: ' + err); | 379 console.log('Error while adding listeners: ' + err); |
| 596 } | 380 } |
| 597 | 381 |
| 598 // Convenience functions for the manual run mode. | 382 // Convenience functions for the manual run mode. |
| 599 function $(o) { | 383 function $(o) { |
| 600 return document.getElementById(o); | 384 return document.getElementById(o); |
| 601 } | 385 } |
| 602 | 386 |
| 603 var completed = 0; | 387 var completed = 0; |
| 604 function setCompleted(str) { | 388 function resetStatus(str) { |
| 605 completed++; | 389 completed = 0; |
| 606 if ($('status') != null) { | 390 if ($('status') != null) { |
| 607 $('status').innerText = 'Completed ' + str; | 391 $('status').innerText = ''; |
| 608 } | 392 } |
| 609 console.log('[SUCCESS] ' + str); | |
| 610 } | 393 } |
| 611 | 394 |
| 612 function setError(str) { | 395 function appendCompleted(str) { |
| 613 $('status').innerText = 'Error: ' + str; | 396 if ($('status') != null) { |
| 397 if (completed > 0) { | |
| 398 $('status').innerText += ', ' + str; | |
| 399 } else { | |
| 400 $('status').innerText = 'Completed: ' + str; | |
| 401 } | |
| 402 } | |
| 403 completed += 1; | |
| 404 console.log('Completed ' + str); | |
| 405 } | |
| 406 | |
| 407 function appendError(str) { | |
| 408 if ($('status') != null) { | |
| 409 $('status').innerText += 'Error: ' + str; | |
| 410 } | |
| 614 } | 411 } |
| 615 | 412 |
| 616 // Set up the event listeners for use in manual run mode. | 413 // Set up the event listeners for use in manual run mode. |
| 617 function setupEvents() { | 414 function setupEvents() { |
| 618 for (var key in fnMap) { | 415 for (var key in fnMap) { |
| 619 if (fnMap.hasOwnProperty(key) && key != '' && $(key) != null) { | 416 if (fnMap.hasOwnProperty(key) && key != '' && $(key) != null) { |
| 620 $(key).addEventListener('click', fnMap[key]); | 417 $(key).addEventListener('click', fnMap[key]); |
| 621 } | 418 } |
| 622 } | 419 } |
| 623 $('incognito_checkbox').addEventListener( | 420 if ($('incognito_checkbox' != null)) { |
| 624 'click', | 421 $('incognito_checkbox').addEventListener( |
| 625 function() { useIncognito = $('incognito_checkbox').checked; }); | 422 'click', |
| 626 setCompleted('setup events'); | 423 function() { useIncognito = $('incognito_checkbox').checked; }); |
| 424 } | |
| 627 completed = 0; | 425 completed = 0; |
| 426 appendCompleted('setup events'); | |
| 628 } | 427 } |
| 629 document.addEventListener('DOMContentLoaded', setupEvents); | 428 document.addEventListener('DOMContentLoaded', setupEvents); |
| OLD | NEW |