Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4645)

Unified Diff: chrome/test/data/extensions/api_test/executescript/removed_frames/test.js

Issue 1216453002: [Extensions] Handle some funny cases in script injection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/test/data/extensions/api_test/executescript/removed_frames/test.js
diff --git a/chrome/test/data/extensions/api_test/executescript/removed_frames/test.js b/chrome/test/data/extensions/api_test/executescript/removed_frames/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..364ff6c5921698f89cae6bea4ac7dc953a258bb2
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/executescript/removed_frames/test.js
@@ -0,0 +1,100 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var responsesReceived = 0;
not at google - send to devlin 2015/06/29 18:28:11 Can we avoid global variables? Worst case it'll be
Devlin 2015/06/29 19:41:44 Not sure I follow. This count is used in both tes
not at google - send to devlin 2015/06/29 20:09:07 It seems like it's reset to 0 in each test. Why do
Devlin 2015/06/29 20:43:13 chrome.runtime.onMessage listener is global to avo
not at google - send to devlin 2015/06/29 21:24:35 I don't think it's excessive. You can listen to th
Devlin 2015/06/29 21:51:20 Done.
+chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
+ if (request == 'fail') {
+ chrome.test.fail();
+ } else {
+ chrome.test.assertEq('complete', request);
+ ++responsesReceived;
+ }
+});
+
+var waitForCommittedAndRun = function(functionToRun, numCommits, url) {
+ responsesReceived = 0;
+ var committedCount = 0;
+ var onCommitted = function(details) {
+ if (++committedCount == numCommits) {
+ functionToRun(details.tabId);
+ chrome.webNavigation.onCommitted.removeListener(onCommitted);
+ }
+ };
+ chrome.webNavigation.onCommitted.addListener(onCommitted);
+ chrome.tabs.create({url: url});
+};
+
+chrome.test.getConfig(function(config) {
+ var url = ('http://a.com:PORT/extensions/api_test/executescript/' +
+ 'removed_frames/outer.html').replace(/PORT/,
+ config.testServer.port);
not at google - send to devlin 2015/06/29 18:28:11 I find this pattern pretty weird, and I've seen it
Devlin 2015/06/29 19:41:44 I don't know either (copied). Changed.
+ // Regression tests for crbug.com/500574.
+ chrome.test.runTests([
+ function() {
+ waitForCommittedAndRun(injectAndDeleteIframeFromMainFrame, 2, url);
not at google - send to devlin 2015/06/29 21:24:35 Err, why is the tab ID 2? Can you make it not depe
Devlin 2015/06/29 21:51:20 Tab id is not 2. The number of commits to wait fo
+ }
+ // This is another great test to have, but currently it crashes in blink.
+ // TODO(devlin): Fix the crash in blink and enable this!
Devlin 2015/06/25 21:12:27 This will be done soon.
+ // function() {
+ // waitForCommittedAndRun(injectAndDeleteIframeFromIframe, 2, url);
+ // }
+ ]);
+});
+
+function injectAndDeleteIframeFromMainFrame(tabId) {
+ // Inject code into each frame. If it's the parent frame, it removes the child
+ // frame from the DOM (invalidating it). The child frame's code shouldn't
+ // finish executing, since it's been removed.
+ var injectFrameCode =
+ 'if (window !== window.top) {' +
not at google - send to devlin 2015/06/29 18:28:11 nit (sorta): the problem with this is that the lin
Devlin 2015/06/29 19:41:44 Done.
+ // There's a (good) chance the child frame reaches "idle" first, since it
+ // is a subresource of the main frame. But it shouldn't stick around for
+ // more than 200ms or so, since that's the max delay for idle. If the
+ // script still tries to execute, it's probably bad.
+ ' window.setTimeout(function() {' +
+ ' chrome.runtime.sendMessage("fail");' +
not at google - send to devlin 2015/06/29 18:28:11 Why does it matter? The way I read this (?) withou
Devlin 2015/06/29 19:41:44 Well, even if that were the case, failing is a lot
not at google - send to devlin 2015/06/29 20:09:07 That is beside the point, but I disagree, and will
Devlin 2015/06/29 20:43:13 But the point is that this code will *not* run. I
+ ' }, 250);' +
+ '} else {' +
+ ' iframe = document.getElementsByTagName("iframe")[0];' +
+ ' iframe.parentElement.removeChild(iframe);' +
+ ' chrome.runtime.sendMessage("complete");' +
+ '}';
+ chrome.tabs.executeScript(
+ tabId,
+ {code: injectFrameCode, allFrames: true, runAt: 'document_idle'},
+ function() {
+ chrome.test.assertEq(1, responsesReceived);
+ chrome.test.succeed();
+ });
+};
+
+function injectAndDeleteIframeFromIframe(tabId) {
+ responsesReceived = 0;
+ // Inject code into each frame. Have the child frame remove itself, deleting
+ // the frame while it's still executing.
+ var injectFrameCode =
+ 'if (window.self !== window.top) {' +
+ ' var iframe = window.top.document.getElementsByTagName("iframe")[0];' +
+ ' if (!iframe || iframe.contentWindow !== window)' +
+ ' chrome.runtime.sendMessage("fail");' +
+ ' else' +
+ ' window.top.document.body.removeChild(iframe);' +
+ '} else {' +
+ ' chrome.runtime.sendMessage("complete");' +
+ '}';
+ // We also use two "executeScript" calls here so that we have a pending script
+ // execution on a frame that gets deleted.
+ chrome.tabs.executeScript(
+ tabId,
+ {code: injectFrameCode, allFrames: true, runAt: 'document_idle'});
+ chrome.tabs.executeScript(
+ tabId,
+ {code: injectFrameCode, allFrames: true, runAt: 'document_idle'},
+ function() {
+ // Script execution, all other things equal, should happen in the order it
+ // was received, so we only need a check in the second callback.
+ chrome.test.assertEq(2, responsesReceived);
+ chrome.test.succeed();
+ });
+}

Powered by Google App Engine
This is Rietveld 408576698