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