| 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 !== '',
|
| + '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;
|
| + 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]);
|
| + 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);
|
| +
|
| + // 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;
|
| +}
|
|
|