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