| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // Tests for browser_tests --gtest_filter=ExtensionApiTest.Messaging | |
| 6 | |
| 7 var assertEq = chrome.test.assertEq; | |
| 8 var assertTrue = chrome.test.assertTrue; | |
| 9 var listenOnce = chrome.test.listenOnce; | 5 var listenOnce = chrome.test.listenOnce; |
| 10 var listenForever = chrome.test.listenForever; | 6 var listenForever = chrome.test.listenForever; |
| 11 | 7 |
| 12 JSON.parse = function() { | 8 JSON.parse = function() { |
| 13 return "JSON.parse clobbered by extension."; | 9 return "JSON.parse clobbered by extension."; |
| 14 }; | 10 }; |
| 15 | 11 |
| 16 JSON.stringify = function() { | 12 JSON.stringify = function() { |
| 17 return "JSON.stringify clobbered by extension."; | 13 return "JSON.stringify clobbered by extension."; |
| 18 }; | 14 }; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 port.disconnect(); | 53 port.disconnect(); |
| 58 }); | 54 }); |
| 59 }, | 55 }, |
| 60 | 56 |
| 61 // Tests that port name is sent & received correctly. | 57 // Tests that port name is sent & received correctly. |
| 62 function portName() { | 58 function portName() { |
| 63 var portName = "lemonjello"; | 59 var portName = "lemonjello"; |
| 64 var port = chrome.tabs.connect(testTab.id, {name: portName}); | 60 var port = chrome.tabs.connect(testTab.id, {name: portName}); |
| 65 port.postMessage({testPortName: true}); | 61 port.postMessage({testPortName: true}); |
| 66 listenOnce(port.onMessage, function(msg) { | 62 listenOnce(port.onMessage, function(msg) { |
| 67 assertEq(msg.portName, portName); | 63 chrome.test.assertEq(msg.portName, portName); |
| 68 port.disconnect(); | 64 port.disconnect(); |
| 69 }); | 65 }); |
| 70 }, | 66 }, |
| 71 | 67 |
| 72 // Tests that postMessage from the tab and its response works. | 68 // Tests that postMessage from the tab and its response works. |
| 73 function postMessageFromTab() { | 69 function postMessageFromTab() { |
| 74 listenOnce(chrome.runtime.onConnect, function(port) { | 70 listenOnce(chrome.runtime.onConnect, function(port) { |
| 75 assertEq({ | 71 chrome.test.assertEq({ |
| 76 tab: testTab, | 72 tab: testTab, |
| 77 frameId: 0, // Main frame | 73 frameId: 0, // Main frame |
| 78 url: testTab.url, | 74 url: testTab.url, |
| 79 id: chrome.runtime.id | 75 id: chrome.runtime.id |
| 80 }, port.sender); | 76 }, port.sender); |
| 81 listenOnce(port.onMessage, function(msg) { | 77 listenOnce(port.onMessage, function(msg) { |
| 82 assertTrue(msg.testPostMessageFromTab); | 78 chrome.test.assertTrue(msg.testPostMessageFromTab); |
| 83 port.postMessage({success: true, portName: port.name}); | 79 port.postMessage({success: true, portName: port.name}); |
| 84 chrome.test.log("postMessageFromTab: got message from tab"); | 80 chrome.test.log("postMessageFromTab: got message from tab"); |
| 85 }); | 81 }); |
| 86 }); | 82 }); |
| 87 | 83 |
| 88 var port = chrome.tabs.connect(testTab.id); | 84 var port = chrome.tabs.connect(testTab.id); |
| 89 port.postMessage({testPostMessageFromTab: true}); | 85 port.postMessage({testPostMessageFromTab: true}); |
| 90 chrome.test.log("postMessageFromTab: sent first message to tab"); | 86 chrome.test.log("postMessageFromTab: sent first message to tab"); |
| 91 listenOnce(port.onMessage, function(msg) { | 87 listenOnce(port.onMessage, function(msg) { |
| 92 port.disconnect(); | 88 port.disconnect(); |
| 93 }); | 89 }); |
| 94 }, | 90 }, |
| 95 | 91 |
| 96 // Tests receiving a request from a content script and responding. | 92 // Tests receiving a request from a content script and responding. |
| 97 function sendMessageFromTab() { | 93 function sendMessageFromTab() { |
| 98 var doneListening = listenForever( | 94 var doneListening = listenForever( |
| 99 chrome.runtime.onMessage, | 95 chrome.runtime.onMessage, |
| 100 function(request, sender, sendResponse) { | 96 function(request, sender, sendResponse) { |
| 101 assertEq({ | 97 chrome.test.assertEq({ |
| 102 tab: testTab, | 98 tab: testTab, |
| 103 frameId: 0, // Main frame | 99 frameId: 0, // Main frame |
| 104 url: testTab.url, | 100 url: testTab.url, |
| 105 id: chrome.runtime.id | 101 id: chrome.runtime.id |
| 106 }, sender); | 102 }, sender); |
| 107 if (request.step == 1) { | 103 if (request.step == 1) { |
| 108 // Step 1: Page should send another request for step 2. | 104 // Step 1: Page should send another request for step 2. |
| 109 chrome.test.log("sendMessageFromTab: got step 1"); | 105 chrome.test.log("sendMessageFromTab: got step 1"); |
| 110 sendResponse({nextStep: true}); | 106 sendResponse({nextStep: true}); |
| 111 } else { | 107 } else { |
| 112 // Step 2. | 108 // Step 2. |
| 113 assertEq(2, request.step); | 109 chrome.test.assertEq(request.step, 2); |
| 114 sendResponse(); | 110 sendResponse(); |
| 115 doneListening(); | 111 doneListening(); |
| 116 } | 112 } |
| 117 }); | 113 }); |
| 118 | 114 |
| 119 var port = chrome.tabs.connect(testTab.id); | 115 var port = chrome.tabs.connect(testTab.id); |
| 120 port.postMessage({testSendMessageFromTab: true}); | 116 port.postMessage({testSendMessageFromTab: true}); |
| 121 port.disconnect(); | 117 port.disconnect(); |
| 122 chrome.test.log("sendMessageFromTab: sent first message to tab"); | 118 chrome.test.log("sendMessageFromTab: sent first message to tab"); |
| 123 }, | 119 }, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 148 return frame.frameId > 0; // Exclude main frame. | 144 return frame.frameId > 0; // Exclude main frame. |
| 149 }).map(function(frame) { | 145 }).map(function(frame) { |
| 150 return { | 146 return { |
| 151 tab: testTab, | 147 tab: testTab, |
| 152 frameId: frame.frameId, | 148 frameId: frame.frameId, |
| 153 url: frame.url, | 149 url: frame.url, |
| 154 id: chrome.runtime.id | 150 id: chrome.runtime.id |
| 155 }; | 151 }; |
| 156 }).sort(sortByFrameId); | 152 }).sort(sortByFrameId); |
| 157 senders.sort(sortByFrameId); | 153 senders.sort(sortByFrameId); |
| 158 assertEq(expectedSenders, senders); | 154 chrome.test.assertEq(expectedSenders, senders); |
| 159 doneListening(); | 155 doneListening(); |
| 160 }); | 156 }); |
| 161 } | 157 } |
| 162 } | 158 } |
| 163 ); | 159 ); |
| 164 | 160 |
| 165 var port = chrome.tabs.connect(testTab.id); | 161 var port = chrome.tabs.connect(testTab.id); |
| 166 port.postMessage({testSendMessageFromFrame: true}); | 162 port.postMessage({testSendMessageFromFrame: true}); |
| 167 port.disconnect(); | 163 port.disconnect(); |
| 168 chrome.test.log("sendMessageFromFrameInTab: send 1st message to tab"); | 164 chrome.test.log("sendMessageFromFrameInTab: send 1st message to tab"); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 180 | 176 |
| 181 // connect with a positive frameId should trigger onConnect in that specific | 177 // connect with a positive frameId should trigger onConnect in that specific |
| 182 // frame only. | 178 // frame only. |
| 183 function sendMessageToFrameInTab() { | 179 function sendMessageToFrameInTab() { |
| 184 chrome.webNavigation.getAllFrames({ | 180 chrome.webNavigation.getAllFrames({ |
| 185 tabId: testTab.id | 181 tabId: testTab.id |
| 186 }, function(details) { | 182 }, function(details) { |
| 187 var frames = details.filter(function(frame) { | 183 var frames = details.filter(function(frame) { |
| 188 return /\?testSendMessageFromFrame1$/.test(frame.url); | 184 return /\?testSendMessageFromFrame1$/.test(frame.url); |
| 189 }); | 185 }); |
| 190 assertEq(1, frames.length); | 186 chrome.test.assertEq(1, frames.length); |
| 191 connectToTabWithFrameId(frames[0].frameId, ['from_1']); | 187 connectToTabWithFrameId(frames[0].frameId, ['from_1']); |
| 192 }); | 188 }); |
| 193 }, | 189 }, |
| 194 | 190 |
| 195 // sendMessage with an invalid frameId should fail. | 191 // sendMessage with an invalid frameId should fail. |
| 196 function sendMessageToInvalidFrameInTab() { | 192 function sendMessageToInvalidFrameInTab() { |
| 197 chrome.tabs.sendMessage(testTab.id, {}, { | 193 chrome.tabs.sendMessage(testTab.id, {}, { |
| 198 frameId: 999999999 // Some (hopefully) invalid frameId. | 194 frameId: 999999999 // Some (hopefully) invalid frameId. |
| 199 }, chrome.test.callbackFail( | 195 }, chrome.test.callbackFail( |
| 200 'Could not establish connection. Receiving end does not exist.')); | 196 'Could not establish connection. Receiving end does not exist.')); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 230 | 226 |
| 231 var port = chrome.tabs.connect(testTab.id); | 227 var port = chrome.tabs.connect(testTab.id); |
| 232 port.postMessage({testConnectFromTabError: true}); | 228 port.postMessage({testConnectFromTabError: true}); |
| 233 port.disconnect(); | 229 port.disconnect(); |
| 234 chrome.test.log("testConnectFromTabError: sent 1st message to tab"); | 230 chrome.test.log("testConnectFromTabError: sent 1st message to tab"); |
| 235 }, | 231 }, |
| 236 | 232 |
| 237 // Tests sending a request to a tab and receiving a response. | 233 // Tests sending a request to a tab and receiving a response. |
| 238 function sendMessage() { | 234 function sendMessage() { |
| 239 chrome.tabs.sendMessage(testTab.id, {step2: 1}, function(response) { | 235 chrome.tabs.sendMessage(testTab.id, {step2: 1}, function(response) { |
| 240 assertTrue(response.success); | 236 chrome.test.assertTrue(response.success); |
| 241 chrome.test.succeed(); | 237 chrome.test.succeed(); |
| 242 }); | 238 }); |
| 243 }, | 239 }, |
| 244 | 240 |
| 245 // Tests that we get the disconnect event when the tab disconnect. | 241 // Tests that we get the disconnect event when the tab disconnect. |
| 246 function disconnect() { | 242 function disconnect() { |
| 247 var port = chrome.tabs.connect(testTab.id); | 243 var port = chrome.tabs.connect(testTab.id); |
| 248 port.postMessage({testDisconnect: true}); | 244 port.postMessage({testDisconnect: true}); |
| 249 listenOnce(port.onDisconnect, function() {}); | 245 listenOnce(port.onDisconnect, function() {}); |
| 250 }, | 246 }, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 274 }, | 270 }, |
| 275 | 271 |
| 276 // Tests that the sendRequest API is disabled. | 272 // Tests that the sendRequest API is disabled. |
| 277 function sendRequest() { | 273 function sendRequest() { |
| 278 var error; | 274 var error; |
| 279 try { | 275 try { |
| 280 chrome.extension.sendRequest("hi"); | 276 chrome.extension.sendRequest("hi"); |
| 281 } catch(e) { | 277 } catch(e) { |
| 282 error = e; | 278 error = e; |
| 283 } | 279 } |
| 284 assertTrue(error != undefined); | 280 chrome.test.assertTrue(error != undefined); |
| 285 | 281 |
| 286 error = undefined; | 282 error = undefined; |
| 287 try { | 283 try { |
| 288 chrome.extension.onRequest.addListener(function() {}); | 284 chrome.extension.onRequest.addListener(function() {}); |
| 289 } catch(e) { | 285 } catch(e) { |
| 290 error = e; | 286 error = e; |
| 291 } | 287 } |
| 292 assertTrue(error != undefined); | 288 chrome.test.assertTrue(error != undefined); |
| 293 | 289 |
| 294 chrome.test.succeed(); | 290 chrome.test.succeed(); |
| 295 }, | 291 }, |
| 296 | 292 |
| 297 // Tests that chrome.runtime.sendMessage is *not* delivered to the current | 293 // Tests that chrome.runtime.sendMessage is *not* delivered to the current |
| 298 // context, consistent behavior with chrome.runtime.connect() and web APIs | 294 // context, consistent behavior with chrome.runtime.connect() and web APIs |
| 299 // like localStorage changed listeners. | 295 // like localStorage changed listeners. |
| 300 // Regression test for http://crbug.com/479951. | 296 // Regression test for http://crbug.com/479951. |
| 301 function sendMessageToCurrentContextFails() { | 297 function sendMessageToCurrentContextFails() { |
| 302 var stopFailing = failWhileListening(chrome.runtime.onMessage); | 298 var stopFailing = failWhileListening(chrome.runtime.onMessage); |
| 303 chrome.runtime.sendMessage('ping', chrome.test.callbackFail( | 299 chrome.runtime.sendMessage('ping', chrome.test.callbackFail( |
| 304 'Could not establish connection. Receiving end does not exist.', | 300 'Could not establish connection. Receiving end does not exist.', |
| 305 function() { | 301 function() { |
| 306 stopFailing(); | 302 stopFailing(); |
| 307 chrome.test.succeed(); | 303 chrome.test.succeed(); |
| 308 } | 304 } |
| 309 )); | 305 )); |
| 310 }, | 306 }, |
| 311 | 307 |
| 312 // Like sendMessageToCurrentContextFails, but with the sendMessage call not | 308 // Like sendMessageToCurrentContextFails, but with the sendMessage call not |
| 313 // given a callback. This requires a more creative test setup because there | 309 // given a callback. This requires a more creative test setup because there |
| 314 // is no callback to signal when it's supposed to have been done. | 310 // is no callback to signal when it's supposed to have been done. |
| 315 // Regression test for http://crbug.com/479951. | 311 // Regression test for http://crbug.com/479951. |
| 316 function sendMessageToCurrentTextWithoutCallbackFails() { | 312 // |
| 317 // Make the iframe - in a different context - watch for the message | 313 // NOTE(kalman): This test is correct. However, the patch which fixes it |
| 318 // event. It *should* get it, while the current context's one doesn't. | 314 // (see bug) was reverted, and I don't plan on resubmitting, so instead |
| 319 var iframe = document.createElement('iframe'); | 315 // I'll comment out this test, and leave it here for the record. |
| 320 iframe.src = chrome.runtime.getURL('blank_iframe.html'); | 316 // |
| 321 document.body.appendChild(iframe); | 317 // function sendMessageToCurrentTextWithoutCallbackFails() { |
| 318 // // Make the iframe - in a different context - watch for the message |
| 319 // // event. It *should* get it, while the current context's one doesn't. |
| 320 // var iframe = document.createElement('iframe'); |
| 321 // iframe.src = chrome.runtime.getURL('blank_iframe.html'); |
| 322 // document.body.appendChild(iframe); |
| 322 | 323 |
| 323 var stopFailing = failWhileListening(chrome.runtime.onMessage); | 324 // var stopFailing = failWhileListening(chrome.runtime.onMessage); |
| 324 listenOnce( | 325 // chrome.test.listenOnce( |
| 325 iframe.contentWindow.chrome.runtime.onMessage, | 326 // iframe.contentWindow.chrome.runtime.onMessage, |
| 326 function(msg, sender) { | 327 // function(msg, sender) { |
| 327 assertEq('ping', msg); | 328 // chrome.test.assertEq('ping', msg); |
| 328 assertEq(chrome.runtime.id, sender.id); | 329 // chrome.test.assertEq(chrome.runtime.id, sender.id); |
| 329 assertEq(location.href, sender.url); | 330 // chrome.test.assertEq(location.href, sender.url); |
| 330 setTimeout(function() { | 331 // setTimeout(function() { |
| 331 stopFailing(); | 332 // stopFailing(); |
| 332 chrome.test.succeed(); | 333 // chrome.test.succeed(); |
| 333 }, 0); | 334 // }, 0); |
| 334 } | 335 // } |
| 335 ); | 336 // ); |
| 337 // |
| 338 // chrome.runtime.sendMessage('ping'); |
| 339 // }, |
| 336 | 340 |
| 337 chrome.runtime.sendMessage('ping'); | |
| 338 }, | |
| 339 | |
| 340 // Tests that destroying a port clears its onMessage and onDisconnect | |
| 341 // listeners. | |
| 342 function disconnectingPortRemovesEventListeners() { | |
| 343 var port = chrome.runtime.connect(chrome.runtime.id); | |
| 344 assertTrue(!port.onMessage.hasListeners() && | |
| 345 !port.onDisconnect.hasListeners()); | |
| 346 port.onMessage.addListener(function() {}); | |
| 347 port.onDisconnect.addListener(function() {}); | |
| 348 assertTrue(port.onMessage.hasListeners() && | |
| 349 port.onDisconnect.hasListeners()); | |
| 350 port.disconnect(); | |
| 351 assertTrue(!port.onMessage.hasListeners() && | |
| 352 !port.onDisconnect.hasListeners()); | |
| 353 chrome.test.succeed(); | |
| 354 } | |
| 355 ]); | 341 ]); |
| 356 }); | 342 }); |
| 357 | 343 |
| 358 function connectToTabWithFrameId(frameId, expectedMessages) { | 344 function connectToTabWithFrameId(frameId, expectedMessages) { |
| 359 var port = chrome.tabs.connect(testTab.id, { | 345 var port = chrome.tabs.connect(testTab.id, { |
| 360 frameId: frameId | 346 frameId: frameId |
| 361 }); | 347 }); |
| 362 var messages = []; | 348 var messages = []; |
| 363 var isDone = false; | 349 var isDone = false; |
| 364 listenForever(port.onMessage, function(message) { | 350 listenForever(port.onMessage, function(message) { |
| 365 if (isDone) // Should not get any messages after completing the test. | 351 if (isDone) // Should not get any messages after completing the test. |
| 366 chrome.test.fail( | 352 chrome.test.fail( |
| 367 'Unexpected message from port to frame ' + frameId + ': ' + message); | 353 'Unexpected message from port to frame ' + frameId + ': ' + message); |
| 368 | 354 |
| 369 messages.push(message); | 355 messages.push(message); |
| 370 isDone = messages.length == expectedMessages.length; | 356 isDone = messages.length == expectedMessages.length; |
| 371 if (isDone) { | 357 if (isDone) { |
| 372 assertEq(expectedMessages.sort(), messages.sort()); | 358 chrome.test.assertEq(expectedMessages.sort(), messages.sort()); |
| 373 chrome.test.succeed(); | 359 chrome.test.succeed(); |
| 374 } | 360 } |
| 375 }); | 361 }); |
| 376 listenOnce(port.onDisconnect, function() { | 362 listenOnce(port.onDisconnect, function() { |
| 377 if (!isDone) // The event should never be triggered when we expect messages. | 363 if (!isDone) // The event should never be triggered when we expect messages. |
| 378 chrome.test.fail('Unexpected disconnect from port to frame ' + frameId); | 364 chrome.test.fail('Unexpected disconnect from port to frame ' + frameId); |
| 379 }); | 365 }); |
| 380 port.postMessage({testSendMessageToFrame: true}); | 366 port.postMessage({testSendMessageToFrame: true}); |
| 381 chrome.test.log('connectToTabWithFrameId: port to frame ' + frameId); | 367 chrome.test.log('connectToTabWithFrameId: port to frame ' + frameId); |
| 382 } | 368 } |
| 383 | 369 |
| 384 // Listens to |event| and returns a callback to run to stop listening. While | 370 // Listens to |event| and returns a callback to run to stop listening. While |
| 385 // listening, if |event| is fired, calls chrome.test.fail(). | 371 // listening, if |event| is fired, calls chrome.test.fail(). |
| 386 function failWhileListening(event, doneListening) { | 372 function failWhileListening(event, doneListening) { |
| 387 var failListener = function() { | 373 var failListener = function() { |
| 388 chrome.test.fail('Event listener ran, but it shouldn\'t have. ' + | 374 chrome.test.fail('Event listener ran, but it shouldn\'t have. ' + |
| 389 'It\'s possible that may be triggered flakily, but this ' + | 375 'It\'s possible that may be triggered flakily, but this ' + |
| 390 'really is a real failure, not flaky sadness. Promise!'); | 376 'really is a real failure, not flaky sadness. Promise!'); |
| 391 }; | 377 }; |
| 392 var release = chrome.test.callbackAdded(); | 378 var release = chrome.test.callbackAdded(); |
| 393 event.addListener(failListener); | 379 event.addListener(failListener); |
| 394 return function() { | 380 return function() { |
| 395 event.removeListener(failListener); | 381 event.removeListener(failListener); |
| 396 release(); | 382 release(); |
| 397 }; | 383 }; |
| 398 } | 384 } |
| OLD | NEW |