OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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. | |
4 | |
5 // This script is run multiple times with different configurations. The content | |
6 // scripts need to determine synchronously which subtest is being run. This | |
7 // state is communicated via the URL. | |
8 var TEST_HOST = location.search.slice(1); | |
9 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.
| |
10 'The subtest type must be specified in the query string.'); | |
11 | |
12 var config; | |
13 var tabId; | |
14 | |
15 function getTestUrl(page) { | |
16 return 'http://' + TEST_HOST + ':' + config.testServer.port + | |
17 '/extensions/api_test/executescript/destructive/' + page; | |
18 } | |
19 | |
20 chrome.test.getConfig(function(config) { | |
21 window.config = config; | |
22 | |
23 chrome.tabs.create({ | |
24 url: 'about:blank' | |
25 }, function(tab) { | |
26 tabId = tab.id; | |
27 startTest(); | |
28 }); | |
29 }); | |
30 | |
31 function startTest() { | |
32 // These tests load a page that contains a frame, where a content script will | |
33 // be run (and remove the frame). The injection point depends on the URL: | |
34 // - ?blankstart = Load a script in the blank frame at document_start. | |
35 // - ?blankend = Load a script in the blank frame at document_end. | |
36 // - ?start = Load a script in the non-blank frame at document_start. | |
37 // - ?end = Load a script in the non-blank frame at document_end. | |
38 | |
39 var kEmptyHtmlBodyPattern = /<body><\/body>/; | |
40 | |
41 var allTests = [ | |
42 // Empty document. | |
43 function removeHttpFrameAtDocumentStart() { | |
44 testRemoveSelf('empty_frame.html?start'); | |
45 }, | |
46 | |
47 function removeHttpFrameAtDocumentEnd() { | |
48 testRemoveSelf('empty_frame.html?end', kEmptyHtmlBodyPattern); | |
49 }, | |
50 | |
51 // about:blank | |
52 function removeAboutBlankAtDocumentStart() { | |
53 testRemoveSelf('about_blank_frame.html?blankstart'); | |
54 }, | |
55 | |
56 function removeAboutBlankAtDocumentEnd() { | |
57 testRemoveSelf('about_blank_frame.html?blankend', kEmptyHtmlBodyPattern); | |
58 }, | |
59 | |
60 // srcdoc frame with a HTML tag | |
61 function removeAboutSrcdocHtmlAtDocumentStart() { | |
62 testRemoveSelf('srcdoc_html_frame.html?blankstart'); | |
63 }, | |
64 | |
65 function removeAboutSrcdocHtmlAtDocumentEnd() { | |
66 testRemoveSelf('srcdoc_html_frame.html?blankend', /<br>/); | |
67 }, | |
68 | |
69 // srcdoc frame with text | |
70 function removeAboutSrcdocTextOnlyAtDocumentStart() { | |
71 testRemoveSelf('srcdoc_text_frame.html?blankstart'); | |
72 }, | |
73 | |
74 function removeAboutSrcdocTextOnlyAtDocumentEnd() { | |
75 testRemoveSelf('srcdoc_text_frame.html?blankend', /text/); | |
76 }, | |
77 | |
78 // <iframe></iframe> (no URL) | |
79 function removeFrameWithoutUrlAtDocumentStart() { | |
80 testRemoveSelf('no_url_frame.html?blankstart'); | |
81 }, | |
82 | |
83 function removeFrameWithoutUrlAtDocumentEnd() { | |
84 testRemoveSelf('no_url_frame.html?blankend', kEmptyHtmlBodyPattern); | |
85 }, | |
86 | |
87 // An image. | |
88 function removeImageAtDocumentStart() { | |
89 testRemoveSelf('image_frame.html?start'); | |
90 }, | |
91 | |
92 function removeImageAtDocumentEnd() { | |
93 testRemoveSelf('image_frame.html?end', /<img/); | |
94 }, | |
95 | |
96 // Audio (media). | |
97 function removeAudioAtDocumentStart() { | |
98 testRemoveSelf('audio_frame.html?start'); | |
99 }, | |
100 | |
101 function removeAudioAtDocumentEnd() { | |
102 testRemoveSelf('audio_frame.html?end', /<video.+ type="audio\//); | |
103 }, | |
104 | |
105 // Video (media). | |
106 function removeVideoAtDocumentStart() { | |
107 testRemoveSelf('video_frame.html?start'); | |
108 }, | |
109 | |
110 function removeVideoAtDocumentEnd() { | |
111 testRemoveSelf('video_frame.html?end', /<video.+ type="video\//); | |
112 }, | |
113 | |
114 // Plugins | |
115 function removePluginAtDocumentStart() { | |
116 if (maybeSkipPluginTest()) | |
117 return; | |
118 testRemoveSelf('plugin_frame.html?start'); | |
119 }, | |
120 | |
121 function removePluginAtDocumentEnd() { | |
122 if (maybeSkipPluginTest()) | |
123 return; | |
124 testRemoveSelf('plugin_frame.html?end', /<embed/); | |
125 }, | |
126 | |
127 // Plain text | |
128 function removePlainTextAtDocumentStart() { | |
129 testRemoveSelf('txt_frame.html?start'); | |
130 }, | |
131 | |
132 function removePlainTextAtDocumentEnd() { | |
133 testRemoveSelf('txt_frame.html?end', /<pre/); | |
134 }, | |
135 | |
136 // XHTML | |
137 function removeXhtmlAtDocumentStart() { | |
138 testRemoveSelf('xhtml_frame.html?start', | |
139 /<html xmlns="http:\/\/www\.w3\.org\/1999\/xhtml"><\/html>/); | |
140 }, | |
141 | |
142 function removeXhtmlAtDocumentEnd() { | |
143 testRemoveSelf('xhtml_frame.html?end', | |
144 /<html xmlns="http:\/\/www\.w3\.org\/1999\/xhtml">/); | |
145 }, | |
146 | |
147 // XML | |
148 function removeXmlAtDocumentStart() { | |
149 testRemoveSelf('xml_frame.html?start', /<root\/>/); | |
150 }, | |
151 | |
152 function removeXmlAtDocumentEnd() { | |
153 testRemoveSelf('xml_frame.html?end', /<root><child\/><\/root>/); | |
154 }, | |
155 ]; | |
156 | |
157 // Each test consists of a document_start and document_end test. | |
158 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
| |
159 var totalTestCount = allTests.length / kTestsPerInstance; | |
160 | |
161 // Used to verify that the number of tests defined in this file matches the | |
162 // number of parameters in execute_script_apitest.cc. | |
163 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.
| |
164 chrome.test.assertEq(totalTestCount, actualTestCount, 'The number of test ' + | |
165 'cases (kNumberOfDestructiveScriptTests in execute_script_apitest.cc) ' + | |
166 'should be' + totalTestCount + ', but was ' + actualTestCount); | |
167 | |
168 // Which pair of tests to run. | |
169 var testInstance = parseInt(/instance=(\d+)/.exec(location.hash)[1]); | |
170 var filteredTests = allTests.slice(testInstance * kTestsPerInstance, | |
171 (testInstance + 1) * kTestsPerInstance); | |
172 chrome.test.runTests(filteredTests); | |
173 } | |
174 | |
175 // |page| must be an existing page in this directory, and the URL must be | |
176 // matched by one content script. Otherwise the test will time out. | |
177 // | |
178 // If the regular expression |pattern| is specified, then the serialization of | |
179 // the frame content must match the pattern. This ensures that the tests are | |
180 // still testing the expected document in the future. | |
181 function testRemoveSelf(page, pattern) { | |
182 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.
| |
183 | |
184 // By default, the serialization of the document must be non-empty. | |
185 var kDefaultPattern = /</; | |
186 | |
187 if (page.includes('start')) { | |
188 pattern = pattern || /^<html><\/html>$/; | |
189 pattern = TEST_HOST === 'synchronous' ? pattern : kDefaultPattern; | |
190 } else if (page.includes('end')) { | |
191 // TODO(robwu): This check should be enabled for all document_end tests, | |
192 // because the DOM should be complete by then (and not modified thereafter). | |
193 // Unfortunately, the serialized document of document_end scripts in image / | |
194 // plugin / ... documents appears to be "<html></html>" at document_end. | |
195 // This is probably a bug, but can be fixed later. | |
196 pattern = TEST_HOST === 'macrotask' && pattern || kDefaultPattern; | |
197 } else { | |
198 chrome.test.fail('URL must contain "start" or "end": ' + page); | |
199 } | |
200 | |
201 chrome.test.listenOnce(chrome.runtime.onMessage, function(msg, sender) { | |
202 chrome.test.assertEq(tabId, sender.tab && sender.tab.id); | |
203 chrome.test.assertEq(0, sender.frameId); | |
204 | |
205 var frameHTML = msg.frameHTML; | |
206 delete msg.frameHTML; | |
207 chrome.test.assertEq({frameCount: 0}, msg); | |
208 | |
209 chrome.test.assertTrue(pattern.test(frameHTML), | |
210 'The pattern ' + pattern + ' should be matched by: ' + frameHTML); | |
211 }); | |
212 chrome.tabs.update(tabId, {url: url}); | |
213 } | |
214 | |
215 // The plugin test requires a plugin to be installed. Skip the test if plugins | |
216 // are not supported. | |
217 function maybeSkipPluginTest() { | |
218 // This MIME-type should be handled by a browser plugin. | |
219 var kPluginMimeType = 'application/pdf'; | |
220 for (var i = 0; i < navigator.plugins.length; ++i) { | |
221 var plugin = navigator.plugins[i]; | |
222 for (var j = 0; j < plugin.length; ++j) { | |
223 var mimeType = plugin[j]; | |
224 if (mimeType.type === kPluginMimeType) | |
225 return false; | |
226 } | |
227 } | |
228 var kMessage = 'Plugin not found for ' + kPluginMimeType + ', skipping test.'; | |
229 console.log(kMessage); | |
230 chrome.test.log(kMessage); | |
231 chrome.test.succeed(); | |
232 return true; | |
233 } | |
OLD | NEW |