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

Side by Side Diff: third_party/WebKit/Source/web/tests/HTMLDocumentParserLoadingTest.cpp

Issue 2614663004: Pause HTML parser for external stylesheets in the body (Closed)
Patch Set: Paramaterized test cases Created 3 years, 11 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/web/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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 #include "core/html/parser/HTMLDocumentParser.h"
6
7 #include "core/dom/Document.h"
8 #include "platform/testing/UnitTestHelpers.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "web/tests/sim/SimRequest.h"
11 #include "web/tests/sim/SimTest.h"
12
13 namespace blink {
14
15 using namespace HTMLNames;
16
17 class HTMLDocumentParserLoadingTest
18 : public SimTest,
19 public ::testing::WithParamInterface<bool> {
20 protected:
21 HTMLDocumentParserLoadingTest() {
22 Document::setThreadedParsingEnabledForTesting(GetParam());
23 }
24 };
25
26 INSTANTIATE_TEST_CASE_P(Threaded,
27 HTMLDocumentParserLoadingTest,
28 ::testing::Values(true));
29 INSTANTIATE_TEST_CASE_P(NotThreaded,
30 HTMLDocumentParserLoadingTest,
31 ::testing::Values(false));
32
33 TEST_P(HTMLDocumentParserLoadingTest,
34 ShouldNotPauseParsingForExternalStylesheetsInHead) {
35 SimRequest mainResource("https://example.com/test.html", "text/html");
36 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
37
38 loadURL("https://example.com/test.html");
39
40 mainResource.complete(
41 "<!DOCTYPE html>"
42 "<html><head>"
43 "<link rel=stylesheet href=testHead.css>"
44 "</head><body>"
45 "<div id=\"bodyDiv\"></div>"
46 "</body></html>");
47
48 testing::runPendingTasks();
49 EXPECT_TRUE(document().getElementById("bodyDiv"));
50 cssHeadResource.complete("");
51 testing::runPendingTasks();
52 EXPECT_TRUE(document().getElementById("bodyDiv"));
53 }
54
55 TEST_P(HTMLDocumentParserLoadingTest,
56 ShouldNotPauseParsingForExternalStylesheetsImportedInHead) {
57 SimRequest mainResource("https://example.com/test.html", "text/html");
58 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
59
60 loadURL("https://example.com/test.html");
61
62 mainResource.complete(
63 "<!DOCTYPE html>"
64 "<html><head>"
65 "<style>"
66 "@import 'testHead.css'"
67 "</style>"
68 "</head><body>"
69 "<div id=\"bodyDiv\"></div>"
70 "</body></html>");
71
72 testing::runPendingTasks();
73 EXPECT_TRUE(document().getElementById("bodyDiv"));
74 cssHeadResource.complete("");
75 testing::runPendingTasks();
76 EXPECT_TRUE(document().getElementById("bodyDiv"));
77 }
78
79 TEST_P(HTMLDocumentParserLoadingTest,
80 ShouldPauseParsingForExternalStylesheetsInBody) {
81 SimRequest mainResource("https://example.com/test.html", "text/html");
82 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
83 SimRequest cssBodyResource("https://example.com/testBody.css", "text/css");
84
85 loadURL("https://example.com/test.html");
86
87 mainResource.complete(
88 "<!DOCTYPE html>"
89 "<html><head>"
90 "<link rel=stylesheet href=testHead.css>"
91 "</head><body>"
92 "<div id=\"before\"></div>"
93 "<link rel=stylesheet href=testBody.css>"
94 "<div id=\"after\"></div>"
95 "</body></html>");
96
97 testing::runPendingTasks();
98 EXPECT_TRUE(document().getElementById("before"));
99 EXPECT_FALSE(document().getElementById("after"));
100
101 // Completing the head css shouldn't change anything
102 cssHeadResource.complete("");
103 testing::runPendingTasks();
104 EXPECT_TRUE(document().getElementById("before"));
105 EXPECT_FALSE(document().getElementById("after"));
106
107 // Completing the body resource and pumping the tasks should continue parsing
108 // and create the "after" div.
109 cssBodyResource.complete("");
110 testing::runPendingTasks();
111 EXPECT_TRUE(document().getElementById("before"));
112 EXPECT_TRUE(document().getElementById("after"));
113 }
114
115 TEST_P(HTMLDocumentParserLoadingTest,
116 ShouldPauseParsingForExternalStylesheetsInBodyIncremental) {
117 SimRequest mainResource("https://example.com/test.html", "text/html");
118 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
119 SimRequest cssBodyResource1("https://example.com/testBody1.css", "text/css");
120 SimRequest cssBodyResource2("https://example.com/testBody2.css", "text/css");
121 SimRequest cssBodyResource3("https://example.com/testBody3.css", "text/css");
122
123 loadURL("https://example.com/test.html");
124
125 mainResource.start();
126 mainResource.write(
127 "<!DOCTYPE html>"
128 "<html><head>"
129 "<link rel=stylesheet href=testHead.css>"
130 "</head><body>"
131 "<div id=\"before\"></div>"
132 "<link rel=stylesheet href=testBody1.css>"
133 "<div id=\"after1\"></div>");
134
135 testing::runPendingTasks();
136 EXPECT_TRUE(document().getElementById("before"));
137 EXPECT_FALSE(document().getElementById("after1"));
138 EXPECT_FALSE(document().getElementById("after2"));
139 EXPECT_FALSE(document().getElementById("after3"));
140
141 mainResource.write(
142 "<link rel=stylesheet href=testBody2.css>"
143 "<div id=\"after2\"></div>");
144
145 testing::runPendingTasks();
146 EXPECT_TRUE(document().getElementById("before"));
147 EXPECT_FALSE(document().getElementById("after1"));
148 EXPECT_FALSE(document().getElementById("after2"));
149 EXPECT_FALSE(document().getElementById("after3"));
150
151 mainResource.complete(
152 "<link rel=stylesheet href=testBody3.css>"
153 "<div id=\"after3\"></div>"
154 "</body></html>");
155
156 testing::runPendingTasks();
157 EXPECT_TRUE(document().getElementById("before"));
158 EXPECT_FALSE(document().getElementById("after1"));
159 EXPECT_FALSE(document().getElementById("after2"));
160 EXPECT_FALSE(document().getElementById("after3"));
161
162 // Completing the head css shouldn't change anything
163 cssHeadResource.complete("");
164 testing::runPendingTasks();
165 EXPECT_TRUE(document().getElementById("before"));
166 EXPECT_FALSE(document().getElementById("after1"));
167 EXPECT_FALSE(document().getElementById("after2"));
168 EXPECT_FALSE(document().getElementById("after3"));
169
170 // Completing the second css shouldn't change anything
171 cssBodyResource2.complete("");
172 testing::runPendingTasks();
173 EXPECT_TRUE(document().getElementById("before"));
174 EXPECT_FALSE(document().getElementById("after1"));
175 EXPECT_FALSE(document().getElementById("after2"));
176 EXPECT_FALSE(document().getElementById("after3"));
177
178 // Completing the first css should allow the parser to continue past it and
179 // the second css which was already completed and then pause again before the
180 // third css.
181 cssBodyResource1.complete("");
182 testing::runPendingTasks();
183 EXPECT_TRUE(document().getElementById("before"));
184 EXPECT_TRUE(document().getElementById("after1"));
185 EXPECT_TRUE(document().getElementById("after2"));
186 EXPECT_FALSE(document().getElementById("after3"));
187
188 // Completing the third css should let it continue to the end.
189 cssBodyResource3.complete("");
190 testing::runPendingTasks();
191 EXPECT_TRUE(document().getElementById("before"));
192 EXPECT_TRUE(document().getElementById("after1"));
193 EXPECT_TRUE(document().getElementById("after2"));
194 EXPECT_TRUE(document().getElementById("after3"));
195 }
196
197 TEST_P(HTMLDocumentParserLoadingTest,
198 ShouldNotPauseParsingForExternalNonMatchingStylesheetsInBody) {
199 SimRequest mainResource("https://example.com/test.html", "text/html");
200 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
201
202 loadURL("https://example.com/test.html");
203
204 mainResource.complete(
205 "<!DOCTYPE html>"
206 "<html><head>"
207 "<link rel=stylesheet href=testHead.css>"
208 "</head><body>"
209 "<div id=\"before\"></div>"
210 "<link rel=stylesheet href=testBody.css type='print'>"
211 "<div id=\"after\"></div>"
212 "</body></html>");
213
214 testing::runPendingTasks();
215 EXPECT_TRUE(document().getElementById("before"));
216 EXPECT_TRUE(document().getElementById("after"));
217
218 // Completing the head css shouldn't change anything
219 cssHeadResource.complete("");
220 }
221
222 TEST_P(HTMLDocumentParserLoadingTest,
223 ShouldPauseParsingForExternalStylesheetsImportedInBody) {
224 SimRequest mainResource("https://example.com/test.html", "text/html");
225 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
226 SimRequest cssBodyResource("https://example.com/testBody.css", "text/css");
227
228 loadURL("https://example.com/test.html");
229
230 mainResource.complete(
231 "<!DOCTYPE html>"
232 "<html><head>"
233 "<link rel=stylesheet href=testHead.css>"
234 "</head><body>"
235 "<div id=\"before\"></div>"
236 "<style>"
237 "@import 'testBody.css'"
238 "</style>"
239 "<div id=\"after\"></div>"
240 "</body></html>");
241
242 testing::runPendingTasks();
243 EXPECT_TRUE(document().getElementById("before"));
244 EXPECT_FALSE(document().getElementById("after"));
245
246 // Completing the head css shouldn't change anything
247 cssHeadResource.complete("");
248 testing::runPendingTasks();
249 EXPECT_TRUE(document().getElementById("before"));
250 EXPECT_FALSE(document().getElementById("after"));
251
252 // Completing the body resource and pumping the tasks should continue parsing
253 // and create the "after" div.
254 cssBodyResource.complete("");
255 testing::runPendingTasks();
256 EXPECT_TRUE(document().getElementById("before"));
257 EXPECT_TRUE(document().getElementById("after"));
258 }
259
260 TEST_P(HTMLDocumentParserLoadingTest,
261 ShouldPauseParsingForExternalStylesheetsWrittenInBody) {
262 SimRequest mainResource("https://example.com/test.html", "text/html");
263 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
264 SimRequest cssBodyResource("https://example.com/testBody.css", "text/css");
265
266 loadURL("https://example.com/test.html");
267
268 mainResource.complete(
269 "<!DOCTYPE html>"
270 "<html><head>"
271 "<link rel=stylesheet href=testHead.css>"
272 "</head><body>"
273 "<div id=\"before\"></div>"
274 "<script>"
275 "document.write('<link rel=stylesheet href=testBody.css>');"
276 "</script>"
277 "<div id=\"after\"></div>"
278 "</body></html>");
279
280 testing::runPendingTasks();
281 EXPECT_TRUE(document().getElementById("before"));
282 EXPECT_FALSE(document().getElementById("after"));
283
284 // Completing the head css shouldn't change anything
285 cssHeadResource.complete("");
286 testing::runPendingTasks();
287 EXPECT_TRUE(document().getElementById("before"));
288 EXPECT_FALSE(document().getElementById("after"));
289
290 // Completing the body resource and pumping the tasks should continue parsing
291 // and create the "after" div.
292 cssBodyResource.complete("");
293 testing::runPendingTasks();
294 EXPECT_TRUE(document().getElementById("before"));
295 EXPECT_TRUE(document().getElementById("after"));
296 }
297
298 TEST_P(HTMLDocumentParserLoadingTest,
299 PendingHeadStylesheetShouldNotBlockParserForBodyInlineStyle) {
300 SimRequest mainResource("https://example.com/test.html", "text/html");
301 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
302
303 loadURL("https://example.com/test.html");
304
305 mainResource.complete(
306 "<!DOCTYPE html>"
307 "<html><head>"
308 "<link rel=stylesheet href=testHead.css>"
309 "</head><body>"
310 "<div id=\"before\"></div>"
311 "<style>"
312 "</style>"
313 "<div id=\"after\"></div>"
314 "</body></html>");
315
316 testing::runPendingTasks();
317 EXPECT_TRUE(document().getElementById("before"));
318 EXPECT_TRUE(document().getElementById("after"));
319 cssHeadResource.complete("");
320 }
321
322 TEST_P(HTMLDocumentParserLoadingTest,
323 PendingHeadStylesheetShouldNotBlockParserForBodyShadowDom) {
324 SimRequest mainResource("https://example.com/test.html", "text/html");
325 SimRequest cssHeadResource("https://example.com/testHead.css", "text/css");
326
327 loadURL("https://example.com/test.html");
328
329 // The marquee tag has a shadow DOM that synchronously applies a stylesheet.
330 mainResource.complete(
331 "<!DOCTYPE html>"
332 "<html><head>"
333 "<link rel=stylesheet href=testHead.css>"
334 "</head><body>"
335 "<div id=\"before\"></div>"
336 "<marquee>Marquee</marquee>"
337 "<div id=\"after\"></div>"
338 "</body></html>");
339
340 testing::runPendingTasks();
341 EXPECT_TRUE(document().getElementById("before"));
342 EXPECT_TRUE(document().getElementById("after"));
343 cssHeadResource.complete("");
344 }
345
346 TEST_P(HTMLDocumentParserLoadingTest,
347 ShouldNotPauseParsingForExternalStylesheetsAttachedInBody) {
348 SimRequest mainResource("https://example.com/test.html", "text/html");
349 SimRequest cssAsyncResource("https://example.com/testAsync.css", "text/css");
350
351 loadURL("https://example.com/test.html");
352
353 mainResource.complete(
354 "<!DOCTYPE html>"
355 "<html><head>"
356 "</head><body>"
357 "<div id=\"before\"></div>"
358 "<script>"
359 "var attach = document.getElementsByTagName('script')[0];"
360 "var link = document.createElement('link');"
361 "link.rel = 'stylesheet';"
362 "link.type = 'text/css';"
363 "link.href = 'testAsync.css';"
364 "link.media = 'all';"
365 "attach.appendChild(link);"
366 "</script>"
367 "<div id=\"after\"></div>"
368 "</body></html>");
369
370 testing::runPendingTasks();
371 EXPECT_TRUE(document().getElementById("before"));
372 EXPECT_TRUE(document().getElementById("after"));
373
374 cssAsyncResource.complete("");
375 }
376
377 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/web/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698