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
3 // found in the LICENSE file.
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
7 // cleaned up, but, realistically, doesn't matter.
8 function ResponseCounter() {
9 this.responsesReceived
= 0;
10 chrome
.runtime
.onMessage
.addListener(function(request
, sender
, sendResponse
) {
11 if (request
== 'fail') {
14 chrome
.test
.assertEq('complete', request
);
15 ++this.responsesReceived
;
20 var waitForCommittedAndRun = function(functionToRun
, numCommits
, url
) {
21 var committedCount
= 0;
22 var counter
= new ResponseCounter(); // Every test gets a counter.
23 var onCommitted = function(details
) {
24 if (++committedCount
== numCommits
) {
25 functionToRun(counter
, details
.tabId
);
26 chrome
.webNavigation
.onCommitted
.removeListener(onCommitted
);
29 chrome
.webNavigation
.onCommitted
.addListener(onCommitted
);
30 chrome
.tabs
.create({url
: url
});
33 chrome
.test
.getConfig(function(config
) {
34 var url
= 'http://a.com:' + config
.testServer
.port
+
35 '/extensions/api_test/executescript/removed_frames/outer.html';
36 // Regression tests for crbug.com/500574.
37 chrome
.test
.runTests([
39 waitForCommittedAndRun(injectAndDeleteIframeFromMainFrame
, 2, url
);
42 waitForCommittedAndRun(injectAndDeleteIframeFromIframe
, 2, url
);
47 function injectAndDeleteIframeFromMainFrame(counter
, tabId
) {
48 // 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
50 // finish executing, since it's been removed.
51 var injectFrameCode
= [
52 'if (window === window.top) {',
53 ' iframe = document.getElementsByTagName("iframe")[0];',
54 ' iframe.parentElement.removeChild(iframe);',
55 ' chrome.runtime.sendMessage("complete");',
58 chrome
.tabs
.executeScript(
60 {code
: injectFrameCode
, allFrames
: true, runAt
: 'document_idle'},
62 chrome
.test
.assertEq(1, counter
.responsesReceived
);
63 chrome
.test
.succeed();
67 function injectAndDeleteIframeFromIframe(counter
, tabId
) {
68 // Inject code into each frame. Have the child frame remove itself, deleting
69 // the frame while it's still executing.
70 var injectFrameCode
= [
71 'if (window.self !== window.top) {',
72 ' var iframe = window.top.document.getElementsByTagName("iframe")[0];',
73 ' if (!iframe || iframe.contentWindow !== window)',
74 ' chrome.runtime.sendMessage("fail");',
76 ' window.top.document.body.removeChild(iframe);',
78 ' chrome.runtime.sendMessage("complete");',
81 // We also use two "executeScript" calls here so that we have a pending script
82 // execution on a frame that gets deleted.
83 chrome
.tabs
.executeScript(
85 {code
: injectFrameCode
, allFrames
: true, runAt
: 'document_idle'});
86 chrome
.tabs
.executeScript(
88 {code
: injectFrameCode
, allFrames
: true, runAt
: 'document_idle'},
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();