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 |