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

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

Issue 1642283002: Deal with frame removal by content scripts (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add more runScriptsAtDocumentElementAvailable + comments Created 4 years, 10 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/destructive/test.js
diff --git a/chrome/test/data/extensions/api_test/executescript/destructive/test.js b/chrome/test/data/extensions/api_test/executescript/destructive/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..0c0404109d830e4b167720151a1915348a670e51
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/executescript/destructive/test.js
@@ -0,0 +1,233 @@
+// Copyright 2016 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.
+
+// This script is run multiple times with different configurations. The content
+// scripts need to determine synchronously which subtest is being run. This
+// state is communicated via the URL.
+var TEST_HOST = location.search.slice(1);
+chrome.test.assertTrue(TEST_HOST !== '',
Devlin 2016/03/15 00:53:32 nit: put TEST_HOST !== '' on the next line to matc
robwu 2016/03/16 22:03:32 Done.
+ 'The subtest type must be specified in the query string.');
+
+var config;
+var tabId;
+
+function getTestUrl(page) {
+ return 'http://' + TEST_HOST + ':' + config.testServer.port +
+ '/extensions/api_test/executescript/destructive/' + page;
+}
+
+chrome.test.getConfig(function(config) {
+ window.config = config;
+
+ chrome.tabs.create({
+ url: 'about:blank'
+ }, function(tab) {
+ tabId = tab.id;
+ startTest();
+ });
+});
+
+function startTest() {
+ // These tests load a page that contains a frame, where a content script will
+ // be run (and remove the frame). The injection point depends on the URL:
+ // - ?blankstart = Load a script in the blank frame at document_start.
+ // - ?blankend = Load a script in the blank frame at document_end.
+ // - ?start = Load a script in the non-blank frame at document_start.
+ // - ?end = Load a script in the non-blank frame at document_end.
+
+ var kEmptyHtmlBodyPattern = /<body><\/body>/;
+
+ var allTests = [
+ // Empty document.
+ function removeHttpFrameAtDocumentStart() {
+ testRemoveSelf('empty_frame.html?start');
+ },
+
+ function removeHttpFrameAtDocumentEnd() {
+ testRemoveSelf('empty_frame.html?end', kEmptyHtmlBodyPattern);
+ },
+
+ // about:blank
+ function removeAboutBlankAtDocumentStart() {
+ testRemoveSelf('about_blank_frame.html?blankstart');
+ },
+
+ function removeAboutBlankAtDocumentEnd() {
+ testRemoveSelf('about_blank_frame.html?blankend', kEmptyHtmlBodyPattern);
+ },
+
+ // srcdoc frame with a HTML tag
+ function removeAboutSrcdocHtmlAtDocumentStart() {
+ testRemoveSelf('srcdoc_html_frame.html?blankstart');
+ },
+
+ function removeAboutSrcdocHtmlAtDocumentEnd() {
+ testRemoveSelf('srcdoc_html_frame.html?blankend', /<br>/);
+ },
+
+ // srcdoc frame with text
+ function removeAboutSrcdocTextOnlyAtDocumentStart() {
+ testRemoveSelf('srcdoc_text_frame.html?blankstart');
+ },
+
+ function removeAboutSrcdocTextOnlyAtDocumentEnd() {
+ testRemoveSelf('srcdoc_text_frame.html?blankend', /text/);
+ },
+
+ // <iframe></iframe> (no URL)
+ function removeFrameWithoutUrlAtDocumentStart() {
+ testRemoveSelf('no_url_frame.html?blankstart');
+ },
+
+ function removeFrameWithoutUrlAtDocumentEnd() {
+ testRemoveSelf('no_url_frame.html?blankend', kEmptyHtmlBodyPattern);
+ },
+
+ // An image.
+ function removeImageAtDocumentStart() {
+ testRemoveSelf('image_frame.html?start');
+ },
+
+ function removeImageAtDocumentEnd() {
+ testRemoveSelf('image_frame.html?end', /<img/);
+ },
+
+ // Audio (media).
+ function removeAudioAtDocumentStart() {
+ testRemoveSelf('audio_frame.html?start');
+ },
+
+ function removeAudioAtDocumentEnd() {
+ testRemoveSelf('audio_frame.html?end', /<video.+ type="audio\//);
+ },
+
+ // Video (media).
+ function removeVideoAtDocumentStart() {
+ testRemoveSelf('video_frame.html?start');
+ },
+
+ function removeVideoAtDocumentEnd() {
+ testRemoveSelf('video_frame.html?end', /<video.+ type="video\//);
+ },
+
+ // Plugins
+ function removePluginAtDocumentStart() {
+ if (maybeSkipPluginTest())
+ return;
+ testRemoveSelf('plugin_frame.html?start');
+ },
+
+ function removePluginAtDocumentEnd() {
+ if (maybeSkipPluginTest())
+ return;
+ testRemoveSelf('plugin_frame.html?end', /<embed/);
+ },
+
+ // Plain text
+ function removePlainTextAtDocumentStart() {
+ testRemoveSelf('txt_frame.html?start');
+ },
+
+ function removePlainTextAtDocumentEnd() {
+ testRemoveSelf('txt_frame.html?end', /<pre/);
+ },
+
+ // XHTML
+ function removeXhtmlAtDocumentStart() {
+ testRemoveSelf('xhtml_frame.html?start',
+ /<html xmlns="http:\/\/www\.w3\.org\/1999\/xhtml"><\/html>/);
+ },
+
+ function removeXhtmlAtDocumentEnd() {
+ testRemoveSelf('xhtml_frame.html?end',
+ /<html xmlns="http:\/\/www\.w3\.org\/1999\/xhtml">/);
+ },
+
+ // XML
+ function removeXmlAtDocumentStart() {
+ testRemoveSelf('xml_frame.html?start', /<root\/>/);
+ },
+
+ function removeXmlAtDocumentEnd() {
+ testRemoveSelf('xml_frame.html?end', /<root><child\/><\/root>/);
+ },
+ ];
+
+ // Each test consists of a document_start and document_end test.
+ var kTestsPerInstance = 2;
Devlin 2016/03/15 16:34:35 How slow is this if we run all 24 tests in one?
robwu 2016/03/16 22:03:32 About 25 seconds. I've now disabled 6x12 DOM mutat
Devlin 2016/03/17 16:59:02 Hmm... if it's only 25 seconds, I wonder if we can
robwu 2016/03/17 22:20:40 I've decreased it to 1 bucket, but kept the test s
+ var totalTestCount = allTests.length / kTestsPerInstance;
+
+ // Used to verify that the number of tests defined in this file matches the
+ // number of parameters in execute_script_apitest.cc.
+ var actualTestCount = parseInt(/count=(\d+)/.exec(location.hash)[1]);
Devlin 2016/03/15 16:34:35 Could we use the URL api (specifically searchParam
robwu 2016/03/16 22:03:32 Done.
+ chrome.test.assertEq(totalTestCount, actualTestCount, 'The number of test ' +
+ 'cases (kNumberOfDestructiveScriptTests in execute_script_apitest.cc) ' +
+ 'should be' + totalTestCount + ', but was ' + actualTestCount);
+
+ // Which pair of tests to run.
+ var testInstance = parseInt(/instance=(\d+)/.exec(location.hash)[1]);
+ var filteredTests = allTests.slice(testInstance * kTestsPerInstance,
+ (testInstance + 1) * kTestsPerInstance);
+ chrome.test.runTests(filteredTests);
+}
+
+// |page| must be an existing page in this directory, and the URL must be
+// matched by one content script. Otherwise the test will time out.
+//
+// If the regular expression |pattern| is specified, then the serialization of
+// the frame content must match the pattern. This ensures that the tests are
+// still testing the expected document in the future.
+function testRemoveSelf(page, pattern) {
+ var url = getTestUrl(page);
Devlin 2016/03/15 16:34:35 Just inline this on line 212
robwu 2016/03/16 22:03:32 Done.
+
+ // By default, the serialization of the document must be non-empty.
+ var kDefaultPattern = /</;
+
+ if (page.includes('start')) {
+ pattern = pattern || /^<html><\/html>$/;
+ pattern = TEST_HOST === 'synchronous' ? pattern : kDefaultPattern;
+ } else if (page.includes('end')) {
+ // TODO(robwu): This check should be enabled for all document_end tests,
+ // because the DOM should be complete by then (and not modified thereafter).
+ // Unfortunately, the serialized document of document_end scripts in image /
+ // plugin / ... documents appears to be "<html></html>" at document_end.
+ // This is probably a bug, but can be fixed later.
+ pattern = TEST_HOST === 'macrotask' && pattern || kDefaultPattern;
+ } else {
+ chrome.test.fail('URL must contain "start" or "end": ' + page);
+ }
+
+ chrome.test.listenOnce(chrome.runtime.onMessage, function(msg, sender) {
+ chrome.test.assertEq(tabId, sender.tab && sender.tab.id);
+ chrome.test.assertEq(0, sender.frameId);
+
+ var frameHTML = msg.frameHTML;
+ delete msg.frameHTML;
+ chrome.test.assertEq({frameCount: 0}, msg);
+
+ chrome.test.assertTrue(pattern.test(frameHTML),
+ 'The pattern ' + pattern + ' should be matched by: ' + frameHTML);
+ });
+ chrome.tabs.update(tabId, {url: url});
+}
+
+// The plugin test requires a plugin to be installed. Skip the test if plugins
+// are not supported.
+function maybeSkipPluginTest() {
+ // This MIME-type should be handled by a browser plugin.
+ var kPluginMimeType = 'application/pdf';
+ for (var i = 0; i < navigator.plugins.length; ++i) {
+ var plugin = navigator.plugins[i];
+ for (var j = 0; j < plugin.length; ++j) {
+ var mimeType = plugin[j];
+ if (mimeType.type === kPluginMimeType)
+ return false;
+ }
+ }
+ var kMessage = 'Plugin not found for ' + kPluginMimeType + ', skipping test.';
+ console.log(kMessage);
+ chrome.test.log(kMessage);
+ chrome.test.succeed();
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698