View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.host.css;
16  
17  import java.net.URL;
18  
19  import org.htmlunit.WebDriverTestCase;
20  import org.htmlunit.junit.annotation.Alerts;
21  import org.htmlunit.util.MimeType;
22  import org.junit.jupiter.api.Test;
23  import org.openqa.selenium.WebDriver;
24  
25  /**
26   * Tests for {@link CSSImportRule}.
27   *
28   * @author Daniel Gredler
29   * @author Marc Guillemot
30   * @author Ronald Brill
31   * @author Guy Burton
32   * @author Frank Danek
33   */
34  public class CSSImportRuleTest extends WebDriverTestCase {
35  
36      /**
37       * @throws Exception if an error occurs
38       */
39      @Test
40      @Alerts("TypeError")
41      public void ctor() throws Exception {
42          final String html = DOCTYPE_HTML
43              + "<html><body>\n"
44              + LOG_TEXTAREA
45              + "<script>\n"
46              + LOG_TEXTAREA_FUNCTION
47              + "try {\n"
48              + "  var rule = new CSSImportRule();\n"
49              + "  log(rule);\n"
50              + "} catch(e) { logEx(e); }\n"
51              + "</script></body></html>";
52  
53          loadPageVerifyTextArea2(html);
54      }
55  
56      /**
57       * @throws Exception if an error occurs
58       */
59      @Test
60      @Alerts({"[object CSSImportRule]", "[object CSSImportRule]"})
61      public void scriptableToString() throws Exception {
62          final String html = DOCTYPE_HTML
63              + "<html><body>\n"
64  
65              + "<style>\n"
66              + "  @import 'imp.css';\n"
67              + "</style>\n"
68  
69              + "<script>\n"
70              + LOG_TITLE_FUNCTION
71              + "  var styleSheet = document.styleSheets[0];\n"
72              + "  var rule = styleSheet.cssRules[0];\n"
73              + "  log(Object.prototype.toString.call(rule));\n"
74              + "  log(rule);\n"
75              + "</script>\n"
76  
77              + "</body></html>";
78  
79          final String css = "#d { color: green }";
80          getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
81  
82          loadPageVerifyTitle2(html);
83      }
84  
85      /**
86       * @throws Exception if an error occurs
87       */
88      @Test
89      @Alerts("@import url(\"imp.css\");")
90      public void cssText() throws Exception {
91          final String html = DOCTYPE_HTML
92              + "<html><body>\n"
93  
94              + "<style>\n"
95              + "  @import 'imp.css';\n"
96              + "</style>\n"
97  
98              + "<script>\n"
99              + LOG_TITLE_FUNCTION
100             + "  var styleSheet = document.styleSheets[0];\n"
101             + "  var rule = styleSheet.cssRules[0];\n"
102             + "  log(rule.cssText);\n"
103             + "</script>\n"
104 
105             + "</body></html>";
106 
107         final String css = "#d { color: green }";
108         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
109 
110         loadPageVerifyTitle2(html);
111     }
112 
113     /**
114      * @throws Exception if an error occurs
115      */
116     @Test
117     @Alerts("@import url(\"imp.css\");")
118     public void cssTextSet() throws Exception {
119         final String html = DOCTYPE_HTML
120             + "<html><body>\n"
121 
122             + "<style>\n"
123             + "  @import 'imp.css';\n"
124             + "</style>\n"
125 
126             + "<script>\n"
127             + LOG_TITLE_FUNCTION
128             + "  var styleSheet = document.styleSheets[0];\n"
129             + "  var rule = styleSheet.cssRules[0];\n"
130             + "  try {"
131             + "    rule.cssText = '@import \"imp2.css\";';\n"
132             + "    log(rule.cssText);\n"
133             + "  } catch(e) {\n"
134             + "    logEx(e);\n"
135             + "  }\n"
136             + "</script>\n"
137 
138             + "</body></html>";
139 
140         final String css = "#d { color: green }";
141         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
142 
143         loadPageVerifyTitle2(html);
144     }
145 
146     /**
147      * @throws Exception if an error occurs
148      */
149     @Test
150     @Alerts("null")
151     public void parentRule() throws Exception {
152         final String html = DOCTYPE_HTML
153             + "<html><body>\n"
154 
155             + "<style>\n"
156             + "  @import 'imp.css';\n"
157             + "</style>\n"
158 
159             + "<script>\n"
160             + LOG_TITLE_FUNCTION
161             + "  var styleSheet = document.styleSheets[0];\n"
162             + "  var rule = styleSheet.cssRules[0];\n"
163             + "  log(rule.parentRule);\n"
164             + "</script>\n"
165 
166             + "</body></html>";
167 
168         final String css = "#d { color: green }";
169         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
170 
171         loadPageVerifyTitle2(html);
172     }
173 
174     /**
175      * @throws Exception if an error occurs
176      */
177     @Test
178     @Alerts("null")
179     public void parentRuleSet() throws Exception {
180         final String html = DOCTYPE_HTML
181             + "<html><body>\n"
182 
183             + "<style>\n"
184             + "  @import 'imp.css';\n"
185             + "</style>\n"
186 
187             + "<script>\n"
188             + LOG_TITLE_FUNCTION
189             + "  var styleSheet = document.styleSheets[0];\n"
190             + "  var rule = styleSheet.cssRules[0];\n"
191             + "  try {"
192             + "    rule.parentRule = rule;\n"
193             + "    log(rule.parentRule);\n"
194             + "  } catch(e) {\n"
195             + "    logEx(e);\n"
196             + "  }\n"
197             + "</script>\n"
198 
199             + "</body></html>";
200 
201         final String css = "#d { color: green }";
202         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
203 
204         loadPageVerifyTitle2(html);
205     }
206 
207     /**
208      * @throws Exception if an error occurs
209      */
210     @Test
211     @Alerts("[object CSSStyleSheet]")
212     public void parentStyleSheet() throws Exception {
213         final String html = DOCTYPE_HTML
214             + "<html><body>\n"
215 
216             + "<style>\n"
217             + "  @import 'imp.css';\n"
218             + "</style>\n"
219 
220             + "<script>\n"
221             + LOG_TITLE_FUNCTION
222             + "  var styleSheet = document.styleSheets[0];\n"
223             + "  var rule = styleSheet.cssRules[0];\n"
224             + "  log(rule.parentStyleSheet);\n"
225             + "</script>\n"
226 
227             + "</body></html>";
228 
229         final String css = "#d { color: green }";
230         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
231 
232         loadPageVerifyTitle2(html);
233     }
234 
235     /**
236      * @throws Exception if an error occurs
237      */
238     @Test
239     @Alerts("[object CSSStyleSheet]")
240     public void parentStyleSheetSet() throws Exception {
241         final String html = DOCTYPE_HTML
242             + "<html><body>\n"
243 
244             + "<style>\n"
245             + "  @media screen { p { background-color:#FFFFFF; }};\n"
246             + "</style>\n"
247 
248             + "<script>\n"
249             + LOG_TITLE_FUNCTION
250             + "  var styleSheet = document.styleSheets[0];\n"
251             + "  var rule = styleSheet.cssRules[0];\n"
252             + "  try {"
253             + "    rule.parentStyleSheet = null;\n"
254             + "    log(rule.parentStyleSheet);\n"
255             + "  } catch(e) {\n"
256             + "    logEx(e);\n"
257             + "  }\n"
258             + "</script>\n"
259 
260             + "</body></html>";
261 
262         loadPageVerifyTitle2(html);
263     }
264 
265     /**
266      * @throws Exception if an error occurs
267      */
268     @Test
269     @Alerts({"imp.css", "@import url(\"imp.css\");"})
270     public void hrefSimpleRelative() throws Exception {
271         final String html = DOCTYPE_HTML
272             + "<html><body>\n"
273 
274             + "<style>\n"
275             + "  @import  'imp.css';\n"
276             + "</style>\n"
277 
278             + "<script>\n"
279             + LOG_TITLE_FUNCTION
280             + "  var styleSheet = document.styleSheets[0];\n"
281             + "  var rule = styleSheet.cssRules[0];\n"
282             + "  log(rule.href);\n"
283             + "  log(rule.cssText);\n"
284             + "</script>\n"
285 
286             + "</body></html>";
287 
288         final String css = "#d { color: green }";
289         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
290 
291         loadPageVerifyTitle2(html);
292     }
293 
294     /**
295      * @throws Exception if an error occurs
296      */
297     @Test
298     @Alerts({"§§URL§§imp.css", "@import url(\"§§URL§§imp.css\");"})
299     public void hrefSimpleAbsolute() throws Exception {
300         final String html = DOCTYPE_HTML
301             + "<html><body>\n"
302 
303             + "<style>\n"
304             + "  @import  '" + new URL(URL_FIRST, "imp.css").toExternalForm() + "';\n"
305             + "</style>\n"
306 
307             + "<script>\n"
308             + LOG_TITLE_FUNCTION
309             + "  var styleSheet = document.styleSheets[0];\n"
310             + "  var rule = styleSheet.cssRules[0];\n"
311             + "  log(rule.href);\n"
312             + "  log(rule.cssText);\n"
313             + "</script>\n"
314 
315             + "</body></html>";
316 
317         final String css = "#d { color: green }";
318         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
319 
320         expandExpectedAlertsVariables(URL_FIRST);
321         loadPageVerifyTitle2(html);
322     }
323 
324     /**
325      * @throws Exception if an error occurs
326      */
327     @Test
328     @Alerts({"imp.css", "@import url(\"imp.css\");"})
329     public void hrefUrlRelative() throws Exception {
330         final String html = DOCTYPE_HTML
331             + "<html><body>\n"
332 
333             + "<style>\n"
334             + "  @import url( 'imp.css' );\n"
335             + "</style>\n"
336 
337             + "<script>\n"
338             + LOG_TITLE_FUNCTION
339             + "  var styleSheet = document.styleSheets[0];\n"
340             + "  var rule = styleSheet.cssRules[0];\n"
341             + "  log(rule.href);\n"
342             + "  log(rule.cssText);\n"
343             + "</script>\n"
344 
345             + "</body></html>";
346 
347         final String css = "#d { color: green }";
348         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
349 
350         loadPageVerifyTitle2(html);
351     }
352 
353     /**
354      * @throws Exception if an error occurs
355      */
356     @Test
357     @Alerts({"§§URL§§imp.css", "@import url(\"§§URL§§imp.css\");"})
358     public void hrefUrlAbsolute() throws Exception {
359         final String html = DOCTYPE_HTML
360             + "<html><body>\n"
361 
362             + "<style>\n"
363             + "  @import  url('" + new URL(URL_FIRST, "imp.css").toExternalForm() + "');\n"
364             + "</style>\n"
365 
366             + "<script>\n"
367             + LOG_TITLE_FUNCTION
368             + "  var styleSheet = document.styleSheets[0];\n"
369             + "  var rule = styleSheet.cssRules[0];\n"
370             + "  log(rule.href);\n"
371             + "  log(rule.cssText);\n"
372             + "</script>\n"
373 
374             + "</body></html>";
375 
376         final String css = "#d { color: green }";
377         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
378 
379         expandExpectedAlertsVariables(URL_FIRST);
380         loadPageVerifyTitle2(html);
381     }
382 
383     /**
384      * @throws Exception if an error occurs
385      */
386     @Test
387     @Alerts({"[object MediaList]", "", "0", "", "@import url(\"imp.css\");"})
388     public void mediaNone() throws Exception {
389         final String html = DOCTYPE_HTML
390             + "<html><body>\n"
391 
392             + "<style>\n"
393             + "  @import 'imp.css';\n"
394             + "</style>\n"
395 
396             + "<script>\n"
397             + LOG_TITLE_FUNCTION
398             + "  var styleSheet = document.styleSheets[0];\n"
399             + "  var rule = styleSheet.cssRules[0];\n"
400             + "  var mediaList = rule.media;\n"
401             + "  log(Object.prototype.toString.call(mediaList));\n"
402             + "  log(mediaList);\n"
403             + "  log(mediaList.length);\n"
404             + "  for (var i = 0; i < mediaList.length; i++) {\n"
405             + "    log(mediaList.item(i));\n"
406             + "  }\n"
407             + "  log(mediaList.mediaText);\n"
408             + "  log(rule.cssText);\n"
409             + "</script>\n"
410 
411             + "</body></html>";
412 
413         final String css = "#d { color: green }";
414         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
415 
416         loadPageVerifyTitle2(html);
417     }
418 
419     /**
420      * @throws Exception if an error occurs
421      */
422     @Test
423     @Alerts({"[object MediaList]", "all", "1", "all", "all", "@import url(\"imp.css\") all;"})
424     public void mediaAll() throws Exception {
425         final String html = DOCTYPE_HTML
426             + "<html><body>\n"
427 
428             + "<style>\n"
429             + "  @import 'imp.css' all;\n"
430             + "</style>\n"
431 
432             + "<script>\n"
433             + LOG_TITLE_FUNCTION
434             + "  var styleSheet = document.styleSheets[0];\n"
435             + "  var rule = styleSheet.cssRules[0];\n"
436             + "  var mediaList = rule.media;\n"
437             + "  log(Object.prototype.toString.call(mediaList));\n"
438             + "  log(mediaList);\n"
439             + "  log(mediaList.length);\n"
440             + "  for (var i = 0; i < mediaList.length; i++) {\n"
441             + "    log(mediaList.item(i));\n"
442             + "  }\n"
443             + "  log(mediaList.mediaText);\n"
444             + "  log(rule.cssText);\n"
445             + "</script>\n"
446 
447             + "</body></html>";
448 
449         final String css = "#d { color: green }";
450         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
451 
452         loadPageVerifyTitle2(html);
453     }
454 
455     /**
456      * @throws Exception if an error occurs
457      */
458     @Test
459     @Alerts({"[object MediaList]", "screen", "1", "screen", "screen", "@import url(\"imp.css\") screen;"})
460     public void media() throws Exception {
461         final String html = DOCTYPE_HTML
462             + "<html><body>\n"
463 
464             + "<style>\n"
465             + "  @import 'imp.css' screen;\n"
466             + "</style>\n"
467 
468             + "<script>\n"
469             + LOG_TITLE_FUNCTION
470             + "  var styleSheet = document.styleSheets[0];\n"
471             + "  var rule = styleSheet.cssRules[0];\n"
472             + "  var mediaList = rule.media;\n"
473             + "  log(Object.prototype.toString.call(mediaList));\n"
474             + "  log(mediaList);\n"
475             + "  log(mediaList.length);\n"
476             + "  for (var i = 0; i < mediaList.length; i++) {\n"
477             + "    log(mediaList.item(i));\n"
478             + "  }\n"
479             + "  log(mediaList.mediaText);\n"
480             + "  log(rule.cssText);\n"
481             + "</script>\n"
482 
483             + "</body></html>";
484 
485         final String css = "#d { color: green }";
486         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
487 
488         loadPageVerifyTitle2(html);
489     }
490 
491     /**
492      * @throws Exception if an error occurs
493      */
494     @Test
495     @Alerts({"2", "only screen and (color)", "print and (max-width: 12cm) and (min-width: 30em)",
496              "only screen and (color), print and (max-width: 12cm) and (min-width: 30em)",
497              "@import url(\"imp.css\") only screen and (color), "
498                                + "print and (max-width: 12cm) and (min-width: 30em);"})
499     public void mediaQuery() throws Exception {
500         final String html = DOCTYPE_HTML
501             + "<html><body>\n"
502 
503             + "<style>\n"
504             + "  @import 'imp.css' only screen and  (color ),print and ( max-width:12cm) and (min-width: 30em);\n"
505             + "</style>\n"
506 
507             + "<script>\n"
508             + LOG_TITLE_FUNCTION
509             + "  var styleSheet = document.styleSheets[0];\n"
510             + "  var rule = styleSheet.cssRules[0];\n"
511             + "  var mediaList = rule.media;\n"
512             + "  log(mediaList.length);\n"
513             + "  for (var i = 0; i < mediaList.length; i++) {\n"
514             + "    log(mediaList.item(i));\n"
515             + "  }\n"
516             + "  log(mediaList.mediaText);\n"
517             + "  log(rule.cssText);\n"
518             + "</script>\n"
519 
520             + "</body></html>";
521 
522         final String css = "#d { color: green }";
523         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
524 
525         loadPageVerifyTitle2(html);
526     }
527 
528     /**
529      * @throws Exception if an error occurs
530      */
531     @Test
532     @Alerts({"[object HTMLStyleElement]", "[object CSSStyleSheet]", "§§URL§§imp.css",
533              "null", "div { color: green; }"})
534     public void styleSheet() throws Exception {
535         final String html = DOCTYPE_HTML
536             + "<html><body>\n"
537 
538             + "<style>\n"
539             + "  @import 'imp.css';\n"
540             + "</style>\n"
541 
542             + "<script>\n"
543             + LOG_TITLE_FUNCTION
544             + "  var styleSheet = document.styleSheets[0];\n"
545             + "  log(styleSheet.ownerNode);\n"
546             + "  var rule = styleSheet.cssRules[0];\n"
547             + "  log(rule.styleSheet);\n"
548             + "  log(rule.styleSheet.href);\n"
549             + "  log(rule.styleSheet.ownerNode);\n"
550             + "  log(rule.styleSheet.cssRules[0].cssText);\n"
551             + "</script>\n"
552 
553             + "</body></html>";
554 
555         final String css = "div { color: green }";
556         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
557 
558         expandExpectedAlertsVariables(URL_FIRST);
559         loadPageVerifyTitle2(html);
560     }
561 
562     /**
563      * @throws Exception if an error occurs
564      */
565     @Test
566     @Alerts({"[object HTMLStyleElement]", "[object CSSStyleSheet]", "§§URL§§imp.css",
567              "[object CSSRuleList]", "null", "0"})
568     public void styleSheetNotAvailable() throws Exception {
569         final String html = DOCTYPE_HTML
570             + "<html><body>\n"
571 
572             + "<style>\n"
573             + "  @import 'imp.css';\n"
574             + "</style>\n"
575 
576             + "<script>\n"
577             + LOG_TITLE_FUNCTION
578             + "  var styleSheet = document.styleSheets[0];\n"
579             + "  log(styleSheet.ownerNode);\n"
580             + "  var rule = styleSheet.cssRules[0];\n"
581             + "  log(rule.styleSheet);\n"
582             + "  log(rule.styleSheet.href);\n"
583             + "  log(rule.styleSheet.cssRules);\n"
584             + "  log(rule.styleSheet.ownerNode);\n"
585             + "  log(rule.styleSheet.cssRules.length);\n"
586             + "</script>\n"
587 
588             + "</body></html>";
589 
590         expandExpectedAlertsVariables(URL_FIRST);
591         loadPageVerifyTitle2(html);
592     }
593 
594     /**
595      * @throws Exception if an error occurs
596      */
597     @Test
598     @Alerts({"[object CSSStyleSheet]", "§§URL§§imp.css", "div { color: green; }"})
599     public void styleSheetMediaNotMatching() throws Exception {
600         final String html = DOCTYPE_HTML
601             + "<html><body>\n"
602 
603             + "<style>\n"
604             + "  @import 'imp.css' print;\n"
605             + "</style>\n"
606 
607             + "<script>\n"
608             + LOG_TITLE_FUNCTION
609             + "  var styleSheet = document.styleSheets[0];\n"
610             + "  var rule = styleSheet.cssRules[0];\n"
611             + "  log(rule.styleSheet);\n"
612             + "  log(rule.styleSheet.href);\n"
613             + "  log(rule.styleSheet.cssRules[0].cssText);\n"
614             + "</script>\n"
615 
616             + "</body></html>";
617 
618         final String css = "div { color: green }";
619         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
620 
621         expandExpectedAlertsVariables(URL_FIRST);
622         loadPageVerifyTitle2(html);
623     }
624 
625 
626     /**
627      * @throws Exception if an error occurs
628      */
629     @Test
630     @Alerts("true")
631     public void styleSheetSameObject() throws Exception {
632         final String html = DOCTYPE_HTML
633             + "<html><body>\n"
634 
635             + "<style>\n"
636             + "  @import 'imp.css' print;\n"
637             + "</style>\n"
638 
639             + "<script>\n"
640             + LOG_TITLE_FUNCTION
641             + "  var styleSheet = document.styleSheets[0];\n"
642             + "  var rule = styleSheet.cssRules[0];\n"
643             + "  var sheet = rule.styleSheet;\n"
644             + "  log(rule.styleSheet === sheet);\n"
645             + "</script>\n"
646 
647             + "</body></html>";
648 
649         final String css = "div { color: green }";
650         getMockWebConnection().setResponse(new URL(URL_FIRST, "imp.css"), css, MimeType.TEXT_CSS);
651 
652         expandExpectedAlertsVariables(URL_FIRST);
653         loadPageVerifyTitle2(html);
654     }
655 
656     /**
657      * Regression test for Bug #789.
658      * @throws Exception if an error occurs
659      */
660     @Test
661     @Alerts({"[object CSSImportRule]", "§§URL§§second/", "", "0", "[object CSSStyleSheet]"})
662     public void getImportFromCssRulesCollection_absolute() throws Exception {
663         expandExpectedAlertsVariables(URL_FIRST);
664         getImportFromCssRulesCollection(URL_FIRST, URL_SECOND.toExternalForm(), URL_SECOND);
665     }
666 
667     /**
668      * Regression test for Bug #789.
669      * @throws Exception if an error occurs
670      */
671     @Test
672     @Alerts({"[object CSSImportRule]", "foo.css", "", "0", "[object CSSStyleSheet]"})
673     public void getImportFromCssRulesCollection_relative() throws Exception {
674         final URL urlPage = new URL(URL_FIRST, "/dir1/dir2/foo.html");
675         final URL urlCss = new URL(URL_FIRST, "/dir1/dir2/foo.css");
676         getImportFromCssRulesCollection(urlPage, "foo.css", urlCss);
677     }
678 
679     private void getImportFromCssRulesCollection(final URL pageUrl, final String cssRef, final URL cssUrl)
680         throws Exception {
681         final String html = DOCTYPE_HTML
682             + "<html><body>\n"
683             + "<style>@import url('" + cssRef + "');</style><div id='d'>foo</div>\n"
684             + "<script>\n"
685             + LOG_TITLE_FUNCTION
686             + "  var item = document.styleSheets.item(0);\n"
687             + "  if (item.cssRules) {\n"
688             + "    var r = item.cssRules[0];\n"
689             + "    log(r);\n"
690             + "    log(r.href);\n"
691             + "    log(r.media);\n"
692             + "    log(r.media.length);\n"
693             + "    log(r.styleSheet);\n"
694             + "  } else {\n"
695             + "    log('cssRules undefined');\n"
696             + "  }\n"
697             + "</script>\n"
698             + "</body></html>";
699         final String css = "#d { color: green }";
700 
701         getMockWebConnection().setResponse(cssUrl, css, MimeType.TEXT_CSS);
702 
703         final WebDriver driver = loadPage2(html, pageUrl);
704         verifyTitle2(driver, getExpectedAlerts());
705     }
706 
707     /**
708      * @throws Exception if an error occurs
709      */
710     @Test
711     @Alerts("true")
712     public void importedStylesheetsLoaded() throws Exception {
713         final String html = DOCTYPE_HTML
714             + "<html><body>\n"
715             + "<style>@import url('" + URL_SECOND + "');</style>\n"
716             + "<div id='d'>foo</div>\n"
717             + "<script>\n"
718             + LOG_TITLE_FUNCTION
719             + "var d = document.getElementById('d');\n"
720             + "var s = window.getComputedStyle(d, null);\n"
721             + "log(s.color.indexOf('128') > 0);\n"
722             + "</script>\n"
723             + "</body></html>";
724         final String css = "#d { color: rgb(0, 128, 0); }";
725 
726         getMockWebConnection().setResponse(URL_SECOND, css, MimeType.TEXT_CSS);
727 
728         loadPageVerifyTitle2(html);
729     }
730 
731     /**
732      * @throws Exception if an error occurs
733      */
734     @Test
735     @Alerts("true")
736     public void importedStylesheetsURLResolution() throws Exception {
737         final String html = DOCTYPE_HTML
738             + "<html><head>\n"
739             + "<link rel='stylesheet' type='text/css' href='dir1/dir2/file1.css'></link>\n"
740             + "<body>\n"
741             + "<div id='d'>foo</div>\n"
742             + "<script>\n"
743             + LOG_TITLE_FUNCTION
744             + "var d = document.getElementById('d');\n"
745             + "var s = window.getComputedStyle(d, null);\n"
746             + "log(s.color.indexOf('128') > 0);\n"
747             + "</script>\n"
748             + "</body></html>";
749         final String css1 = "@import url('file2.css');";
750         final String css2 = "#d { color: rgb(0, 128, 0); }";
751 
752         final URL urlPage = URL_FIRST;
753         final URL urlCss1 = new URL(urlPage, "dir1/dir2/file1.css");
754         final URL urlCss2 = new URL(urlPage, "dir1/dir2/file2.css");
755         getMockWebConnection().setResponse(urlCss1, css1, MimeType.TEXT_CSS);
756         getMockWebConnection().setResponse(urlCss2, css2, MimeType.TEXT_CSS);
757 
758         final WebDriver driver = loadPage2(html, urlPage);
759         verifyTitle2(driver, getExpectedAlerts());
760     }
761 
762     /**
763      * @throws Exception if an error occurs
764      */
765     @Test
766     @Alerts("true")
767     public void circularImportedStylesheets() throws Exception {
768         final String html = DOCTYPE_HTML
769             + "<html><head>\n"
770             + "<link rel='stylesheet' type='text/css' href='dir1/dir2/file1.css'></link>\n"
771             + "<body>\n"
772             + "<div id='d'>foo</div>\n"
773             + "<script>\n"
774             + LOG_TITLE_FUNCTION
775             + "  var d = document.getElementById('d');\n"
776             + "  var s = window.getComputedStyle(d, null);\n"
777             + "  log(s.color.indexOf('128') > 0);\n"
778             + "</script>\n"
779             + "</body></html>";
780 
781         final String css1 = "@import url('file2.css');";
782         final String css2 = "@import url('file1.css');\n"
783             + "#d { color: rgb(0, 128, 0); }";
784 
785         final URL urlPage = URL_FIRST;
786         final URL urlCss1 = new URL(urlPage, "dir1/dir2/file1.css");
787         final URL urlCss2 = new URL(urlPage, "dir1/dir2/file2.css");
788         getMockWebConnection().setResponse(urlCss1, css1, MimeType.TEXT_CSS);
789         getMockWebConnection().setResponse(urlCss2, css2, MimeType.TEXT_CSS);
790 
791         final WebDriver driver = loadPage2(html, urlPage);
792         verifyTitle2(driver, getExpectedAlerts());
793     }
794 
795     /**
796      * @throws Exception if an error occurs
797      */
798     @Test
799     @Alerts({"true", "true", "true"})
800     public void circularImportedStylesheetsComplexCase() throws Exception {
801         final String html = DOCTYPE_HTML
802             + "<html><head>\n"
803             + "<link rel='stylesheet' type='text/css' href='dir1/dir2/file1.css'></link>\n"
804             + "<body>\n"
805             + "<div id='d'>foo</div>\n"
806             + "<div id='e'>foo</div>\n"
807             + "<div id='f'>foo</div>\n"
808             + "<script>\n"
809             + LOG_TITLE_FUNCTION
810             + "var d = document.getElementById('d');\n"
811             + "var s = window.getComputedStyle(d, null);\n"
812             + "log(s.color.indexOf('128') > 0);\n"
813             + "var e = document.getElementById('e');\n"
814             + "s = window.getComputedStyle(e, null);\n"
815             + "log(s.color.indexOf('127') > 0);\n"
816             + "var f = document.getElementById('f');\n"
817             + "s = window.getComputedStyle(f, null);\n"
818             + "log(s.color.indexOf('126') > 0);\n"
819             + "</script>\n"
820             + "</body></html>";
821         final String css1 = "@import url('file2.css');";
822         final String css2 = "@import url('file3.css');\n"
823             + "@import url('file4.css');";
824         final String css3 = "#d { color: rgb(0, 128, 0); }";
825         final String css4 = "@import url('file5.css');\n"
826             + "#e { color: rgb(0, 127, 0); }";
827         final String css5 = "@import url('file2.css');\n"
828             + "#f { color: rgb(0, 126, 0); }";
829 
830         final URL urlPage = URL_FIRST;
831         final URL urlCss1 = new URL(urlPage, "dir1/dir2/file1.css");
832         final URL urlCss2 = new URL(urlPage, "dir1/dir2/file2.css");
833         final URL urlCss3 = new URL(urlPage, "dir1/dir2/file3.css");
834         final URL urlCss4 = new URL(urlPage, "dir1/dir2/file4.css");
835         final URL urlCss5 = new URL(urlPage, "dir1/dir2/file5.css");
836         getMockWebConnection().setResponse(urlCss1, css1, MimeType.TEXT_CSS);
837         getMockWebConnection().setResponse(urlCss2, css2, MimeType.TEXT_CSS);
838         getMockWebConnection().setResponse(urlCss3, css3, MimeType.TEXT_CSS);
839         getMockWebConnection().setResponse(urlCss4, css4, MimeType.TEXT_CSS);
840         getMockWebConnection().setResponse(urlCss5, css5, MimeType.TEXT_CSS);
841 
842         final WebDriver driver = loadPage2(html, urlPage);
843         verifyTitle2(driver, getExpectedAlerts());
844     }
845 
846     /**
847      * Test that media specific imports work correctly.
848      * Should import the first stylesheet and not the second
849      * @throws Exception if an error occurs
850      */
851     @Test
852     @Alerts("42px")
853     public void importedStylesheetsLoadedAccordingToMediaType() throws Exception {
854         final String html = DOCTYPE_HTML
855             + "<html><head>\n"
856             + "  <style>\n"
857             + "    @import url('" + URL_SECOND  + "');\n"
858             + "    @import url('" + URL_THIRD + "') print;\n"
859             + "  </style>\n"
860             + "</head>\n"
861 
862             + "<body>\n"
863             + "  <div id='d'>foo</div>\n"
864             + "  <script>\n"
865             + LOG_TITLE_FUNCTION
866             + "    var d = document.getElementById('d');\n"
867             + "    var s = window.getComputedStyle(d, null);\n"
868             + "    log(s.fontSize);\n"
869             + "</script>\n"
870             + "</body></html>";
871         final String screenCss = "#d { font-size: 42px; }";
872         final String printCss  = "#d { font-size: 13px; }";
873 
874         getMockWebConnection().setResponse(URL_SECOND, screenCss, MimeType.TEXT_CSS);
875         getMockWebConnection().setResponse(URL_THIRD, printCss, MimeType.TEXT_CSS);
876 
877         loadPageVerifyTitle2(html);
878     }
879 }