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 |