| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 // A simple helper to keep track of how many responses are received, and fail | 5 // A simple helper to keep track of how many responses are received, and fail |
| 6 // if it receives a "fail" message. It's unfortunate that these are never | 6 // if it receives a "fail" message. It's unfortunate that these are never |
| 7 // cleaned up, but, realistically, doesn't matter. | 7 // cleaned up, but, realistically, doesn't matter. |
| 8 function ResponseCounter() { | 8 function ResponseCounter() { |
| 9 this.responsesReceived = 0; | 9 this.responsesReceived = 0; |
| 10 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { | 10 this.expectedResponses = -1; |
| 11 var listenerFunction = function(request, sender, sendResponse) { |
| 11 if (request == 'fail') { | 12 if (request == 'fail') { |
| 12 chrome.test.fail(); | 13 chrome.test.fail('Received bad message'); |
| 13 } else { | 14 } else { |
| 14 chrome.test.assertEq('complete', request); | 15 chrome.test.assertEq('complete', request); |
| 15 ++this.responsesReceived; | 16 ++this.responsesReceived; |
| 17 chrome.test.assertTrue(this.responsesReceived <= this.expectedResponses); |
| 18 if (this.responsesReceived == this.expectedResponses && |
| 19 this.doneCallback) { |
| 20 this.removeListener(); |
| 21 this.doneCallback(); |
| 22 } |
| 16 } | 23 } |
| 17 }.bind(this)); | 24 }.bind(this); |
| 25 this.removeListener = function() { |
| 26 chrome.runtime.onMessage.removeListener(listenerFunction); |
| 27 } |
| 28 chrome.runtime.onMessage.addListener(listenerFunction); |
| 18 } | 29 } |
| 19 | 30 |
| 20 var waitForCommittedAndRun = function(functionToRun, numCommits, url) { | 31 var waitForCommittedAndRun = function(functionToRun, numCommits, url) { |
| 21 var committedCount = 0; | 32 var committedCount = 0; |
| 22 var counter = new ResponseCounter(); // Every test gets a counter. | 33 var counter = new ResponseCounter(); // Every test gets a counter. |
| 23 var onCommitted = function(details) { | 34 var onCommitted = function(details) { |
| 24 if (++committedCount == numCommits) { | 35 if (++committedCount == numCommits) { |
| 25 functionToRun(counter, details.tabId); | 36 functionToRun(counter, details.tabId); |
| 26 chrome.webNavigation.onCommitted.removeListener(onCommitted); | 37 chrome.webNavigation.onCommitted.removeListener(onCommitted); |
| 27 } | 38 } |
| 28 }; | 39 }; |
| 29 chrome.webNavigation.onCommitted.addListener(onCommitted); | 40 chrome.webNavigation.onCommitted.addListener(onCommitted); |
| 30 chrome.tabs.create({url: url}); | 41 chrome.tabs.create({url: url}); |
| 31 }; | 42 }; |
| 32 | 43 |
| 33 chrome.test.getConfig(function(config) { | 44 chrome.test.getConfig(function(config) { |
| 34 var url = 'http://a.com:' + config.testServer.port + | 45 var url = 'http://a.com:' + config.testServer.port + |
| 35 '/extensions/api_test/executescript/removed_frames/outer.html'; | 46 '/extensions/api_test/executescript/removed_frames/outer.html'; |
| 36 // Regression tests for crbug.com/500574. | 47 // Regression tests for crbug.com/500574. |
| 37 chrome.test.runTests([ | 48 chrome.test.runTests([ |
| 38 function() { | 49 function testInjectAndDeleteIframeFromMainFrame() { |
| 39 waitForCommittedAndRun(injectAndDeleteIframeFromMainFrame, 2, url); | 50 waitForCommittedAndRun(injectAndDeleteIframeFromMainFrame, 2, url); |
| 40 }, | 51 }, |
| 41 function() { | 52 function testInjectAndDeleteIframeFromIframe() { |
| 42 waitForCommittedAndRun(injectAndDeleteIframeFromIframe, 2, url); | 53 waitForCommittedAndRun(injectAndDeleteIframeFromIframe, 2, url); |
| 43 } | 54 } |
| 44 ]); | 55 ]); |
| 45 }); | 56 }); |
| 46 | 57 |
| 47 function injectAndDeleteIframeFromMainFrame(counter, tabId) { | 58 function injectAndDeleteIframeFromMainFrame(counter, tabId) { |
| 48 // Inject code into each frame. If it's the parent frame, it removes the child | 59 // Inject code into each frame. If it's the parent frame, it removes the child |
| 49 // frame from the DOM (invalidating it). The child frame's code shouldn't | 60 // frame from the DOM (invalidating it). The child frame's code shouldn't |
| 50 // finish executing, since it's been removed. | 61 // finish executing, since it's been removed. |
| 62 counter.expectedResponses = 1; |
| 63 counter.doneCallback = function() { |
| 64 chrome.test.assertEq(1, counter.responsesReceived); |
| 65 chrome.test.succeed(); |
| 66 }; |
| 51 var injectFrameCode = [ | 67 var injectFrameCode = [ |
| 52 'if (window === window.top) {', | 68 'if (window === window.top) {', |
| 53 ' iframe = document.getElementsByTagName("iframe")[0];', | 69 ' iframe = document.getElementsByTagName("iframe")[0];', |
| 54 ' iframe.parentElement.removeChild(iframe);', | 70 ' iframe.parentElement.removeChild(iframe);', |
| 55 ' chrome.runtime.sendMessage("complete");', | 71 ' chrome.runtime.sendMessage("complete");', |
| 56 '}' | 72 '}' |
| 57 ].join('\n'); | 73 ].join('\n'); |
| 58 chrome.tabs.executeScript( | 74 chrome.tabs.executeScript( |
| 59 tabId, | 75 tabId, |
| 60 {code: injectFrameCode, allFrames: true, runAt: 'document_idle'}, | 76 {code: injectFrameCode, allFrames: true, runAt: 'document_idle'}); |
| 61 function() { | |
| 62 chrome.test.assertEq(1, counter.responsesReceived); | |
| 63 chrome.test.succeed(); | |
| 64 }); | |
| 65 }; | 77 }; |
| 66 | 78 |
| 67 function injectAndDeleteIframeFromIframe(counter, tabId) { | 79 function injectAndDeleteIframeFromIframe(counter, tabId) { |
| 68 // Inject code into each frame. Have the child frame remove itself, deleting | 80 // Inject code into each frame. Have the child frame remove itself, deleting |
| 69 // the frame while it's still executing. | 81 // the frame while it's still executing. |
| 82 counter.expectedResponses = 2; |
| 83 counter.doneCallback = function() { |
| 84 chrome.test.assertEq(2, counter.responsesReceived); |
| 85 chrome.test.succeed(); |
| 86 }; |
| 70 var injectFrameCode = [ | 87 var injectFrameCode = [ |
| 71 'if (window.self !== window.top) {', | 88 'if (window.self !== window.top) {', |
| 72 ' var iframe = window.top.document.getElementsByTagName("iframe")[0];', | 89 ' var iframe = window.top.document.getElementsByTagName("iframe")[0];', |
| 73 ' if (!iframe || iframe.contentWindow !== window)', | 90 ' if (!iframe || iframe.contentWindow !== window)', |
| 74 ' chrome.runtime.sendMessage("fail");', | 91 ' chrome.runtime.sendMessage("fail");', |
| 75 ' else', | 92 ' else', |
| 76 ' window.top.document.body.removeChild(iframe);', | 93 ' window.top.document.body.removeChild(iframe);', |
| 77 '} else {', | 94 '} else {', |
| 78 ' chrome.runtime.sendMessage("complete");', | 95 ' chrome.runtime.sendMessage("complete");', |
| 79 '}' | 96 '}' |
| 80 ].join('\n'); | 97 ].join('\n'); |
| 81 // We also use two "executeScript" calls here so that we have a pending script | 98 // We also use two "executeScript" calls here so that we have a pending script |
| 82 // execution on a frame that gets deleted. | 99 // execution on a frame that gets deleted. |
| 83 chrome.tabs.executeScript( | 100 chrome.tabs.executeScript( |
| 84 tabId, | 101 tabId, |
| 85 {code: injectFrameCode, allFrames: true, runAt: 'document_idle'}); | 102 {code: injectFrameCode, allFrames: true, runAt: 'document_idle'}); |
| 86 chrome.tabs.executeScript( | 103 chrome.tabs.executeScript( |
| 87 tabId, | 104 tabId, |
| 88 {code: injectFrameCode, allFrames: true, runAt: 'document_idle'}, | 105 {code: injectFrameCode, allFrames: true, runAt: 'document_idle'}); |
| 89 function() { | |
| 90 // Script execution, all other things equal, should happen in the order it | |
| 91 // was received, so we only need a check in the second callback. | |
| 92 chrome.test.assertEq(2, counter.responsesReceived); | |
| 93 chrome.test.succeed(); | |
| 94 }); | |
| 95 } | 106 } |
| OLD | NEW |