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.html;
16  
17  import static java.nio.charset.StandardCharsets.ISO_8859_1;
18  import static java.nio.charset.StandardCharsets.UTF_8;
19  
20  import java.net.URL;
21  import java.util.ArrayList;
22  import java.util.Map;
23  
24  import org.apache.commons.io.ByteOrderMark;
25  import org.htmlunit.HttpHeader;
26  import org.htmlunit.WebDriverTestCase;
27  import org.htmlunit.http.HttpStatus;
28  import org.htmlunit.junit.annotation.Alerts;
29  import org.htmlunit.junit.annotation.HtmlUnitNYI;
30  import org.htmlunit.util.MimeType;
31  import org.htmlunit.util.NameValuePair;
32  import org.junit.jupiter.api.Test;
33  import org.openqa.selenium.By;
34  import org.openqa.selenium.WebDriver;
35  
36  /**
37   * Tests for {@link HtmlScript}, but as WebDriverTestCase.
38   *
39   * @author Marc Guillemot
40   * @author Daniel Gredler
41   * @author Ahmed Ashour
42   * @author Ronald Brill
43   * @author Daniel Wagner-Hall
44   * @author Frank Danek
45   */
46  public class HtmlScript2Test extends WebDriverTestCase {
47  
48      /**
49       * @throws Exception on test failure
50       */
51      @Test
52      @Alerts("myValue")
53      public void insertBefore() throws Exception {
54          final String html = DOCTYPE_HTML
55              + "<html><head>\n"
56              + "<script>\n"
57              + LOG_TITLE_FUNCTION
58              + "  function test() {\n"
59              + "    var script = document.createElement('script');\n"
60              + "    script.text = \"foo = 'myValue';\";\n"
61              + "    document.body.insertBefore(script, document.body.firstChild);\n"
62              + "    log(foo);\n"
63              + "  }\n"
64              + "</script>\n"
65              + "</head>\n"
66              + "<body onload='test()'></body>\n"
67              + "</html>";
68  
69          loadPageVerifyTitle2(html);
70      }
71  
72      /**
73       * @throws Exception if an error occurs
74       */
75      @Test
76      @Alerts({"created", "hello", "replaced"})
77      public void addedFromDocumentFragment() throws Exception {
78          final String html = DOCTYPE_HTML
79              + "<html><body>\n"
80              + "<span id='A'></span>\n"
81              + "<script>\n"
82              + LOG_TITLE_FUNCTION
83              + "var text = '<script>log(\"hello\");</sc' + 'ript>';\n"
84              + "var element = document.getElementById('A');\n"
85              + "try {\n"
86              + "  var range = element.ownerDocument.createRange();\n"
87              + "  range.selectNode(element);\n"
88              + "  var fragment = range.createContextualFragment(text);\n"
89              + "  log('created');\n"
90              + "  element.parentNode.replaceChild(fragment, element);\n"
91              + "  log('replaced');\n"
92              + "} catch(e) { logEx(e); }\n"
93              + "</script></body></html>";
94  
95          loadPageVerifyTitle2(html);
96      }
97  
98      /**
99       * @throws Exception if the test fails
100      */
101     @Test
102     @Alerts("[object HTMLScriptElement]")
103     public void simpleScriptable() throws Exception {
104         final String html = DOCTYPE_HTML
105             + "<html><head>\n"
106             + "<script>\n"
107             + LOG_TITLE_FUNCTION
108             + "  function test() {\n"
109             + "    log(document.getElementById('myId'));\n"
110             + "  }\n"
111             + "</script>\n"
112             + "</head><body onload='test()'>\n"
113             + "  <script id='myId'></script>\n"
114             + "</body></html>";
115 
116         final WebDriver driver = loadPageVerifyTitle2(html);
117         assertEquals("script", driver.findElement(By.id("myId")).getTagName());
118     }
119 
120     /**
121      * @exception Exception If the test fails
122      */
123     @Test
124     @Alerts("Hello")
125     public void type_case_sensitivity() throws Exception {
126         final String html = DOCTYPE_HTML
127             + "<html>\n"
128             + "<body>\n"
129             + "  <script type='text/JavaScript'>\n"
130             + LOG_TITLE_FUNCTION
131             + "    log('Hello');\n"
132             + "  </script>\n"
133             + "</body></html>";
134 
135         loadPageVerifyTitle2(html);
136     }
137 
138     /**
139      * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#JavaScript_types.
140      * @exception Exception If the test fails
141      */
142     @Test
143     @Alerts({"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G"})
144     public void typeValues() throws Exception {
145         final String html = DOCTYPE_HTML
146             + "<html>"
147             + "<head>\n"
148             + "<script>\n"
149             + LOG_TITLE_FUNCTION
150             + "</script>\n"
151             + "</head>\n"
152             + "<body>\n"
153             + "  <script type='application/javascript'>log('1');</script>\n"
154             + "  <script type='application/ecmascript'>log('2');</script>\n"
155             + "  <script type='application/x-ecmascript'>log('3');</script>\n"
156             + "  <script type='application/x-javascript'>log('4');</script>\n"
157             + "  <script type='text/javascript'>log('5');</script>\n"
158             + "  <script type='text/ecmascript'>log('6');</script>\n"
159             + "  <script type='text/javascript1.0'>log('7');</script>\n"
160             + "  <script type='text/javascript1.1'>log('8');</script>\n"
161             + "  <script type='text/javascript1.2'>log('9');</script>\n"
162             + "  <script type='text/javascript1.3'>log('A');</script>\n"
163             + "  <script type='text/javascript1.4'>log('B');</script>\n"
164             + "  <script type='text/javascript1.5'>log('C');</script>\n"
165             + "  <script type='text/jscript'>log('D');</script>\n"
166             + "  <script type='text/livescript'>log('E');</script>\n"
167             + "  <script type='text/x-ecmascript'>log('F');</script>\n"
168             + "  <script type='text/x-javascript'>log('G');</script>\n"
169             + "</body></html>";
170 
171         loadPageVerifyTitle2(html);
172     }
173 
174     /**
175      * @exception Exception If the test fails
176      */
177     @Test
178     @Alerts({"1", "5", "7"})
179     public void type_language() throws Exception {
180         final String html = DOCTYPE_HTML
181             + "<html>\n"
182             + "<head>\n"
183             + "<script>\n"
184             + LOG_TITLE_FUNCTION
185             + "</script>\n"
186             + "</head>\n"
187             + "<body>\n"
188             + "  <script>\n"
189             + "    log('1');\n"
190             + "  </script>\n"
191             + "  <script language='anything'>\n"
192             + "    log('2');\n"
193             + "  </script>\n"
194             + "  <script type='anything'>\n"
195             + "    log('3');\n"
196             + "  </script>\n"
197             + "  <script language='anything' type='anything'>\n"
198             + "    log('4');\n"
199             + "  </script>\n"
200             + "  <script language='anything' type='text/javascript'>\n"
201             + "    log('5');\n"
202             + "  </script>\n"
203             + "  <script language='javascript' type='anything'>\n"
204             + "    log('6');\n"
205             + "  </script>\n"
206             + "  <script language='javascript'>\n"
207             + "    log('7');\n"
208             + "  </script>\n"
209             + "</body></html>";
210 
211         loadPageVerifyTitle2(html);
212     }
213 
214     /**
215      * Verifies that a script element is not run when it is cloned.
216      * See bug #469.
217      * @throws Exception if an error occurs
218      */
219     @Test
220     @Alerts("a")
221     public void scriptIsNotRunWhenCloned() throws Exception {
222         final String html = DOCTYPE_HTML
223             + "<html>\n"
224             + "<head>\n"
225             + "<script>\n"
226             + LOG_TITLE_FUNCTION
227             + "</script>\n"
228             + "</head>\n"
229             + "<body onload='document.body.cloneNode(true)'>\n"
230             + "<script>log('a')</script></body></html>";
231 
232         loadPageVerifyTitle2(html);
233     }
234 
235     /**
236      * @throws Exception if an error occurs
237      */
238     @Test
239     @Alerts({"deferred", "start", "dcl listener added", "end", "dcLoaded", "onload"})
240     public void deferInline() throws Exception {
241         final String html = DOCTYPE_HTML
242             + "<html>\n"
243             + "<head>\n"
244             + "  <script>\n"
245             + LOG_TITLE_FUNCTION
246             + "  </script>\n"
247             + "  <script defer>log('deferred')</script>\n"
248             + "  <script>log('start')</script>"
249             + "  <script>\n"
250             + "    document.addEventListener('DOMContentLoaded', function(event) { log('dcLoaded') });\n"
251             + "    log('dcl listener added')</script>"
252             + "  </script>\n"
253             + "</head>\n"
254             + "<body onload='log(\"onload\")'>\n"
255             + "</body>\n"
256             + "<script>log('end')</script>\n"
257             + "</html>";
258 
259         loadPageVerifyTitle2(html);
260     }
261 
262     /**
263      * @throws Exception if an error occurs
264      */
265     @Test
266     @Alerts({"start", "dcl listener added", "end", "deferred-1", "deferred-2", "deferred-3", "dcLoaded", "onload"})
267     public void deferExternal() throws Exception {
268         final String html = DOCTYPE_HTML
269             + "<html>\n"
270             + "<head>\n"
271             + "  <script>\n"
272             + LOG_TITLE_FUNCTION
273             + "  </script>\n"
274             + "  <script defer src='script1.js'></script>\n"
275             + "  <script>log('start')</script>"
276             + "  <script>\n"
277             + "    document.addEventListener('DOMContentLoaded', function(event) { log('dcLoaded') });\n"
278             + "    log('dcl listener added')</script>"
279             + "  </script>\n"
280             + "  <script defer src='script2.js'></script>\n"
281             + "</head>\n"
282             + "<body onload='log(\"onload\")'>\n"
283             + "  <div id='abc'>Test</div>\n"
284             + "</body>\n"
285             + "<script defer src='script3.js'></script>\n"
286             + "<script>log('end')</script>\n"
287             + "</html>";
288 
289         getMockWebConnection().setResponse(new URL(URL_FIRST, "script1.js"), "log('deferred-1');");
290         getMockWebConnection().setResponse(new URL(URL_FIRST, "script2.js"), "log('deferred-2');");
291         getMockWebConnection().setResponse(new URL(URL_FIRST, "script3.js"), "log('deferred-3');");
292 
293         loadPageVerifyTitle2(html);
294     }
295 
296 
297     /**
298      * @throws Exception if an error occurs
299      */
300     @Test
301     @Alerts(DEFAULT = {"dcl listener added", "head-end", "end",
302                        "deferred-2", "deferred-1", "deferred-3", "dcLoaded", "onload"},
303             CHROME = {"dcl listener added", "head-end", "end",
304                       "deferred-1", "deferred-3", "dcLoaded", "deferred-2", "onload"},
305             EDGE = {"dcl listener added", "head-end", "end",
306                     "deferred-1", "deferred-3", "dcLoaded", "deferred-2", "onload"})
307     @HtmlUnitNYI(CHROME = {"dcl listener added", "head-end", "end",
308                            "deferred-1", "deferred-2", "deferred-3", "dcLoaded", "onload"},
309             EDGE = {"dcl listener added", "head-end", "end",
310                     "deferred-1", "deferred-2", "deferred-3", "dcLoaded", "onload"},
311             FF = {"dcl listener added", "head-end", "end",
312                   "deferred-1", "deferred-2", "deferred-3", "dcLoaded", "onload"},
313             FF_ESR = {"dcl listener added", "head-end", "end",
314                       "deferred-1", "deferred-2", "deferred-3", "dcLoaded", "onload"})
315     public void deferDynamicExternal() throws Exception {
316         final String html = DOCTYPE_HTML
317             + "<html>\n"
318             + "<head>\n"
319             + "  <script>\n"
320             + LOG_TITLE_FUNCTION
321             + "    document.addEventListener('DOMContentLoaded', function(event) { log('dcLoaded') });\n"
322             + "    log('dcl listener added')</script>"
323             + "  </script>\n"
324             + "  <script defer src='script1.js'></script>\n"
325             + "  <script>\n"
326             + "    head = document.getElementsByTagName('head')[0];\n"
327 
328             + "    script = document.createElement('script');\n"
329             + "    script.setAttribute('defer', 'defer');\n"
330             + "    script.setAttribute('src', 'script2.js');\n"
331             + "    head.appendChild(script);\n"
332             + "  </script>\n"
333             + "  <script defer src='script3.js'></script>\n"
334             + "  <script>log('head-end')</script>\n"
335             + "</head>\n"
336             + "<body onload='log(\"onload\")'>\n"
337             + "  <div id='abc'>Test</div>\n"
338             + "</body>\n"
339             + "<script>log('end')</script>\n"
340             + "</html>";
341 
342         getMockWebConnection().setResponse(new URL(URL_FIRST, "script1.js"), "log('deferred-1');");
343         getMockWebConnection().setResponse(new URL(URL_FIRST, "script2.js"), "log('deferred-2');");
344         getMockWebConnection().setResponse(new URL(URL_FIRST, "script3.js"), "log('deferred-3');");
345 
346         loadPageVerifyTitle2(html);
347     }
348 
349     /**
350      * @throws Exception if an error occurs
351      */
352     @Test
353     @Alerts({"end", "s0 6", "5", "deferred-1", "deferred-2", "deferred-3", "onload"})
354     public void deferRemovesScript() throws Exception {
355         final String html = DOCTYPE_HTML
356             + "<html>\n"
357             + "<head>\n"
358             + "  <script>\n"
359             + LOG_TITLE_FUNCTION
360             + "  </script>\n"
361             + "  <script defer id='s0' src='script0.js'></script>\n"
362             + "  <script defer id='s1' src='script1.js'></script>\n"
363             + "  <script defer id='s2' src='script2.js'></script>\n"
364             + "  <script defer id='s3' src='script3.js'></script>\n"
365             + "</head>\n"
366             + "<body onload='log(\"onload\")'>\n"
367             + "</body>\n"
368             + "<script>log('end')</script>\n"
369             + "</html>";
370 
371         getMockWebConnection().setResponse(new URL(URL_FIRST, "script0.js"),
372                 "log('s0 ' + document.getElementsByTagName('script').length);\n"
373                 + "var scr = document.getElementById('s3');\n"
374                 + "scr.parentNode.removeChild(scr);\n"
375                 + " log(document.getElementsByTagName('script').length);\n");
376         getMockWebConnection().setResponse(new URL(URL_FIRST, "script1.js"), "log('deferred-1');");
377         getMockWebConnection().setResponse(new URL(URL_FIRST, "script2.js"), "log('deferred-2');");
378         getMockWebConnection().setResponse(new URL(URL_FIRST, "script3.js"), "log('deferred-3');");
379 
380         loadPageVerifyTitle2(html);
381     }
382 
383     /**
384      * Regression test for replaceChild.
385      * @throws Exception if the test fails
386      */
387     @Test
388     @Alerts({"false", "false"})
389     public void appendChild_newIdAndScriptAddedInOnce() throws Exception {
390         final String html = DOCTYPE_HTML
391             + "<html><body>\n"
392             + "<script>\n"
393             + LOG_TITLE_FUNCTION
394             + "  var div1 = document.createElement('div');\n"
395             + "  div1.id = 'div1';\n"
396             + "  var script = document.createElement('script');\n"
397             + "  script.text = 'log(document.getElementById(\"div1\") == null)';\n"
398             + "  div1.appendChild(script);\n"
399             + "  document.body.appendChild(div1);\n"
400             + "  log(document.getElementById('div1') == null);\n"
401             + "</script>\n"
402             + "</body></html>";
403 
404         loadPageVerifyTitle2(html);
405     }
406 
407     /**
408      * @throws Exception if an error occurs
409      */
410     @Test
411     @Alerts({"1", "2"})
412     public void executesMultipleTextNodes() throws Exception {
413         final String html = DOCTYPE_HTML
414             + "<html><body>\n"
415             + "<script>\n"
416             + LOG_TITLE_FUNCTION
417             + "  var script = document.createElement('script');\n"
418             + "  try {\n"
419             + "    script.appendChild(document.createTextNode('log(\"1\");'));\n"
420             + "    script.appendChild(document.createTextNode('log(\"2\");'));\n"
421             + "  } catch(e) {\n"
422             + "    script.text = 'log(\"1\");log(\"2\");';\n"
423             + "  }\n"
424             + "  document.body.appendChild(script);\n"
425             + "</script>\n"
426             + "</body></html>";
427 
428         loadPageVerifyTitle2(html);
429     }
430 
431     /**
432      * @throws Exception if an error occurs
433      */
434     @Test
435     @Alerts("var x=1;x=2;")
436     public void getTextMultipleTextNodes() throws Exception {
437         final String html = DOCTYPE_HTML
438             + "<html><body>\n"
439             + "<script>\n"
440             + LOG_TITLE_FUNCTION
441             + "  var script = document.createElement('script');\n"
442             + "  try {\n"
443             + "  script.appendChild(document.createTextNode('var x=1;'));\n;\n"
444             + "  script.appendChild(document.createTextNode('x=2;'));\n;\n"
445             + "  } catch(e) {\n"
446             + "    script.text = 'var x=1;x=2;';\n;\n"
447             + "  }\n"
448             + "  document.body.appendChild(script);\n"
449             + "  log(script.text);\n"
450             + "</script>\n"
451             + "</body></html>";
452 
453         loadPageVerifyTitle2(html);
454     }
455 
456     /**
457      * @throws Exception if an error occurs
458      */
459     @Test
460     @Alerts("3")
461     public void setTextMultipleTextNodes() throws Exception {
462         final String html = DOCTYPE_HTML
463             + "<html><body>\n"
464             + "<script>\n"
465             + LOG_TITLE_FUNCTION
466             + "  try {\n"
467             + "    var script = document.createElement('script');\n"
468             + "    script.appendChild(document.createTextNode('log(\"1\");'));\n"
469             + "    script.appendChild(document.createTextNode('log(\"2\");'));\n"
470             + "    script.text = 'log(\"3\");';\n"
471             + "    document.body.appendChild(script);\n"
472             + "  } catch(e) {logEx(e);}\n"
473             + "</script>\n"
474             + "</body></html>";
475 
476         loadPageVerifyTitle2(html);
477     }
478 
479     /**
480      * Verifies that setting a script's <tt>src</tt> attribute behaves correctly.
481      * @throws Exception if an error occurs
482      */
483     @Test
484     @Alerts({"1", "2", "3"})
485     public void settingSrcAttribute() throws Exception {
486         final String html = DOCTYPE_HTML
487             + "<html>\n"
488             + "  <head>\n"
489             + "    <script>\n"
490             + LOG_TITLE_FUNCTION
491             + "    </script>\n"
492             + "    <script id='a'></script>\n"
493             + "    <script id='b'>log('1');</script>\n"
494             + "    <script id='c' src='script2.js'></script>\n"
495             + "    <script>\n"
496             + "      function test() {\n"
497             + "        document.getElementById('a').src = 'script3.js';\n"
498             + "        document.getElementById('b').src = 'script4.js';\n"
499             + "        document.getElementById('c').src = 'script5.js';\n"
500             + "      }\n"
501             + "    </script>\n"
502             + "  </head>\n"
503             + "  <body onload='test()'>\n"
504             + "      test\n"
505             + "  </body>\n"
506             + "</html>";
507 
508         getMockWebConnection().setResponse(new URL(URL_FIRST, "script2.js"), "log(2);");
509         getMockWebConnection().setResponse(new URL(URL_FIRST, "script3.js"), "log(3);");
510         getMockWebConnection().setResponse(new URL(URL_FIRST, "script4.js"), "log(4);");
511         getMockWebConnection().setResponse(new URL(URL_FIRST, "script5.js"), "log(5);");
512 
513         loadPage2(html);
514         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
515     }
516 
517     /**
518      * @throws Exception on test failure
519      */
520     @Test
521     @Alerts({"s-x", "z"})
522     public void addEventListener_load() throws Exception {
523         final String html = DOCTYPE_HTML
524             + "<html><head>\n"
525             + "<script>\n"
526             + LOG_TITLE_FUNCTION
527             + "  function test() {\n"
528             + "    var s1 = document.createElement('script');\n"
529             + "    s1.text = 'log(\"s-x\")';\n"
530             + "    s1.addEventListener('load', function() {log('x')}, false);\n"
531             + "    document.body.insertBefore(s1, document.body.firstChild);\n"
532             + "    \n"
533             + "    var s2 = document.createElement('script');\n"
534             + "    s2.src = '//:';\n"
535             + "    s2.addEventListener('load', function() {log('y')}, false);\n"
536             + "    document.body.insertBefore(s2, document.body.firstChild);\n"
537             + "    \n"
538             + "    var s3 = document.createElement('script');\n"
539             + "    s3.src = 'script.js';\n"
540             + "    s3.addEventListener('load', function() {log('z')}, false);\n"
541             + "    document.body.insertBefore(s3, document.body.firstChild);\n"
542             + "  }\n"
543             + "</script>\n"
544             + "</head>\n"
545             + "<body onload='test()'></body>\n"
546             + "</html>";
547 
548         getMockWebConnection().setDefaultResponse("", MimeType.TEXT_JAVASCRIPT);
549 
550         loadPage2(html);
551         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
552     }
553 
554     /**
555      * @throws Exception on test failure
556      */
557     @Test
558     @Alerts("load")
559     public void addEventListener_NoContent() throws Exception {
560         addEventListener(HttpStatus.NO_CONTENT_204);
561     }
562 
563     /**
564      * @throws Exception on test failure
565      */
566     @Test
567     @Alerts("error [object HTMLScriptElement]")
568     public void addEventListener_BadRequest() throws Exception {
569         addEventListener(HttpStatus.BAD_REQUEST_400);
570     }
571 
572     /**
573      * @throws Exception on test failure
574      */
575     @Test
576     @Alerts("error [object HTMLScriptElement]")
577     public void addEventListener_Forbidden() throws Exception {
578         addEventListener(HttpStatus.FORBIDDEN_403);
579     }
580 
581     /**
582      * @throws Exception on test failure
583      */
584     @Test
585     @Alerts("error [object HTMLScriptElement]")
586     public void addEventListener_NotFound() throws Exception {
587         addEventListener(HttpStatus.NOT_FOUND_404);
588     }
589 
590     /**
591      * @throws Exception on test failure
592      */
593     @Test
594     @Alerts("error [object HTMLScriptElement]")
595     public void addEventListener_MethodNotAllowed() throws Exception {
596         addEventListener(HttpStatus.METHOD_NOT_ALLOWED_405);
597     }
598 
599     /**
600      * @throws Exception on test failure
601      */
602     @Test
603     @Alerts("error [object HTMLScriptElement]")
604     public void addEventListener_NotAcceptable() throws Exception {
605         addEventListener(HttpStatus.NOT_ACCEPTABLE_406);
606     }
607 
608     /**
609      * @throws Exception on test failure
610      */
611     @Test
612     @Alerts("error [object HTMLScriptElement]")
613     public void addEventListener_ProxyAuthRequired() throws Exception {
614         addEventListener(HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407);
615     }
616 
617     /**
618      * @throws Exception on test failure
619      */
620     @Test
621     @Alerts("error [object HTMLScriptElement]")
622     public void addEventListener_RequestTimeout() throws Exception {
623         addEventListener(HttpStatus.REQUEST_TIMEOUT_408);
624     }
625 
626     /**
627      * @throws Exception on test failure
628      */
629     @Test
630     @Alerts("error [object HTMLScriptElement]")
631     public void addEventListener_Conflict() throws Exception {
632         addEventListener(HttpStatus.CONFLICT_409);
633     }
634 
635     /**
636      * @throws Exception on test failure
637      */
638     @Test
639     @Alerts("error [object HTMLScriptElement]")
640     public void addEventListener_Gone() throws Exception {
641         addEventListener(HttpStatus.GONE_410);
642     }
643 
644     /**
645      * @throws Exception on test failure
646      */
647     @Test
648     @Alerts("error [object HTMLScriptElement]")
649     public void addEventListener_LengthRequired() throws Exception {
650         addEventListener(HttpStatus.LENGTH_REQUIRED_411);
651     }
652 
653     /**
654      * @throws Exception on test failure
655      */
656     @Test
657     @Alerts("error [object HTMLScriptElement]")
658     public void addEventListener_PreconditionFailed() throws Exception {
659         addEventListener(HttpStatus.PRECONDITION_FAILED_412);
660     }
661 
662     /**
663      * @throws Exception on test failure
664      */
665     @Test
666     @Alerts("error [object HTMLScriptElement]")
667     public void addEventListener_PayloadTooLarge() throws Exception {
668         addEventListener(HttpStatus.PAYLOAD_TOO_LARGE_413);
669     }
670 
671     /**
672      * @throws Exception on test failure
673      */
674     @Test
675     @Alerts("error [object HTMLScriptElement]")
676     public void addEventListener_UriTooLong() throws Exception {
677         addEventListener(HttpStatus.URI_TOO_LONG_414);
678     }
679 
680     /**
681      * @throws Exception on test failure
682      */
683     @Test
684     @Alerts("error [object HTMLScriptElement]")
685     public void addEventListener_UnsupportedMediaType() throws Exception {
686         addEventListener(HttpStatus.UNSUPPORTED_MEDIA_TYPE_415);
687     }
688 
689     /**
690      * @throws Exception on test failure
691      */
692     @Test
693     @Alerts("error [object HTMLScriptElement]")
694     public void addEventListener_RangeNotSatisfiable() throws Exception {
695         addEventListener(HttpStatus.RANGE_NOT_SATISFIABLE_416);
696     }
697 
698     /**
699      * @throws Exception on test failure
700      */
701     @Test
702     @Alerts("error [object HTMLScriptElement]")
703     public void addEventListener_ExpectationFailed() throws Exception {
704         addEventListener(HttpStatus.EXPECTATION_FAILED_417);
705     }
706 
707     /**
708      * @throws Exception on test failure
709      */
710     @Test
711     @Alerts("error [object HTMLScriptElement]")
712     public void addEventListener_ImaTeapot() throws Exception {
713         addEventListener(HttpStatus.IM_A_TEAPOT_418);
714     }
715 
716     /**
717      * @throws Exception on test failure
718      */
719     @Test
720     @Alerts("error [object HTMLScriptElement]")
721     public void addEventListener_EnhanceYourCalm() throws Exception {
722         addEventListener(HttpStatus.ENHANCE_YOUR_CALM_420);
723     }
724 
725     /**
726      * @throws Exception on test failure
727      */
728     @Test
729     @Alerts("error [object HTMLScriptElement]")
730     public void addEventListener_MisdirectedRequest() throws Exception {
731         addEventListener(HttpStatus.MISDIRECTED_REQUEST_421);
732     }
733 
734     /**
735      * @throws Exception on test failure
736      */
737     @Test
738     @Alerts("error [object HTMLScriptElement]")
739     public void addEventListener_UnprocessableEntity() throws Exception {
740         addEventListener(HttpStatus.UNPROCESSABLE_ENTITY_422);
741     }
742 
743     /**
744      * @throws Exception on test failure
745      */
746     @Test
747     @Alerts("error [object HTMLScriptElement]")
748     public void addEventListener_Locked() throws Exception {
749         addEventListener(HttpStatus.LOCKED_423);
750     }
751 
752     /**
753      * @throws Exception on test failure
754      */
755     @Test
756     @Alerts("error [object HTMLScriptElement]")
757     public void addEventListener_FailedDependency() throws Exception {
758         addEventListener(HttpStatus.FAILED_DEPENDENCY_424);
759     }
760 
761     /**
762      * @throws Exception on test failure
763      */
764     @Test
765     @Alerts("error [object HTMLScriptElement]")
766     public void addEventListener_UpgradeRequired() throws Exception {
767         addEventListener(HttpStatus.UPGRADE_REQUIRED_426);
768     }
769 
770     /**
771      * @throws Exception on test failure
772      */
773     @Test
774     @Alerts("error [object HTMLScriptElement]")
775     public void addEventListener_PreconditionRequired() throws Exception {
776         addEventListener(HttpStatus.PRECONDITION_REQUIRED_428);
777     }
778 
779     /**
780      * @throws Exception on test failure
781      */
782     @Test
783     @Alerts("error [object HTMLScriptElement]")
784     public void addEventListener_TooManyRedirects() throws Exception {
785         addEventListener(HttpStatus.TOO_MANY_REQUESTS_429);
786     }
787 
788     /**
789      * @throws Exception on test failure
790      */
791     @Test
792     @Alerts("error [object HTMLScriptElement]")
793     public void addEventListener_RequestHeaderFieldsTooLarge() throws Exception {
794         addEventListener(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431);
795     }
796 
797     /**
798      * @throws Exception on test failure
799      */
800     @Test
801     @Alerts("error [object HTMLScriptElement]")
802     public void addEventListener_UnavailableForLegalReasons() throws Exception {
803         addEventListener(HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS_451);
804     }
805 
806     /**
807      * @throws Exception on test failure
808      */
809     @Test
810     @Alerts("error [object HTMLScriptElement]")
811     public void addEventListener_InternalServerError() throws Exception {
812         addEventListener(HttpStatus.INTERNAL_SERVER_ERROR_500);
813     }
814 
815     /**
816      * @throws Exception on test failure
817      */
818     @Test
819     @Alerts("error [object HTMLScriptElement]")
820     public void addEventListener_NotImplemented() throws Exception {
821         addEventListener(HttpStatus.NOT_IMPLEMENTED_501);
822     }
823 
824     /**
825      * @throws Exception on test failure
826      */
827     @Test
828     @Alerts("error [object HTMLScriptElement]")
829     public void addEventListener_BadGateway() throws Exception {
830         addEventListener(HttpStatus.BAD_GATEWAY_502);
831     }
832 
833     /**
834      * @throws Exception on test failure
835      */
836     @Test
837     @Alerts("error [object HTMLScriptElement]")
838     public void addEventListener_ServiceUnavailable() throws Exception {
839         addEventListener(HttpStatus.SERVICE_UNAVAILABLE_503);
840     }
841 
842     /**
843      * @throws Exception on test failure
844      */
845     @Test
846     @Alerts("error [object HTMLScriptElement]")
847     public void addEventListener_GatewayTimeout() throws Exception {
848         addEventListener(HttpStatus.GATEWAY_TIMEOUT_504);
849     }
850 
851     /**
852      * @throws Exception on test failure
853      */
854     @Test
855     @Alerts("error [object HTMLScriptElement]")
856     public void addEventListener_HttpVersionNotSupported() throws Exception {
857         addEventListener(HttpStatus.HTTP_VERSION_NOT_SUPPORTED_505);
858     }
859 
860     /**
861      * @throws Exception on test failure
862      */
863     @Test
864     @Alerts("error [object HTMLScriptElement]")
865     public void addEventListener_InsufficientStrorage() throws Exception {
866         addEventListener(HttpStatus.INSUFFICIENT_STORAGE_507);
867     }
868 
869     /**
870      * @throws Exception on test failure
871      */
872     @Test
873     @Alerts("error [object HTMLScriptElement]")
874     public void addEventListener_LoopDetected() throws Exception {
875         addEventListener(HttpStatus.LOOP_DETECTED_508);
876     }
877 
878     /**
879      * @throws Exception on test failure
880      */
881     @Test
882     @Alerts("error [object HTMLScriptElement]")
883     public void addEventListener_NotExtended() throws Exception {
884         addEventListener(HttpStatus.NOT_EXTENDED_510);
885     }
886 
887     /**
888      * @throws Exception on test failure
889      */
890     @Test
891     @Alerts("error [object HTMLScriptElement]")
892     public void addEventListener_NetworkAuthenticationRequired() throws Exception {
893         addEventListener(HttpStatus.NETWORK_AUTHENTICATION_REQUIRED_511);
894     }
895 
896     private void addEventListener(final int statusCode) throws Exception {
897         // use always a different url to avoid caching effects
898         final URL scriptUrl = new URL(URL_SECOND, "" + System.currentTimeMillis() + ".js");
899 
900         final String html = DOCTYPE_HTML
901             + "<html><head>\n"
902             + "<script>\n"
903             + LOG_TITLE_FUNCTION
904             + "  function test() {\n"
905             + "    var s1 = document.createElement('script');\n"
906             + "    s1.src = '" + scriptUrl + "';\n"
907             + "    s1.addEventListener('load', function() { log('load'); }, false);\n"
908             + "    s1.addEventListener('error', function(event) { log(event.type + ' ' + event.target); }, false);\n"
909             + "    document.body.insertBefore(s1, document.body.firstChild);\n"
910             + "  }\n"
911             + "</script>\n"
912             + "</head>\n"
913             + "<body onload='test()'></body>\n"
914             + "</html>";
915 
916         getMockWebConnection().setResponse(scriptUrl, (String) null,
917                 statusCode, "test", MimeType.TEXT_JAVASCRIPT, null);
918         loadPageVerifyTitle2(html);
919     }
920 
921     /**
922      * Regression test for bug #1267.
923      * @throws Exception if an error occurs
924      */
925     @Test
926     public void badSrcUrl() throws Exception {
927         final String html = DOCTYPE_HTML
928                 + "<html><head>\n"
929                 + "<script src='http://'>log(1)</script>\n"
930                 + "</head><body></body></html>";
931 
932         loadPageVerifyTitle2(html);
933     }
934 
935     /**
936      * Verifies that the weird script src attribute used by the jQuery JavaScript library is
937      * ignored silently (bug #455).
938      * @throws Exception if the test fails
939      */
940     @Test
941     public void invalidJQuerySrcAttribute() throws Exception {
942         loadPage2(DOCTYPE_HTML + "<html><body><script src='//:'></script></body></html>");
943     }
944 
945     /**
946      * @throws Exception if the test fails
947      */
948     @Test
949     @Alerts({"loaded", "§§URL§§abcd"})
950     public void lineBreaksInUrl() throws Exception {
951         final String html = DOCTYPE_HTML
952             + "<html><head>\n"
953             + "  <script>\n"
954             + LOG_TITLE_FUNCTION_NORMALIZE
955             + "  </script>\n"
956             + "  <script id='myScript' src='" + URL_SECOND + "a\rb\nc\r\nd'></script>\n"
957             + "</head>\n"
958             + "<body onload='log(document.getElementById(\"myScript\").src);'>Test</body>\n"
959             + "</html>";
960 
961         getMockWebConnection().setResponse(new URL(URL_SECOND, "abcd"), "log('loaded')");
962         expandExpectedAlertsVariables(URL_SECOND);
963 
964         loadPageVerifyTitle2(html);
965     }
966 
967     /**
968      * @throws Exception if the test fails
969      */
970     @Test
971     @Alerts({"\u0623\u0647\u0644\u0627\u064b\u0623\u0647\u0644\u0627"
972             + "\u064b\u0623\u0647\u0644\u0627\u064b\u0623\u0647\u0644\u0627\u064b", "§§URL§§"})
973     public void incorrectCharset() throws Exception {
974         final String html = DOCTYPE_HTML
975             + "<html><head>\n"
976             + "  <script>\n"
977             + LOG_TITLE_FUNCTION_NORMALIZE
978             + "  </script>\n"
979             + "  <script id='myScript' src='" + URL_SECOND + "' charset='" + ISO_8859_1 + "'></script>\n"
980             + "</head>\n"
981             + "<body onload='log(document.getElementById(\"myScript\").src);'></body>\n"
982             + "</html>";
983 
984         final String script = new String(ByteOrderMark.UTF_8.getBytes())
985                 + "log('" + "\u0623\u0647\u0644\u0627\u064b\u0623\u0647\u0644\u0627"
986                             + "\u064b\u0623\u0647\u0644\u0627\u064b\u0623\u0647\u0644\u0627\u064b" + "');";
987         getMockWebConnection().setResponse(URL_SECOND, script, MimeType.TEXT_JAVASCRIPT, UTF_8);
988         expandExpectedAlertsVariables(URL_SECOND);
989 
990         loadPageVerifyTitle2(html);
991     }
992 
993     /**
994      * @throws Exception if an error occurs
995      */
996     @Test
997     @Alerts({"onLoad", "body onLoad"})
998     public void onLoad() throws Exception {
999         getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.js"), "");
1000         onLoadOnError("src='simple.js' type='text/javascript'");
1001     }
1002 
1003     /**
1004      * @throws Exception if an error occurs
1005      */
1006     @Test
1007     @Alerts({"onLoad", "body onLoad"})
1008     public void onLoadTypeWhitespace() throws Exception {
1009         getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.js"), "");
1010         onLoadOnError("src='simple.js' type='\t  text/javascript     '");
1011     }
1012 
1013     /**
1014      * @throws Exception if an error occurs
1015      */
1016     @Test
1017     @Alerts({"onError", "body onLoad"})
1018     public void onError() throws Exception {
1019         onLoadOnError("src='unknown.js' type='text/javascript'");
1020     }
1021 
1022     /**
1023      * @throws Exception if an error occurs
1024      */
1025     @Test
1026     @Alerts({"onError", "body onLoad"})
1027     public void onLoadOnErrorWithoutType() throws Exception {
1028         onLoadOnError("src='unknown.js'");
1029     }
1030 
1031     private void onLoadOnError(final String attribs) throws Exception {
1032         final String html = DOCTYPE_HTML
1033                 + "<html>\n"
1034                 + "<head>\n"
1035                 + "  <script>\n"
1036                 + LOG_TITLE_FUNCTION
1037                 + "  </script>\n"
1038                 + "  <script " + attribs
1039                         + " onload='log(\"onLoad\")' onerror='log(\"onError\")'></script>\n"
1040                 + "</head>\n"
1041                 + "<body onload='log(\"body onLoad\")'>\n"
1042                 + "</body>\n"
1043                 + "</html>";
1044         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
1045 
1046         loadPageVerifyTitle2(html);
1047     }
1048 
1049     /**
1050      * @throws Exception if an error occurs
1051      */
1052     @Test
1053     @Alerts({"from script", "onLoad [object Event]"})
1054     public void onLoadDynamic() throws Exception {
1055         getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.js"), "log('from script');");
1056         final String html = DOCTYPE_HTML
1057                 + "<html>\n"
1058                 + "<head>\n"
1059                 + "  <script>\n"
1060                 + LOG_TITLE_FUNCTION
1061                 + "    function test() {\n"
1062                 + "      var dynScript = document.createElement('script');\n"
1063                 + "      dynScript.type = 'text/javascript';\n"
1064                 + "      dynScript.onload = function (e) { log(\"onLoad \" + e) };\n"
1065                 + "      document.head.appendChild(dynScript);\n"
1066                 + "      dynScript.src = 'simple.js';"
1067                 + "    }\n"
1068                 + "  </script>\n"
1069                 + "</head>\n"
1070                 + "<body onload='test()'></body>\n"
1071                 + "</html>";
1072 
1073         final WebDriver driver = loadPage2(html);
1074         verifyTitle2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
1075     }
1076 
1077     /**
1078      * @throws Exception if an error occurs
1079      */
1080     @Test
1081     @Alerts("[object HTMLScriptElement]")
1082     public void currentScriptInline() throws Exception {
1083         final String html = DOCTYPE_HTML
1084                 + "<html>\n"
1085                 + "<head>\n"
1086                 + "  <script id='tester'>\n"
1087                 + LOG_TITLE_FUNCTION
1088                 + "    log(document.currentScript);\n"
1089                 + "  </script>\n"
1090                 + "</head>\n"
1091                 + "<body>\n"
1092                 + "</body>\n"
1093                 + "</html>";
1094 
1095         loadPageVerifyTitle2(html);
1096     }
1097 
1098     /**
1099      * @throws Exception if an error occurs
1100      */
1101     @Test
1102     @Alerts("null")
1103     public void currentScriptFunction() throws Exception {
1104         final String html = DOCTYPE_HTML
1105                 + "<html>\n"
1106                 + "<head>\n"
1107                 + "  <script id='tester'>\n"
1108                 + LOG_TITLE_FUNCTION
1109                 + "    function test() {\n"
1110                 + "      log(document.currentScript);\n"
1111                 + "  }\n"
1112                 + "</script>\n"
1113                 + "</head>\n"
1114                 + "<body onload='test()'>\n"
1115                 + "</body>\n"
1116                 + "</html>";
1117 
1118         loadPageVerifyTitle2(html);
1119     }
1120 
1121     /**
1122      * @throws Exception if an error occurs
1123      */
1124     @Test
1125     @Alerts("[object HTMLScriptElement]")
1126     public void currentScriptExternal() throws Exception {
1127         getMockWebConnection().setResponse(new URL(URL_FIRST, "simple.js"), "log(document.currentScript);");
1128         final String html = DOCTYPE_HTML
1129                 + "<html>\n"
1130                 + "<head>\n"
1131                 + "  <script>\n"
1132                 + LOG_TITLE_FUNCTION
1133                 + "  </script>\n"
1134                 + "  <script id='tester' src='simple.js' type='text/javascript'></script>\n"
1135                 + "</head>\n"
1136                 + "<body>\n"
1137                 + "</body>\n"
1138                 + "</html>";
1139 
1140         loadPage2(html);
1141         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
1142     }
1143 
1144     /**
1145      * @throws Exception if an error occurs
1146      */
1147     @Test
1148     @Alerts("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 "
1149             + "21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39")
1150     public void scriptExecutionOrder() throws Exception {
1151         final StringBuilder html = new StringBuilder();
1152         html.append(DOCTYPE_HTML + "<html>\n<head>\n");
1153         int i = 0;
1154         for ( ; i < 20; i++) {
1155             html.append("  <script type='text/javascript'>document.title += ' ")
1156                 .append(Integer.toString(i))
1157                 .append("'</script>\n");
1158         }
1159         html.append("</head>\n<body>\n");
1160         for ( ; i < 40; i++) {
1161             html.append("  <script type='text/javascript'>document.title += ' ")
1162                 .append(Integer.toString(i))
1163                 .append("'</script>\n");
1164         }
1165         html.append("</body>\n</html>");
1166 
1167         final WebDriver driver = loadPage2(html.toString());
1168         assertTitle(driver, getExpectedAlerts()[0]);
1169     }
1170 
1171     /**
1172      * Tests the 'Referer' HTTP header.
1173      * @throws Exception on test failure
1174      */
1175     @Test
1176     @Alerts("§§URL§§index.html?test")
1177     public void refererHeader() throws Exception {
1178         final String firstContent = DOCTYPE_HTML
1179             + "<html><head><title>Page A</title></head>\n"
1180             + "<body><script src='" + URL_SECOND + "'/></body>\n"
1181             + "</html>";
1182 
1183         final String secondContent = "var i = 7;";
1184 
1185         expandExpectedAlertsVariables(URL_FIRST);
1186 
1187         final URL indexUrl = new URL(URL_FIRST.toString() + "index.html");
1188 
1189         getMockWebConnection().setResponse(indexUrl, firstContent);
1190         getMockWebConnection().setResponse(URL_SECOND, secondContent);
1191 
1192         loadPage2(firstContent, new URL(URL_FIRST.toString() + "index.html?test#ref"));
1193 
1194         assertEquals(2, getMockWebConnection().getRequestCount());
1195 
1196         final Map<String, String> lastAdditionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1197         assertEquals(getExpectedAlerts()[0], lastAdditionalHeaders.get(HttpHeader.REFERER));
1198     }
1199 
1200     /**
1201      * Verifies that we're lenient about whitespace before and after URLs in the "src" attribute.
1202      * @throws Exception if an error occurs
1203      */
1204     @Test
1205     @Alerts({"loaded", "§§URL§§"})
1206     public void whitespaceInSrc() throws Exception {
1207         final String html = DOCTYPE_HTML
1208                 + "<html><head>"
1209                 + "  <script>" + LOG_TITLE_FUNCTION_NORMALIZE + "</script>"
1210                 + "<script id='myScript' src=' " + URL_SECOND + " '></script></head>"
1211                 + "<body onload='log(document.getElementById(\"myScript\").src);'>abc</body></html>";
1212 
1213         final String js = "log('loaded')";
1214         getMockWebConnection().setResponse(URL_SECOND, js);
1215         expandExpectedAlertsVariables(URL_SECOND);
1216 
1217         loadPageVerifyTitle2(html);
1218     }
1219 
1220     /**
1221      * Verifies that we're lenient about control characters before and after URLs in the "src" attribute.
1222      * @throws Exception if an error occurs
1223      */
1224     @Test
1225     @Alerts({"loaded", "§§URL§§"})
1226     public void controlCharsInSrc() throws Exception {
1227         final String html = DOCTYPE_HTML
1228                 + "<html><head>"
1229                 + "  <script>" + LOG_TITLE_FUNCTION_NORMALIZE + "</script>"
1230                 + "<script id='myScript' src=' " + URL_SECOND + "\u001d'></script></head>"
1231                 + "<body onload='log(document.getElementById(\"myScript\").src);'>abc</body></html>";
1232 
1233         final String js = "log('loaded')";
1234         getMockWebConnection().setResponse(URL_SECOND, js);
1235         expandExpectedAlertsVariables(URL_SECOND);
1236 
1237         loadPageVerifyTitle2(html);
1238     }
1239 
1240     /**
1241      * Verifies that we're lenient about control characters before and after URLs in the "src" attribute.
1242      * @throws Exception if an error occurs
1243      */
1244     @Test
1245     @Alerts({"loaded", "§§URL§§"})
1246     public void tabCharInSrc() throws Exception {
1247         String url = URL_SECOND.toExternalForm();
1248         url = url.replace("http", "http\t");
1249 
1250         final String html = DOCTYPE_HTML
1251                 + "<html><head>"
1252                 + "  <script>" + LOG_TITLE_FUNCTION_NORMALIZE + "</script>"
1253                 + "<script id='myScript' src=' " + url + "\u001d'></script></head>"
1254                 + "<body onload='log(document.getElementById(\"myScript\").src);'>abc</body></html>";
1255 
1256         final String js = "log('loaded')";
1257         getMockWebConnection().setResponse(URL_SECOND, js);
1258         expandExpectedAlertsVariables(URL_SECOND);
1259 
1260         loadPageVerifyTitle2(html);
1261     }
1262 
1263     /**
1264      * Verifies that we're lenient about empty "src" attributes.
1265      * @throws Exception if an error occurs
1266      */
1267     @Test
1268     public void emptySrc() throws Exception {
1269         final String html1 = DOCTYPE_HTML + "<html><head><script src=''></script></head><body>abc</body></html>";
1270         final String html2 = DOCTYPE_HTML + "<html><head><script src='  '></script></head><body>abc</body></html>";
1271 
1272         loadPageWithAlerts2(html1);
1273         loadPageWithAlerts2(html2);
1274     }
1275 
1276     /**
1277      * Verifies that 204 (No Content) responses for script resources are handled gracefully.
1278      * @throws Exception on test failure
1279      * @see <a href="https://sourceforge.net/tracker/?func=detail&atid=448266&aid=2815903&group_id=47038">2815903</a>
1280      */
1281     @Test
1282     public void noContent() throws Exception {
1283         final String html = DOCTYPE_HTML + "<html><body><script src='" + URL_SECOND + "'/></body></html>";
1284 
1285         final ArrayList<NameValuePair> headers = new ArrayList<>();
1286         getMockWebConnection().setResponse(URL_SECOND, (String) null,
1287                 HttpStatus.NO_CONTENT_204, HttpStatus.NO_CONTENT_204_MSG,
1288                 MimeType.TEXT_JAVASCRIPT,
1289                 headers);
1290 
1291         loadPageWithAlerts2(html);
1292     }
1293 
1294     /**
1295      * @throws Exception if an error occurs
1296      */
1297     @Test
1298     @Alerts("script")
1299     public void srcAndContent() throws Exception {
1300         final String html = DOCTYPE_HTML
1301             + "<html>\n"
1302             + "  <head>\n"
1303             + "    <script src='foo.js'>window.document.title += 'content' + '\\u00a7';</script>\n";
1304 
1305         final String js = "window.document.title += 'script' + '\\u00a7';";
1306 
1307         getMockWebConnection().setDefaultResponse(js, MimeType.TEXT_JAVASCRIPT);
1308 
1309         loadPageVerifyTitle2(html);
1310     }
1311 
1312     /**
1313      * @throws Exception if an error occurs
1314      */
1315     @Test
1316     public void emptySrcAndContent() throws Exception {
1317         final String html = DOCTYPE_HTML
1318             + "<html>\n"
1319             + "  <head>\n"
1320             + "    <script src=''>window.document.title += 'content' + '\\u00a7';</script>\n";
1321 
1322         final String js = "window.document.title += 'script' + '\\u00a7';";
1323 
1324         getMockWebConnection().setDefaultResponse(js, MimeType.TEXT_JAVASCRIPT);
1325 
1326         loadPageVerifyTitle2(html);
1327     }
1328 
1329     /**
1330      * @throws Exception if an error occurs
1331      */
1332     @Test
1333     public void blankSrcAndContent() throws Exception {
1334         final String html = DOCTYPE_HTML
1335             + "<html>\n"
1336             + "  <head>\n"
1337             + "    <script src=' '>window.document.title += 'content' + '\\u00a7';</script>\n";
1338 
1339         final String js = "window.document.title += 'script' + '\\u00a7';";
1340 
1341         getMockWebConnection().setDefaultResponse(js, MimeType.TEXT_JAVASCRIPT);
1342 
1343         loadPageVerifyTitle2(html);
1344     }
1345 
1346     /**
1347      * @throws Exception if an error occurs
1348      */
1349     @Test
1350     public void attribSrcAndContent() throws Exception {
1351         final String html = DOCTYPE_HTML
1352             + "<html>\n"
1353             + "  <head>\n"
1354             + "    <script src>window.document.title += 'content' + '\\u00a7';</script>\n";
1355 
1356         final String js = "window.document.title += 'script' + '\\u00a7';";
1357 
1358         getMockWebConnection().setDefaultResponse(js, MimeType.TEXT_JAVASCRIPT);
1359 
1360         loadPageVerifyTitle2(html);
1361     }
1362 
1363 
1364     /**
1365      * @throws Exception if an error occurs
1366      */
1367     @Test
1368     @Alerts({"first script", "second script"})
1369     public void content() throws Exception {
1370         final String html = DOCTYPE_HTML
1371             + "<html>\n"
1372             + "  <head>\n"
1373             + "    <script src='foo.js'>window.document.title += 'content' + '\\u00a7';</script>\n"
1374             + "    <script>window.document.title += 'second script' + '\\u00a7';</script>\n";
1375 
1376         final String js = "window.document.title += 'first script' + '\\u00a7';";
1377 
1378         getMockWebConnection().setDefaultResponse(js, MimeType.TEXT_JAVASCRIPT);
1379 
1380         loadPageVerifyTitle2(html);
1381     }
1382 }