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.html;
16  
17  import static java.nio.charset.StandardCharsets.ISO_8859_1;
18  import static java.nio.charset.StandardCharsets.UTF_8;
19  import static org.junit.jupiter.api.Assertions.fail;
20  
21  import java.net.URL;
22  import java.text.ParseException;
23  import java.text.SimpleDateFormat;
24  import java.util.ArrayList;
25  import java.util.Date;
26  import java.util.LinkedList;
27  import java.util.List;
28  import java.util.Locale;
29  import java.util.TimeZone;
30  
31  import org.apache.http.client.utils.DateUtils;
32  import org.htmlunit.BrowserVersion;
33  import org.htmlunit.WebDriverTestCase;
34  import org.htmlunit.html.HtmlPage;
35  import org.htmlunit.junit.annotation.Alerts;
36  import org.htmlunit.junit.annotation.BuggyWebDriver;
37  import org.htmlunit.junit.annotation.HtmlUnitNYI;
38  import org.htmlunit.util.MimeType;
39  import org.htmlunit.util.NameValuePair;
40  import org.junit.jupiter.api.Test;
41  import org.openqa.selenium.By;
42  import org.openqa.selenium.WebDriver;
43  import org.openqa.selenium.htmlunit.HtmlUnitDriver;
44  
45  /**
46   * Tests for {@link HTMLDocument}.
47   *
48   * @author Ahmed Ashour
49   * @author Marc Guillemot
50   * @author Ronald Brill
51   * @author Frank Danek
52   */
53  public class HTMLDocumentTest extends WebDriverTestCase {
54      /** jQuery selectors that aren't CSS selectors. */
55      static final String[] JQUERY_CUSTOM_SELECTORS = {"div.submenu-last:last",
56          "*#__sizzle__ div.submenu-last:last", "div:animated", "div:animated", "*:button", "*:checkbox", "div:even",
57          "*:file", "div:first", "td:gt(4)", ":header", ":hidden", ":image", ":input", "td:lt(4)",
58          ":odd", ":password", ":radio", ":reset", ":selected", ":submit", ":text", ":visible"
59      };
60  
61      /**
62       * @throws Exception if the test fails
63       */
64      @Test
65      @Alerts("[object HTMLDocument]")
66      public void scriptableToString() throws Exception {
67          final String html = DOCTYPE_HTML
68              + "<html><head>\n"
69              + "<script>\n"
70              + LOG_TITLE_FUNCTION
71              + "  function test() {\n"
72              + "    log(document);\n"
73              + "  }\n"
74              + "</script></head>\n"
75              + "<body onload='test()'>\n"
76              + "</body></html>";
77  
78          loadPageVerifyTitle2(html);
79      }
80  
81      /**
82       * @throws Exception if the test fails
83       */
84      @Test
85      @Alerts({"2", "DIV", "2"})
86      public void getElementsByTagName() throws Exception {
87          final String html = DOCTYPE_HTML
88              + "<html>\n"
89              + "<head>\n"
90              + "  <script>\n"
91              + LOG_TITLE_FUNCTION
92              + "  function test() {\n"
93              + "    log(document.getElementsByTagName('div').length);\n"
94              + "    document.getElementById('myDiv').innerHTML = \"<P><DIV id='secondDiv'></DIV></P>\";\n"
95              + "    log(document.getElementById('secondDiv').nodeName);\n"
96              + "    log(document.getElementsByTagName('div').length);\n"
97              + "  }\n"
98              + "  </script>\n"
99              + "</head>\n"
100             + "<body onload='test()'>\n"
101             + "<div id='myDiv'>\n"
102             + "  <div></div>\n"
103             + "</div>\n"
104             + "</body>\n"
105             + "</html>";
106 
107         loadPageVerifyTitle2(html);
108     }
109 
110     /**
111      * @throws Exception if the test fails
112      */
113     @Test
114     @Alerts({"function", "div1", "span2", "span3", "2", "1", "1", "0", "0", "0"})
115     public void getElementsByClassName() throws Exception {
116         final String html = DOCTYPE_HTML
117             + "<html><head><script>\n"
118             + LOG_TITLE_FUNCTION
119             + "function doTest() {\n"
120             + "  log(typeof document.getElementsByClassName);\n"
121             + "  try {\n"
122             + "    var elements = document.getElementsByClassName('foo');\n"
123             + "    for (var i = 0; i < elements.length; i++) {\n"
124             + "      log(elements[i].id);\n"
125             + "    }\n"
126             + "    log(document.getElementsByClassName('red').length);\n"
127             + "    log(document.getElementsByClassName('foo red').length);\n"
128             + "    log(document.getElementsByClassName('red foo').length);\n"
129             + "    log(document.getElementsByClassName('blue foo').length);\n"
130             + "    log(document.getElementsByClassName('*').length);\n"
131 //            + "    log(document.getElementsByClassName().length);\n" // exception in FF3
132             + "    log(document.getElementsByClassName(null).length);\n"
133             + "  }\n"
134             + "  catch(e) { logEx(e) }\n"
135             + "}\n"
136             + "</script></head><body onload='doTest()'>\n"
137             + "<div class='foo' id='div1'><span class='c2'>hello</span>\n"
138             + "  <span class='foo' id='span2'>World!</span></div>\n"
139             + "<span class='foo red' id='span3'>again</span>\n"
140             + "<span class='red' id='span4'>bye</span>\n"
141             + "</body></html>";
142 
143         loadPageVerifyTitle2(html);
144     }
145 
146     /**
147      * @throws Exception if the test fails
148      */
149     @Test
150     @Alerts("BackCompat")
151     public void compatMode() throws Exception {
152         compatMode("");
153     }
154 
155     /**
156      * @throws Exception if the test fails
157      */
158     @Test
159     @Alerts("BackCompat")
160     public void compatMode_doctype() throws Exception {
161         compatMode("<!DOCTYPE>");
162     }
163 
164     /**
165      * @throws Exception if the test fails
166      */
167     @Test
168     @Alerts("CSS1Compat")
169     public void compatMode_html() throws Exception {
170         compatMode("<!DOCTYPE html>");
171     }
172 
173     /**
174      * @throws Exception if the test fails
175      */
176     @Test
177     @Alerts("CSS1Compat")
178     public void compatMode_htmlLowercase() throws Exception {
179         compatMode("<!doctype html>");
180     }
181 
182     /**
183      * @throws Exception if the test fails
184      */
185     @Test
186     @Alerts("BackCompat")
187     public void compatMode_question() throws Exception {
188         compatMode("<?DOCTYPE html>");
189     }
190 
191     /**
192      * @throws Exception if the test fails
193      */
194     @Test
195     @Alerts("BackCompat")
196     public void compatMode_html_transitional_40_noUrl() throws Exception {
197         compatMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">");
198     }
199 
200     /**
201      * @throws Exception if the test fails
202      */
203     @Test
204     @Alerts("BackCompat")
205     public void compatMode_html_transitional_noUrl() throws Exception {
206         compatMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
207     }
208 
209     /**
210      * @throws Exception if the test fails
211      */
212     @Test
213     @Alerts("BackCompat")
214     public void compatMode_html_transitional_40() throws Exception {
215         compatMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" "
216             + "\"http://www.w3.org/TR/html4/loose.dtd\">");
217     }
218 
219     /**
220      * @throws Exception if the test fails
221      */
222     @Test
223     @Alerts("CSS1Compat")
224     public void compatMode_html_transitional() throws Exception {
225         compatMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
226             + "\"http://www.w3.org/TR/html4/loose.dtd\">");
227     }
228 
229     /**
230      * @throws Exception if the test fails
231      */
232     @Test
233     @Alerts("CSS1Compat")
234     public void compatMode_html_strict_40() throws Exception {
235         compatMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
236     }
237 
238     /**
239      * @throws Exception if the test fails
240      */
241     @Test
242     @Alerts("CSS1Compat")
243     public void compatMode_html_strict() throws Exception {
244         compatMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
245     }
246 
247     /**
248      * @throws Exception if the test fails
249      */
250     @Test
251     @Alerts("CSS1Compat")
252     public void compatMode_xhtml_transitional() throws Exception {
253         compatMode("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
254             + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
255     }
256 
257     /**
258      * @throws Exception if the test fails
259      */
260     @Test
261     @Alerts("CSS1Compat")
262     public void compatMode_xhtml_strict() throws Exception {
263         compatMode("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
264             + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
265     }
266 
267     private void compatMode(final String doctype) throws Exception {
268         final String html = doctype
269             + "<html>\n"
270             + "<head>\n"
271             + "  <script>\n"
272             + LOG_TITLE_FUNCTION
273             + "  function test() {\n"
274             + "    log(document.compatMode);\n"
275             + "  }\n"
276             + "  </script>\n"
277             + "</head>\n"
278             + "<body onload='test()'>\n"
279             + "</body>\n"
280             + "</html>";
281 
282         final WebDriver driver = loadPageVerifyTitle2(html);
283         if (driver instanceof HtmlUnitDriver) {
284             final HtmlPage page = (HtmlPage) getEnclosedPage();
285             assertEquals("BackCompat".equals(getExpectedAlerts()[0]), page.isQuirksMode());
286         }
287     }
288 
289     /**
290      * @throws Exception if the test fails
291      */
292     @Test
293     @Alerts("false")
294     public void uniqueID() throws Exception {
295         final String html = DOCTYPE_HTML
296             + "<html>\n"
297             + "<head>\n"
298             + "  <script>\n"
299             + LOG_TITLE_FUNCTION
300             + "  function test() {\n"
301             + "    log(document.uniqueID != undefined);\n"
302             + "  }\n"
303             + "  </script>\n"
304             + "</head>\n"
305             + "<body onload='test()'>\n"
306             + "</body>\n"
307             + "</html>";
308 
309         loadPageVerifyTitle2(html);
310     }
311 
312     /**
313      * @throws Exception if the test fails
314      */
315     @Test
316     @Alerts({"[object HTMLDivElement]", "[object HTMLUnknownElement]", "[object Element]"})
317     public void createDocumentNS() throws Exception {
318         final String html = DOCTYPE_HTML
319             + "<html>\n"
320             + "<head>\n"
321             + "<script>\n"
322             + "function test() {\n"
323             + LOG_TITLE_FUNCTION
324             + "  var elt = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');\n"
325             + "  log(elt);\n"
326             + "  var elt = document.createElementNS('http://www.w3.org/1999/xhtml', 'foo');\n"
327             + "  log(elt);\n"
328             + "  elt = document.createElementNS('blabla', 'div');\n"
329             + "  log(elt);\n"
330             + "}\n"
331             + "</script>\n"
332             + "</head>\n"
333             + "<body onload='test()'>\n"
334             + "</body>\n"
335             + "</html>";
336 
337         loadPageVerifyTitle2(html);
338     }
339 
340     /**
341      * @throws Exception if the test fails
342      */
343     @Test
344     @Alerts("[object SVGSVGElement]")
345     public void createDocumentNS_svg() throws Exception {
346         final String html = DOCTYPE_HTML
347             + "<html><body>\n"
348             + "<script>\n"
349             + LOG_TITLE_FUNCTION
350             + "try {\n"
351             + "  var elt = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n"
352             + "  log(elt);\n"
353             + "} catch(e) { logEx(e); }\n"
354             + "</script></body></html>";
355 
356         loadPageVerifyTitle2(html);
357     }
358 
359     /**
360      * @throws Exception if the test fails
361      */
362     @Test
363     @Alerts("[object SVGRectElement]")
364     public void createElementNS() throws Exception {
365         final String html = DOCTYPE_HTML
366             + "<html><head>\n"
367             + "<script>\n"
368             + LOG_TITLE_FUNCTION
369             + "  function test() {\n"
370             + "    log(document.createElementNS('http://www.w3.org/2000/svg', 'rect'));\n"
371             + "  }\n"
372             + "</script>\n"
373             + "</head><body onload='test()'>\n"
374             + "</body></html>";
375 
376         loadPageVerifyTitle2(html);
377     }
378 
379     /**
380      * @throws Exception if the test fails
381      */
382     @Test
383     @Alerts(DEFAULT = "TypeError",
384             FF = "NS_ERROR_NOT_AVAILABLE/Exception",
385             FF_ESR = "NS_ERROR_NOT_AVAILABLE/Exception")
386     @HtmlUnitNYI(FF = "TypeError",
387             FF_ESR = "TypeError")
388     public void createDocumentNS_xul() throws Exception {
389         final String html = DOCTYPE_HTML
390             + "<html><body>\n"
391             + "<script>\n"
392             + LOG_TITLE_FUNCTION
393             + "try {\n"
394             + "  var inner = document.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul',"
395             + "'label');\n"
396             + "  inner.setAttribute('value', 'Hello');\n"
397             + "  inner.style['fontFamily'] = 'inherit';\n"
398             + "  document.body.appendChild(inner);\n"
399             + "  log(document.body.lastChild.value);\n"
400             + "}\n"
401             + "catch(e) { logEx(e); }\n"
402             + "</script>\n"
403             + "</body>\n"
404             + "</html>";
405 
406         loadPageVerifyTitle2(html);
407     }
408 
409     /**
410      * @throws Exception if the test fails
411      */
412     @Test
413     @Alerts("true")
414     public void hasXmlNamespaceSupport() throws Exception {
415         final String html = DOCTYPE_HTML
416             + "<html><head>\n"
417             + "<script>\n"
418             + LOG_TITLE_FUNCTION
419             + "  function test() {\n"
420             + "    log(typeof(document.createElementNS) != \"undefined\");\n"
421             + "  }\n"
422             + "</script></head>\n"
423             + "<body onload='test()'>\n"
424             + "</body></html>";
425         loadPageVerifyTitle2(html);
426     }
427 
428     /**
429      * @throws Exception if the test fails
430      */
431     @Test
432     @Alerts({"[object HTMLCollection]", "0"})
433     public void applets() throws Exception {
434         final String html = DOCTYPE_HTML
435             + "<html>\n"
436             + "<head>\n"
437             + "<script>\n"
438             + LOG_TITLE_FUNCTION
439             + "function test() {\n"
440             + "  log(document.applets);\n"
441             + "  log(document.applets.length);\n"
442             + "}\n"
443             + "</script>\n"
444             + "</head>\n"
445             + "<body onload='test()'>\n"
446             + "</body>\n"
447             + "</html>";
448 
449         loadPageVerifyTitle2(html);
450     }
451 
452     /**
453      * @throws Exception if the test fails
454      */
455     @Test
456     @Alerts(DEFAULT = {"imported: [object HTMLScriptElement]", "replaced"},
457             CHROME = {"imported: [object HTMLScriptElement]", "o", "replaced"},
458             EDGE = {"imported: [object HTMLScriptElement]", "o", "replaced"})
459     @HtmlUnitNYI(CHROME = {"imported: [object HTMLScriptElement]", "replaced"},
460             EDGE = {"imported: [object HTMLScriptElement]", "replaced"})
461     public void importNode_script() throws Exception {
462         final String html = DOCTYPE_HTML
463             + "<html><head><script>\n"
464             + LOG_TITLE_FUNCTION
465             + "function test() {\n"
466             + "  try {\n"
467             + "    var d = document.implementation.createDocument(null, null, null);\n"
468             + "    var xhtml = \"<html xmlns='http://www.w3.org/1999/xhtml'><sc\" "
469             + "     + \"ript>log('o'); _scriptEvaluated=true;</scr\" + \"ipt></html>\";\n"
470             + "    var newDoc = (new DOMParser()).parseFromString(xhtml, 'text/xml');\n"
471             + "    var theScript = newDoc.getElementsByTagName('script')[0];\n"
472             + "    var importedScript = window.document.importNode(theScript, true);\n"
473             + "    log('imported: ' + importedScript);\n"
474             + "    var theSpan = document.getElementById('s1');\n"
475             + "    document.body.replaceChild(importedScript, theSpan);\n"
476             + "    log('replaced');\n"
477             + "  } catch(e) { logEx(e) }\n"
478             + "}\n"
479             + "</script></head><body onload='test()'>\n"
480             + "  <span id='s1'></span>\n"
481             + "</body></html>";
482 
483         loadPageVerifyTitle2(html);
484     }
485 
486     /**
487      * This one is like {@link #importNode_script()}, but the script is
488      * a child of the imported node.
489      * @throws Exception if the test fails
490      */
491     @Test
492     @Alerts(DEFAULT = {"imported: [object HTMLDivElement]", "replaced"},
493             CHROME = {"imported: [object HTMLDivElement]", "o", "replaced"},
494             EDGE = {"imported: [object HTMLDivElement]", "o", "replaced"})
495     @HtmlUnitNYI(CHROME = {"imported: [object HTMLDivElement]", "replaced"},
496             EDGE = {"imported: [object HTMLDivElement]", "replaced"})
497     public void importNode_scriptChild() throws Exception {
498         final String html = DOCTYPE_HTML
499             + "<html><head><script>\n"
500             + LOG_TITLE_FUNCTION
501             + "function test() {\n"
502             + "  try {\n"
503             + "    var d = document.implementation.createDocument(null, null, null);\n"
504             + "    var xhtml = \"<html xmlns='http://www.w3.org/1999/xhtml'><div id='myDiv'><sc\" "
505             + "     + \"ript>log('o'); _scriptEvaluated=true;</scr\" + \"ipt></div></html>\";\n"
506             + "    var newDoc = (new DOMParser()).parseFromString(xhtml, 'text/xml');\n"
507             + "    var theDiv = newDoc.getElementById('myDiv');\n"
508             + "    var importedDiv = window.document.importNode(theDiv, true);\n"
509             + "    log('imported: ' + importedDiv);\n"
510             + "    var theSpan = document.getElementById('s1');\n"
511             + "    document.body.replaceChild(importedDiv, theSpan);\n"
512             + "    log('replaced');\n"
513             + "  } catch(e) { logEx(e) }\n"
514             + "}\n"
515             + "</script></head><body onload='test()'>\n"
516             + "  <span id='s1'></span>\n"
517             + "</body></html>";
518 
519         loadPageVerifyTitle2(html);
520     }
521 
522     /**
523      * @throws Exception if an error occurs
524      */
525     @Test
526     @Alerts("clicked")
527     public void dispatchEvent() throws Exception {
528         final String html = DOCTYPE_HTML
529             + "<html>\n"
530             + "<script>\n"
531             + LOG_TITLE_FUNCTION
532             + "  function doTest() {\n"
533             + "    var e = document.createEvent('MouseEvents');\n"
534             + "    e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n"
535             + "    document.dispatchEvent(e);\n"
536             + "  }\n"
537             + "  function clickListener() {\n"
538             + "    log('clicked');\n"
539             + "  }\n"
540 
541             + "  document.addEventListener('click', clickListener, true);\n"
542             + "</script>\n"
543             + "<body onload='doTest()'>foo</body>\n"
544             + "</html>";
545 
546         loadPageVerifyTitle2(html);
547     }
548 
549     /**
550      * @throws Exception if an error occurs
551      */
552     @Test
553     @Alerts({"undefined", "TypeError"})
554     public void namespaces() throws Exception {
555         final String html =
556               "<body><script>\n"
557             + LOG_TITLE_FUNCTION
558             + "var ns = document.namespaces;\n"
559             + "log(ns);\n"
560             + "try {\n"
561             + "  log(ns.length);\n"
562             + "  ns.add('f', 'urn:f');\n"
563             + "  log(ns.length);\n"
564             + "  log(ns.item(0).name);\n"
565             + "  log(ns[0].name);\n"
566             + "  log(ns(0).name);\n"
567             + "  log(ns('f').name);\n"
568             + "  log(ns.item('f').urn);\n"
569             + "  log(ns['f'].urn);\n"
570             + "  log(ns == document.namespaces);\n"
571             + "}\n"
572             + "catch(e) { logEx(e) }\n"
573             + "</script></body>";
574 
575         loadPageVerifyTitle2(html);
576     }
577 
578     /**
579      * Verifies that we can store document methods and use them from a variable (IE only).
580      * @throws Exception if the test fails
581      */
582     @Test
583     @Alerts({"TypeError", "TypeError"})
584     public void documentMethodsWithoutDocument() throws Exception {
585         final String html
586             = "<div id='d' name='d'>d</div>\n"
587             + "<script>\n"
588             + LOG_TITLE_FUNCTION
589             + "try {\n"
590             + "  var i = document.getElementById;\n"
591             + "  log(i('d').id);\n"
592             + "} catch(e) { logEx(e) }\n"
593 
594             + "try {\n"
595             + "  var n = document.getElementsByName;\n"
596             + "  log(n('d').length);\n"
597             + "} catch(e) { logEx(e) }\n"
598             + "</script>";
599         loadPageVerifyTitle2(html);
600     }
601 
602     /**
603      * @throws Exception if an error occurs
604      */
605     @Test
606     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
607     public void bgColor() throws Exception {
608         final String html = DOCTYPE_HTML
609             + "<html>\n"
610             + "  <head>\n"
611             + "    <script>\n"
612             + LOG_TITLE_FUNCTION
613             + "      function test() {\n"
614             + "        var b = document.getElementById('body');\n"
615             + "        log(document.bgColor);\n"
616             + "        log(b.bgColor);\n"
617             + "        document.bgColor = '#0000aa';\n"
618             + "        log(document.bgColor);\n"
619             + "        log(b.bgColor);\n"
620             + "        document.bgColor = 'x';\n"
621             + "        log(document.bgColor);\n"
622             + "        log(b.bgColor);\n"
623             + "      }\n"
624             + "    </script>\n"
625             + "  </head>\n"
626             + "  <body id='body' onload='test()'>blah</body>\n"
627             + "</html>";
628         loadPageVerifyTitle2(html);
629     }
630 
631     /**
632      * @throws Exception if an error occurs
633      */
634     @Test
635     @Alerts({"[object HTMLCollection]", "4", "red"})
636     public void identicalIDs() throws Exception {
637         final String html = DOCTYPE_HTML
638             + "<html>\n"
639             + "  <head>\n"
640             + "    <script>\n"
641             + LOG_TITLE_FUNCTION
642             + "      function test() {\n"
643             + "        log(document.all['Item']);\n"
644             + "        log(document.all.Item.length);\n"
645             + "        if (document.all.Item.length) {\n"
646             + "          log(document.all.Item[1].style.color);\n"
647             + "        }\n"
648             + "      }\n"
649             + "    </script>\n"
650             + "  </head>\n"
651             + "  <body id='body' onload='test()'>\n"
652             + "    <span id='Item' style='color:black'></span>\n"
653             + "    <span id='Item' style='color:red'></span>\n"
654             + "    <span id='Item' style='color:green'></span>\n"
655             + "    <span id='Item' style='color:blue'></span>\n"
656             + "  </body>\n"
657             + "</html>";
658         loadPageVerifyTitle2(html);
659     }
660 
661     /**
662      * Test that {@code document.forms.form_name} should be evaluated to {@code undefined} if the form has a prefix.
663      * @throws Exception if the test fails
664      */
665     @Test
666     @Alerts("undefined")
667     public void prefix() throws Exception {
668         final String html = DOCTYPE_HTML
669             + "<html><head><script>\n"
670             + LOG_TITLE_FUNCTION
671             + "function doTest() {\n"
672             + "  log(document.forms.fmLogin);\n"
673             + "}\n"
674             + "</script></head>\n"
675             + "<body onload='doTest()'>\n"
676             + "  <s:form name='fmLogin' action='doLogin' method='POST'>\n"
677             + "    <s:hidden name='hdUserID'/>\n"
678             + "    <s:hidden name='hdPassword'/>\n"
679             + "  </s:form>\n"
680             + "</body></html>";
681 
682         loadPageVerifyTitle2(html);
683     }
684 
685     /**
686      * Warning: this test works fine in real FF8 when started manually but fails through WebDriver.
687      * Warning: opens a modal panel when run through IEDriver which needs to be closed MANUALLY.
688      * If not all following test will fail.
689      * @throws Exception if an error occurs
690      */
691     @Test
692     @Alerts(DEFAULT = {"0", "IndexSizeError/DOMException"},
693             FF = {"1", "[object HTMLBodyElement]"},
694             FF_ESR = {"1", "[object HTMLBodyElement]"})
695     public void designMode_selectionRange_empty() throws Exception {
696         designMode_selectionRange("");
697     }
698 
699     /**
700      * Warning: opens a modal panel when run through IEDriver which needs to be closed MANUALLY.
701      * If not all following test will fail.
702      * @throws Exception if an error occurs
703      */
704     @Test
705     @Alerts(DEFAULT = {"0", "IndexSizeError/DOMException"},
706             FF = {"1", "[object Text]"},
707             FF_ESR = {"1", "[object Text]"})
708     public void designMode_selectionRange_text() throws Exception {
709         designMode_selectionRange("hello");
710     }
711 
712     private void designMode_selectionRange(final String bodyContent) throws Exception {
713         final String html = DOCTYPE_HTML
714             + "<html>\n"
715             + "<head>\n"
716             + "<script>\n"
717             + LOG_TITLE_FUNCTION
718             + "function doTest() {\n"
719             + "  try {\n"
720             + "    document.designMode = 'on';\n"
721             + "    var s = window.getSelection();\n"
722             + "    log(s.rangeCount);\n"
723             + "    log(s.getRangeAt(0).startContainer);\n"
724             + "  } catch(e) {logEx(e); }\n"
725             + "}\n"
726             + "</script></head>\n"
727             + "<body onload='doTest()'>" // no \n here!
728             + bodyContent
729             + "</body></html>";
730 
731         loadPageVerifyTitle2(html);
732     }
733 
734     /**
735      * @throws Exception if the test fails
736      */
737     @Test
738     @Alerts("false")
739     public void all_detection() throws Exception {
740         final String html = DOCTYPE_HTML
741             + "<html><head><script>\n"
742             + LOG_TITLE_FUNCTION
743             + "  function test() {\n"
744             + "    log(!(!document.all));\n"
745             + "  }\n"
746             + "</script></head><body onload='test()'>\n"
747             + "</body></html>";
748 
749         loadPageVerifyTitle2(html);
750     }
751 
752     /**
753      * @throws Exception if the test fails
754      */
755     @Test
756     @Alerts("[object HTMLAllCollection]")
757     public void all_scriptableToString() throws Exception {
758         final String html = DOCTYPE_HTML
759             + "<html><head><script>\n"
760             + LOG_TITLE_FUNCTION
761             + "  function test() {\n"
762             + "    log(document.all);\n"
763             + "  }\n"
764             + "</script></head><body onload='test()'>\n"
765             + "</body></html>";
766 
767         loadPageVerifyTitle2(html);
768     }
769 
770     /**
771      * @throws Exception if the test fails
772      */
773     @Test
774     @Alerts("not defined")
775     public void frames() throws Exception {
776         final String html = DOCTYPE_HTML
777             + "<html><head><script>\n"
778             + LOG_TITLE_FUNCTION
779             + "function test() {\n"
780             + "  if (document.frames) {\n"
781             + "    log(document.frames == window.frames);\n"
782             + "    log(document.frames.length);\n"
783             + "  } else\n"
784             + "    log('not defined');\n"
785             + "}\n"
786             + "</script></head>\n"
787             + "<body onload='test();'>\n"
788             + "  <iframe src='about:blank' name='foo'></iframe>\n"
789             + "</body></html>";
790 
791         loadPageVerifyTitle2(html);
792     }
793 
794     /**
795      * IE allows document.frameName to access a frame window.
796      * @throws Exception if the test fails
797      */
798     @Test
799     @Alerts(DEFAULT = {"[object Window]", "true"},
800             FF_ESR = {"undefined", "false"})
801     public void frameAccessByName() throws Exception {
802         final String html = DOCTYPE_HTML
803             + "<html><head><script>\n"
804             + LOG_TITLE_FUNCTION
805             + "function test() {\n"
806             + "  log(document.foo);\n"
807             + "  log(window.frames[0] == document.foo);\n"
808             + "}\n"
809             + "</script></head>\n"
810             + "<body onload='test()'>\n"
811             + "  <iframe src='about:blank' name='foo'></iframe>\n"
812             + "</body></html>";
813 
814         loadPageVerifyTitle2(html);
815     }
816 
817     /**
818      * @throws Exception if the test fails
819      */
820     @Test
821     @Alerts({"0", "0"})
822     public void getElementsByName_notFound() throws Exception {
823         final String html = DOCTYPE_HTML
824             + "<html><head><script>\n"
825             + LOG_TITLE_FUNCTION
826             + "function doTest() {\n"
827             + "  log(document.getElementsByName(null).length);\n"
828             + "  log(document.getElementsByName('foo').length);\n"
829             + "}\n"
830             + "</script></head><body onload='doTest()'>\n"
831             + "  <div name='test'></div>\n"
832             + "</body></html>";
833 
834         loadPageVerifyTitle2(html);
835     }
836 
837     /**
838      * @throws Exception if the test fails
839      */
840     @Test
841     @Alerts(DEFAULT = {"2", "0", "0"},
842             FF = {"0", "0", "0"},
843             FF_ESR = {"0", "0", "0"})
844     public void getElementsByName_emptyName() throws Exception {
845         final String html = DOCTYPE_HTML
846             + "<html><head><script>\n"
847             + LOG_TITLE_FUNCTION
848             + "  function test() {\n"
849             + "    log(document.getElementsByName('').length);\n"
850             + "    log(document.getElementsByName(' ').length);\n"
851             + "    log(document.getElementsByName(null).length);\n"
852             + "  }\n"
853             + "</script></head><body onload='test()'>\n"
854             + "  <div name=''></div>\n"
855             + "  <div name=''></div>\n"
856             + "  <div></div>\n"
857             + "  <div></div>\n"
858             + "</body></html>";
859 
860         loadPageVerifyTitle2(html);
861     }
862 
863     /**
864      * @throws Exception if the test fails
865      */
866     @Test
867     @Alerts({"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2"})
868     public void getElementsByName_elements() throws Exception {
869         final String html = DOCTYPE_HTML
870             + "<html><head><script>\n"
871             + LOG_TITLE_FUNCTION
872             + "  function test() {\n"
873             + "    try {\n"
874             + "      log(document.getElementsByName('form1').length);\n"
875             + "    } catch(e) { log('exception:f1') }\n"
876             + "    try {\n"
877             + "      log(document.getElementsByName('form2').length);\n"
878             + "    } catch(e) { log('exception:f2') }\n"
879             + "    try {\n"
880             + "      log(document.getElementsByName('frame1').length);\n"
881             + "    } catch(e) { log('exception:f1') }\n"
882             + "    try {\n"
883             + "      log(document.getElementsByName('frame2').length);\n"
884             + "    } catch(e) { log('exception:f2') }\n"
885             + "    try {\n"
886             + "      log(document.getElementsByName('input1').length);\n"
887             + "    } catch(e) { log('exception:i1') }\n"
888             + "    try {\n"
889             + "      log(document.getElementsByName('input2').length);\n"
890             + "    } catch(e) { log('exception:i2') }\n"
891             + "    try {\n"
892             + "      log(document.getElementsByName('anchor1').length);\n"
893             + "    } catch(e) { log('exception:a1') }\n"
894             + "    try {\n"
895             + "      log(document.getElementsByName('anchor2').length);\n"
896             + "    } catch(e) { log('exception:a2') }\n"
897             + "    try {\n"
898             + "      log(document.getElementsByName('image1').length);\n"
899             + "    } catch(e) { log('exception:i1') }\n"
900             + "    try {\n"
901             + "      log(document.getElementsByName('image2').length);\n"
902             + "    } catch(e) { log('exception:i2') }\n"
903             + "    try {\n"
904             + "      log(document.getElementsByName('element1').length);\n"
905             + "    } catch(e) { log('exception:e1') }\n"
906             + "    try {\n"
907             + "      log(document.getElementsByName('element2').length);\n"
908             + "    } catch(e) { log('exception:e2') }\n"
909             + "  }\n"
910             + "</script></head><body onload='test()'>\n"
911             + "  <form name='form1'></form>\n"
912             + "  <form name='form2'></form>\n"
913             + "  <form name='form2'></form>\n"
914             + "  <iframe name='frame1'></iframe>\n"
915             + "  <iframe name='frame2'></iframe>\n"
916             + "  <iframe name='frame2'></iframe>\n"
917             + "  <input type='text' name='input1' value='1'/>\n"
918             + "  <input type='text' name='input2' value='2'/>\n"
919             + "  <input type='text' name='input2' value='3'/>\n"
920             + "  <a name='anchor1'></a>\n"
921             + "  <a name='anchor2'></a>\n"
922             + "  <a name='anchor2'></a>\n"
923             + "  <img name='image1'>\n"
924             + "  <img name='image2'>\n"
925             + "  <img name='image2'>\n"
926             + "  <div name='element1'></table>\n"
927             + "  <div name='element2'></div>\n"
928             + "  <div name='element2'></div>\n"
929             + "</body></html>";
930 
931         loadPageVerifyTitle2(html);
932     }
933 
934     /**
935      * @throws Exception if the test fails
936      */
937     @Test
938     @Alerts({"1", "2"})
939     public void getElementsByName_frame() throws Exception {
940         final String html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\""
941             + "\"http://www.w3.org/TR/html4/frameset.dtd\">\n"
942             + "<html><head><script>\n"
943             + LOG_TITLE_FUNCTION
944             + "  function test() {\n"
945             + "    try {\n"
946             + "      log(document.getElementsByName('frame1').length);\n"
947             + "    } catch(e) { log('exception:f1') }\n"
948             + "    try {\n"
949             + "      log(document.getElementsByName('frame2').length);\n"
950             + "    } catch(e) { log('exception:f2') }\n"
951             + "  }\n"
952             + "</script></head>\n"
953             + "<frameset onload='test()'>\n"
954             + "  <frame src='" + URL_SECOND + "' name='frame1'>\n"
955             + "  <frame src='" + URL_SECOND + "' name='frame2'>\n"
956             + "  <frame src='" + URL_SECOND + "' name='frame2'>\n"
957             + "</frameset>\n"
958             + "</html>";
959 
960         final String frame = DOCTYPE_HTML
961                 + "<html><head><title>frame</title></head><body></body></html>";
962         getMockWebConnection().setDefaultResponse(frame);
963 
964         loadPageVerifyTitle2(html);
965     }
966 
967     /**
968      * @throws Exception if the test fails
969      */
970     @Test
971     @Alerts({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "9"})
972     public void getElementsByName_changedAfterGet() throws Exception {
973         final String html = DOCTYPE_HTML
974             + "<html><head><script>\n"
975             + LOG_TITLE_FUNCTION
976             + "  function test() {\n"
977             // 1
978             + "    var collection = document.getElementsByName('image1');\n"
979             + "    log(collection.length);\n"
980 
981             // 2
982             + "    var newImage1 = document.createElement('img');\n"
983             + "    newImage1.name = 'image1';\n"
984             + "    document.getElementById('outer1').appendChild(newImage1);\n"
985             + "    log(collection.length);\n"
986 
987             // 3
988             + "    var newImage2 = document.createElement('img');\n"
989             + "    newImage2.name = 'image1';\n"
990             + "    document.getElementById('outer2').insertBefore(newImage2, null);\n"
991             + "    log(collection.length);\n"
992 
993             // 4
994             + "    var newImage3 = document.createElement('img');\n"
995             + "    newImage3.name = 'image1';\n"
996             + "    document.getElementById('outer3').replaceChild(newImage3, document.getElementById('inner3'));\n"
997             + "    log(collection.length);\n"
998 
999             // 5
1000             + "    document.getElementById('outer4').outerHTML = '<img name=\"image1\">';\n"
1001             + "    log(collection.length);\n"
1002 
1003             // 6
1004             + "    document.getElementById('outer5').innerHTML = '<img name=\"image1\">';\n"
1005             + "    log(collection.length);\n"
1006 
1007             // 7
1008             + "    document.getElementById('outer6').insertAdjacentHTML('beforeend', '<img name=\"image1\">');\n"
1009             + "    log(collection.length);\n"
1010 
1011             // 8
1012             + "    document.getElementById('image3').setAttribute('name', 'image1');\n"
1013             + "    log(collection.length);\n"
1014 
1015             // 9
1016             + "    var newAttr = document.createAttribute('name');\n"
1017             + "    newAttr.nodeValue = 'image1';\n"
1018             + "    document.getElementById('image4').setAttributeNode(newAttr);\n"
1019             + "    log(collection.length);\n"
1020 
1021             // 10
1022             + "    try {\n"
1023             + "      document.getElementById('image5').setAttributeNS(null, 'name', 'image1');\n"
1024             + "      log(collection.length);\n"
1025             + "    } catch(e) { log('exception:setAttributeNS') }\n"
1026 
1027             // 9
1028             + "    document.getElementById('outer1').removeChild(newImage1);\n"
1029             + "    log(collection.length);\n"
1030             + "  }\n"
1031             + "</script></head><body onload='test()'>\n"
1032             + "  <img name='image1'>\n"
1033             + "  <div id='outer1'></div>\n"
1034             + "  <div id='outer2'></div>\n"
1035             + "  <div id='outer3'><div id='inner3'></div></div>\n"
1036             + "  <div id='outer4'></div>\n"
1037             + "  <div id='outer5'></div>\n"
1038             + "  <div id='outer6'></div>\n"
1039             + "  <img id='image2'>\n"
1040             + "  <img id='image3'>\n"
1041             + "  <img id='image4'>\n"
1042             + "  <img id='image5'>\n"
1043             + "</body></html>";
1044 
1045         loadPageVerifyTitle2(html);
1046     }
1047 
1048     /**
1049      * Contains the cases of test {@link #getElementsByName_changedAfterGet()} that are not yet implemented.<br>
1050      * If a case gets implemented, move it to {@link #getElementsByName_changedAfterGet()}.
1051      * @throws Exception if the test fails
1052      */
1053     @Test
1054     @Alerts({"1", "2"})
1055     public void getElementsByName_changedAfterGet2() throws Exception {
1056         final String html = DOCTYPE_HTML
1057             + "<html><head><script>\n"
1058             + LOG_TITLE_FUNCTION
1059             + "  function test() {\n"
1060             + "    var collection = document.getElementsByName('image1');\n"
1061             + "    log(collection.length);\n"
1062             + "    document.getElementById('image2').name = 'image1';\n"
1063             + "    log(collection.length);\n"
1064             + "  }\n"
1065             + "</script></head><body onload='test()'>\n"
1066             + "  <img name='image1'>\n"
1067             + "  <img id='image2'>\n"
1068             + "</body></html>";
1069 
1070         loadPageVerifyTitle2(html);
1071     }
1072 
1073     /**
1074      * @throws Exception if the test fails
1075      */
1076     @Test
1077     @Alerts({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "9"})
1078     public void getElementsByName_changedAfterGet_nested() throws Exception {
1079         final String html = DOCTYPE_HTML
1080             + "<html><head><script>\n"
1081             + LOG_TITLE_FUNCTION
1082             + "  function test() {\n"
1083             // 1
1084             + "    var collection = document.getElementsByName('image1');\n"
1085             + "    log(collection.length);\n"
1086 
1087             // 2
1088             + "    var newImage1 = document.createElement('img');\n"
1089             + "    newImage1.name = 'image1';\n"
1090             + "    document.getElementById('outer1').appendChild(newImage1);\n"
1091             + "    log(collection.length);\n"
1092 
1093             // 3
1094             + "    var newImage2 = document.createElement('img');\n"
1095             + "    newImage2.name = 'image1';\n"
1096             + "    document.getElementById('outer2').insertBefore(newImage2, null);\n"
1097             + "    log(collection.length);\n"
1098 
1099             // 4
1100             + "    var newImage3 = document.createElement('img');\n"
1101             + "    newImage3.name = 'image1';\n"
1102             + "    document.getElementById('outer3').replaceChild(newImage3, document.getElementById('inner3'));\n"
1103             + "    log(collection.length);\n"
1104 
1105             // 5
1106             + "    document.getElementById('outer4').outerHTML = '<img name=\"image1\">';\n"
1107             + "    log(collection.length);\n"
1108 
1109             // 6
1110             + "    document.getElementById('outer5').innerHTML = '<img name=\"image1\">';\n"
1111             + "    log(collection.length);\n"
1112 
1113             // 7
1114             + "    document.getElementById('outer6').insertAdjacentHTML('beforeend', '<img name=\"image1\">');\n"
1115             + "    log(collection.length);\n"
1116 
1117             // 8
1118             + "    document.getElementById('image3').setAttribute('name', 'image1');\n"
1119             + "    log(collection.length);\n"
1120 
1121             // 9
1122             + "    var newAttr = document.createAttribute('name');\n"
1123             + "    newAttr.nodeValue = 'image1';\n"
1124             + "    document.getElementById('image4').setAttributeNode(newAttr);\n"
1125             + "    log(collection.length);\n"
1126 
1127             // 10
1128             + "    try {\n"
1129             + "      document.getElementById('image5').setAttributeNS(null, 'name', 'image1');\n"
1130             + "      log(collection.length);\n"
1131             + "    } catch(e) { log('exception:setAttributeNS') }\n"
1132 
1133             // 9
1134             + "    document.getElementById('outer1').removeChild(newImage1);\n"
1135             + "    log(collection.length);\n"
1136             + "  }\n"
1137             + "</script></head><body onload='test()'>\n"
1138             + "  <div>\n"
1139             + "    <img name='image1'>\n"
1140             + "    <div id='outer1'></div>\n"
1141             + "    <div id='outer2'></div>\n"
1142             + "    <div id='outer3'><div id='inner3'></div></div>\n"
1143             + "    <div id='outer4'></div>\n"
1144             + "    <div id='outer5'></div>\n"
1145             + "    <div id='outer6'></div>\n"
1146             + "    <img id='image2'>\n"
1147             + "    <img id='image3'>\n"
1148             + "    <img id='image4'>\n"
1149             + "    <img id='image5'>\n"
1150             + "  </div>\n"
1151             + "</body></html>";
1152 
1153         loadPageVerifyTitle2(html);
1154     }
1155 
1156     /**
1157      * Contains the cases of test {@link #getElementsByName_changedAfterGet_nested()} that are not yet implemented.<br>
1158      * If a case gets implemented, move it to {@link #getElementsByName_changedAfterGet_nested()}.
1159      * @throws Exception if the test fails
1160      */
1161     @Test
1162     @Alerts({"1", "2"})
1163     public void getElementsByName_changedAfterGet_nested2() throws Exception {
1164         final String html = DOCTYPE_HTML
1165             + "<html><head><script>\n"
1166             + LOG_TITLE_FUNCTION
1167             + "  function test() {\n"
1168             + "    var collection = document.getElementsByName('image1');\n"
1169             + "    log(collection.length);\n"
1170             + "    document.getElementById('image2').name = 'image1';\n"
1171             + "    log(collection.length);\n"
1172             + "  }\n"
1173             + "</script></head><body onload='test()'>\n"
1174             + "  <div>\n"
1175             + "    <img name='image1'>\n"
1176             + "    <img id='image2'>\n"
1177             + "  </div>\n"
1178             + "</body></html>";
1179 
1180         loadPageVerifyTitle2(html);
1181     }
1182 
1183     /**
1184      * Regression test for a bug introduced by the document proxy and detected by the Dojo JavaScript library tests.
1185      * @throws Exception if an error occurs
1186      */
1187     @Test
1188     @Alerts("true")
1189     public void equalityViaDifferentPaths() throws Exception {
1190         final String html = DOCTYPE_HTML
1191             + "<html><body>\n"
1192             + "<script>"
1193             + LOG_TITLE_FUNCTION
1194             + "log(document.body.parentNode.parentNode === document)\n"
1195             + "</script>\n"
1196             + "</body></html>";
1197         loadPageVerifyTitle2(html);
1198     }
1199 
1200     /**
1201      * @throws Exception if the test fails
1202      */
1203     @Test
1204     @Alerts("TypeError")
1205     public void getBoxObjectFor() throws Exception {
1206         final String html = DOCTYPE_HTML
1207             + "<html><head><script>\n"
1208             + LOG_TITLE_FUNCTION
1209             + "function doTest() {\n"
1210             + "  var e = document.getElementById('log');\n"
1211             + "  try {\n"
1212             + "    var a = document.getBoxObjectFor(e);\n"
1213             + "    log(a);\n"
1214             + "    log(a === document.getBoxObjectFor(e));\n"
1215             + "    log(a.screenX > 0);\n"
1216             + "    log(a.screenY > 0);\n"
1217             + "  } catch(e) { logEx(e) }\n"
1218             + "}\n"
1219             + "</script></head><body onload='doTest()'>\n"
1220             + "<div id='log'></div>\n"
1221             + "</body></html>";
1222 
1223         loadPageVerifyTitle2(html);
1224     }
1225 
1226     /**
1227      * @throws Exception if the test fails
1228      */
1229     @Test
1230     @Alerts({"32 commands supported", "not supported: foo, 123"})
1231     @BuggyWebDriver({"31 commands supported", "not supported: Paste, foo, 123"})
1232     public void queryCommandSupported_common() throws Exception {
1233         final String[] commands = {"BackColor", "Bold",
1234             "Copy", "CreateLink", "Cut", "Delete",
1235             "FontName", "FontSize", "ForeColor", "FormatBlock",
1236             "Indent", "InsertHorizontalRule", "InsertImage", "InsertOrderedList",
1237             "InsertParagraph", "InsertUnorderedList", "Italic",
1238             "JustifyCenter", "JustifyFull", "JustifyLeft", "JustifyRight",
1239             "Outdent", "Paste", "Redo", "RemoveFormat",
1240             "SelectAll", "StrikeThrough", "Subscript", "Superscript",
1241             "Underline", "Undo", "Unlink",
1242             "foo", "123" };
1243         queryCommandSupported(commands);
1244     }
1245 
1246     /**
1247      * @throws Exception if the test fails
1248      */
1249     @Test
1250     @Alerts(DEFAULT = {"3 commands supported", "not supported: 2D-Position, AbsolutePosition, "
1251                     + "BlockDirLTR, BlockDirRTL, BrowseMode, ClearAuthenticationCache, CreateBookmark, "
1252                     + "DirLTR, DirRTL, EditMode, InlineDirLTR, InlineDirRTL, InsertButton, InsertFieldset, "
1253                     + "InsertIFrame, InsertInputButton, InsertInputCheckbox, InsertInputFileUpload, "
1254                     + "InsertInputHidden, InsertInputImage, InsertInputPassword, InsertInputRadio, "
1255                     + "InsertInputReset, InsertInputSubmit, InsertInputText, InsertMarquee, InsertSelectDropdown, "
1256                     + "InsertSelectListbox, InsertTextArea, LiveResize, MultipleSelection, "
1257                     + "Open, OverWrite, PlayImage, Refresh, RemoveParaFormat, SaveAs, SizeToControl, "
1258                     + "SizeToControlHeight, SizeToControlWidth, Stop, StopImage, UnBookmark"},
1259             FF = "0 commands supported",
1260             FF_ESR = "0 commands supported")
1261     public void queryCommandSupported_disctinct() throws Exception {
1262         final String[] commands = {"2D-Position", "AbsolutePosition",
1263             "BlockDirLTR", "BlockDirRTL", "BrowseMode",
1264             "ClearAuthenticationCache", "CreateBookmark",
1265             "DirLTR", "DirRTL", "EditMode",
1266             "InlineDirLTR", "InlineDirRTL", "InsertButton", "InsertFieldset",
1267             "InsertIFrame", "InsertInputButton", "InsertInputCheckbox", "InsertInputFileUpload",
1268             "InsertInputHidden", "InsertInputImage", "InsertInputPassword", "InsertInputRadio",
1269             "InsertInputReset", "InsertInputSubmit", "InsertInputText", "InsertMarquee",
1270             "InsertSelectDropdown", "InsertSelectListbox", "InsertTextArea",
1271             "JustifyNone",
1272             "LiveResize", "MultipleSelection", "Open", "OverWrite",
1273             "PlayImage", "Print", "Refresh", "RemoveParaFormat",
1274             "SaveAs", "SizeToControl", "SizeToControlHeight", "SizeToControlWidth", "Stop", "StopImage",
1275             "UnBookmark", "Unselect"};
1276 
1277         queryCommandSupported(commands);
1278     }
1279 
1280     private void queryCommandSupported(final String... commands) throws Exception {
1281         final String jsCommandArray = "['" + String.join("', '", commands) + "']";
1282         final String html = DOCTYPE_HTML
1283             + "<html><head><script>\n"
1284             + LOG_TITLE_FUNCTION
1285             + "function doTest() {\n"
1286             + "  var cmds = " + jsCommandArray + ";\n"
1287             + "  var nbSupported = 0;\n"
1288             + "  var cmdsNotSupported = [];\n"
1289             + "  try {\n"
1290             + "    for (var i = 0; i < cmds.length; i++) {\n"
1291             + "      var cmd = cmds[i];\n"
1292             + "      var b = document.queryCommandSupported(cmd);\n"
1293             + "      if (b)\n"
1294             + "        nbSupported++;\n"
1295             + "      else\n"
1296             + "        cmdsNotSupported[cmdsNotSupported.length] = cmd;\n"
1297             + "    }\n"
1298             + "  } catch(e) { logEx(e); }\n"
1299             + "  log(nbSupported + ' commands supported');\n"
1300             + "  if (nbSupported != 0 && cmdsNotSupported.length > 0)\n"
1301             + "    log('not supported: ' + cmdsNotSupported.join(', '));\n"
1302             + "}\n"
1303             + "</script></head><body onload='doTest()'>\n"
1304             + "<div id='log'></div>\n"
1305             + "</body></html>";
1306 
1307         loadPageVerifyTitle2(html);
1308     }
1309 
1310     /**
1311      * @throws Exception if the test fails
1312      */
1313     @Test
1314     @Alerts({"3", "div1"})
1315     public void querySelectorAll() throws Exception {
1316         final String html = DOCTYPE_HTML
1317             + "<html><head>\n"
1318             + "<style>\n"
1319             + "  .red   {color:#FF0000;}\n"
1320             + "  .green {color:#00FF00;}\n"
1321             + "  .blue  {color:#0000FF;}\n"
1322             + "</style>\n"
1323             + "<script>\n"
1324             + "function test() {\n"
1325             + LOG_TITLE_FUNCTION
1326             + "  var redTags = document.querySelectorAll('.green,.red');\n"
1327             + "  log(redTags.length);\n"
1328             + "  log(redTags.item(0).id);\n"
1329             + "}\n"
1330             + "</script></head><body onload='test()'>\n"
1331             + "  <div id='div1' class='red'>First</div>\n"
1332             + "  <div id='div2' class='red'>Second</div>\n"
1333             + "  <div id='div3' class='green'>Third</div>\n"
1334             + "  <div id='div4' class='blue'>Fourth</div>\n"
1335             + "</body></html>";
1336 
1337         loadPageVerifyTitle2(html);
1338     }
1339 
1340     /**
1341      * @throws Exception if the test fails
1342      */
1343     @Test
1344     @Alerts("[object NodeList]")
1345     public void querySelectorAllType() throws Exception {
1346         final String html = DOCTYPE_HTML
1347             + "<html><head>\n"
1348             + "<script>\n"
1349             + LOG_TITLE_FUNCTION
1350             + "function test() {\n"
1351             + "  log(document.querySelectorAll('html'));\n"
1352             + "}\n"
1353             + "</script></head>\n"
1354             + "<body onload='test()'>\n"
1355             + "</body></html>";
1356 
1357         loadPageVerifyTitle2(html);
1358     }
1359 
1360     /**
1361      * @throws Exception if the test fails
1362      */
1363     @Test
1364     @Alerts("SyntaxError/DOMException")
1365     public void querySelectorAll_badSelector() throws Exception {
1366         for (final String selector : JQUERY_CUSTOM_SELECTORS) {
1367             doTestQuerySelectorAll_badSelector(selector);
1368         }
1369     }
1370 
1371     private void doTestQuerySelectorAll_badSelector(final String selector) throws Exception {
1372         final String html = DOCTYPE_HTML
1373             + "<html><body><script>\n"
1374             + LOG_TITLE_FUNCTION
1375             + "try {\n"
1376             + "  document.querySelectorAll('" + selector + "');\n"
1377             + "  log('working');\n"
1378             + "} catch(e) { logEx(e); }\n"
1379             + "</script></body></html>";
1380 
1381         loadPageVerifyTitle2(html);
1382     }
1383 
1384     /**
1385      * @throws Exception if the test fails
1386      */
1387     @Test
1388     @Alerts("SyntaxError/DOMException")
1389     public void querySelector_badSelector() throws Exception {
1390         for (final String selector : JQUERY_CUSTOM_SELECTORS) {
1391             doTestQuerySelector_badSelector(selector);
1392         }
1393     }
1394 
1395     private void doTestQuerySelector_badSelector(final String selector) throws Exception {
1396         final String html = DOCTYPE_HTML
1397             + "<html><body><script>\n"
1398             + LOG_TITLE_FUNCTION
1399             + "try {\n"
1400             + "  document.querySelector('" + selector + "');\n"
1401             + "  log('working: " + selector + "');\n"
1402             + "} catch(e) { logEx(e); }\n"
1403             + "</script></body></html>";
1404 
1405         loadPageVerifyTitle2(html);
1406     }
1407 
1408     /**
1409      * @throws Exception if the test fails
1410      */
1411     @Test
1412     @Alerts({"3", "div1"})
1413     public void querySelectorAll_quirks() throws Exception {
1414         final String html = DOCTYPE_HTML
1415             + "<html>\n"
1416             + "<head>\n"
1417             + "<meta http-equiv='X-UA-Compatible' content='IE=7' />\n"
1418             + "<style>\n"
1419             + "  .red   {color:#FF0000;}\n"
1420             + "  .green {color:#00FF00;}\n"
1421             + "  .blue  {color:#0000FF;}\n"
1422             + "</style>\n"
1423             + "<script>\n"
1424             + LOG_TITLE_FUNCTION
1425             + "function test() {\n"
1426             + "  if(document.querySelectorAll) {\n"
1427             + "    var redTags = document.querySelectorAll('.green,.red');\n"
1428             + "    log(redTags.length);\n"
1429             + "    log(redTags.item(0).id);\n"
1430             + "  }\n"
1431             + "  else\n"
1432             + "    log('undefined');\n"
1433             + "}\n"
1434             + "</script></head>\n"
1435             + "<body onload='test()'>\n"
1436             + "  <div id='div1' class='red'>First</div>\n"
1437             + "  <div id='div2' class='red'>Second</div>\n"
1438             + "  <div id='div3' class='green'>Third</div>\n"
1439             + "  <div id='div4' class='blue'>Fourth</div>\n"
1440             + "</body></html>";
1441 
1442         loadPageVerifyTitle2(html);
1443     }
1444 
1445     /**
1446      * @throws Exception if the test fails
1447      */
1448     @Test
1449     @Alerts("3")
1450     public void querySelectorAll_implicitAttribute() throws Exception {
1451         final String html = DOCTYPE_HTML
1452             + "<html><head>\n"
1453             + "<script>\n"
1454             + LOG_TITLE_FUNCTION
1455             + "function test() {\n"
1456             + "  var result = document.querySelectorAll('[disabled]');\n"
1457             + "  log(result.length);\n"
1458             + "}\n"
1459             + "</script></head><body onload='test()'>\n"
1460             + "  <select name='select4' id='select4' multiple='multiple'>\n"
1461             + "    <optgroup disabled='disabled'>\n"
1462             + "      <option id='option4a' class='emptyopt' value=''>Nothing</option>\n"
1463             + "      <option id='option4b' disabled='disabled' selected='selected' value='1'>1</option>\n"
1464             + "      <option id='option4c' selected='selected' value='2'>2</option>\n"
1465             + "    </optgroup>\n"
1466             + "    <option selected='selected' disabled='disabled' id='option4d' value='3'>3</option>\n"
1467             + "    <option id='option4e'>no value</option>\n"
1468             + "    </select>\n"
1469             + "</body></html>";
1470 
1471         loadPageVerifyTitle2(html);
1472     }
1473 
1474     /**
1475      * @throws Exception if the test fails
1476      */
1477     @Test
1478     @Alerts({"div1", "null"})
1479     public void querySelector() throws Exception {
1480         final String html = DOCTYPE_HTML
1481             + "<html><head>\n"
1482             + "<style>\n"
1483             + "  .red   {color:#FF0000;}\n"
1484             + "  .green {color:#00FF00;}\n"
1485             + "  .blue  {color:#0000FF;}\n"
1486             + "</style>\n"
1487             + "<script>\n"
1488             + LOG_TITLE_FUNCTION
1489             + "function test() {\n"
1490             + "  log(document.querySelector('.green,.red').id);\n"
1491             + "  log(document.querySelector('.orange'));\n"
1492             + "}\n"
1493             + "</script></head><body onload='test()'>\n"
1494             + "  <div id='div1' class='red'>First</div>\n"
1495             + "  <div id='div2' class='red'>Second</div>\n"
1496             + "  <div id='div3' class='green'>Third</div>\n"
1497             + "  <div id='div4' class='blue'>Fourth</div>\n"
1498             + "</body></html>";
1499 
1500         loadPageVerifyTitle2(html);
1501     }
1502 
1503     /**
1504      * @throws Exception if the test fails
1505      */
1506     @Test
1507     @Alerts({"1", "0"})
1508     public void getElementsByTagName2() throws Exception {
1509         final String html = "<html xmlns:ns1='http://example.com'>\n"
1510             + "<head>\n"
1511             + "  <script>\n"
1512             + LOG_TITLE_FUNCTION
1513             + "    function test() {\n"
1514             + "      log(document.getElementsByTagName('ns1:ele').length);\n"
1515             + "      log(document.getElementsByTagName('ele').length);\n"
1516             + "    }\n"
1517             + "  </script>\n"
1518             + "</head>\n"
1519             + "<body onload='test()'>\n"
1520             + "  <ns1:ele>&nbsp;</ns1:ele>\n"
1521             + "</body>\n"
1522             + "</html>";
1523 
1524         loadPageVerifyTitle2(html);
1525     }
1526 
1527     /**
1528      * @throws Exception if the test fails
1529      */
1530     @Test
1531     @Alerts({"1", "0"})
1532     public void getElementsByTagName3() throws Exception {
1533         final String html = DOCTYPE_HTML
1534             + "<html>\n"
1535             + "<head>\n"
1536             + "  <script>\n"
1537             + LOG_TITLE_FUNCTION
1538             + "    function test() {\n"
1539             + "      log(document.getElementsByTagName('ns1:ele').length);\n"
1540             + "      log(document.getElementsByTagName('ele').length);\n"
1541             + "    }\n"
1542             + "  </script>\n"
1543             + "</head>\n"
1544             + "<body onload='test()'>\n"
1545             + "  <ns1:ele>&nbsp;</ns1:ele>\n"
1546             + "</body>\n"
1547             + "</html>";
1548 
1549         loadPageVerifyTitle2(html);
1550     }
1551 
1552     /**
1553      * Even if clear() does nothing, it was missing until HtmlUnit-2.8 and this test was failing.
1554      * @throws Exception if the test fails
1555      */
1556     @Test
1557     public void clear() throws Exception {
1558         final String html = DOCTYPE_HTML
1559             + "<html><head>\n"
1560             + "<script>\n"
1561             + "document.clear();\n"
1562             + "</script>\n"
1563             + "</head><body>\n"
1564             + "</body></html>";
1565 
1566         loadPageWithAlerts2(html);
1567     }
1568 
1569     /**
1570      * @throws Exception if an error occurs
1571      */
1572     @Test
1573     @Alerts({"true", "", "foo=bar", "foo=hello world"})
1574     public void cookie_write_cookiesEnabled() throws Exception {
1575         final String html = DOCTYPE_HTML
1576               + "<html><head><script>\n"
1577               + LOG_TITLE_FUNCTION
1578               + "  log(navigator.cookieEnabled);\n"
1579               + "  log(document.cookie);\n"
1580               + "  document.cookie = 'foo=bar';\n"
1581               + "  log(document.cookie);\n"
1582               + "  document.cookie = 'foo=hello world';\n"
1583               + "  log(document.cookie);\n"
1584               + "</script>\n"
1585               + "</head>\n"
1586               + "<body>abc</body>\n"
1587               + "</html>";
1588 
1589         loadPageVerifyTitle2(html);
1590     }
1591 
1592     /**
1593      * @throws Exception if an error occurs
1594      */
1595     @Test
1596     @Alerts(DEFAULT = {"", "a", "a", "b", "b"},
1597             FF_ESR = {"", "a", "", "b", ""})
1598     public void cookie_write2() throws Exception {
1599         final String html = DOCTYPE_HTML
1600             + "<html>\n"
1601             + "  <head>\n"
1602             + "    <script>\n"
1603             + LOG_TITLE_FUNCTION
1604             + "      log(document.cookie);\n"
1605             + "      document.cookie = 'a';\n"
1606             + "      log(document.cookie);\n"
1607             + "      document.cookie = '';\n"
1608             + "      log(document.cookie);\n"
1609             + "      document.cookie = 'b';\n"
1610             + "      log(document.cookie);\n"
1611             + "      document.cookie = ' ';\n"
1612             + "      log(document.cookie);\n"
1613             + "    </script>\n"
1614             + "  </head>\n"
1615             + "  <body>abc</body>\n"
1616             + "</html>";
1617 
1618         loadPageVerifyTitle2(html);
1619     }
1620 
1621     /**
1622      * @throws Exception if an error occurs
1623      */
1624     @Test
1625     @Alerts({"", "a", "b"})
1626     public void cookie_write_valueOnly() throws Exception {
1627         final String html = DOCTYPE_HTML
1628             + "<html>\n"
1629             + "  <head>\n"
1630             + "    <script>\n"
1631             + LOG_TITLE_FUNCTION
1632             + "      log(document.cookie);\n"
1633             + "      document.cookie = 'a';\n"
1634             + "      log(document.cookie);\n"
1635             + "      document.cookie = '=b';\n"
1636             + "      log(document.cookie);\n"
1637             + "    </script>\n"
1638             + "  </head>\n"
1639             + "  <body>abc</body>\n"
1640             + "</html>";
1641 
1642         loadPageVerifyTitle2(html);
1643     }
1644 
1645     /**
1646      * Regression test for bug 3030247: expired cookie was saved.
1647      * @see <a href="http://sourceforge.net/tracker/?func=detail&aid=3030247&group_id=47038&atid=448266">1139</a>
1648      * @throws Exception if the test fails
1649      */
1650     @Test
1651     @Alerts({"", "test2=1", ""})
1652     public void writeCookieExpired() throws Exception {
1653         final String html = DOCTYPE_HTML
1654             + "<html><body>\n"
1655             + "<script>\n"
1656             + LOG_TITLE_FUNCTION
1657             + "log(document.cookie);\n"
1658             + "document.cookie = 'test2=1';\n"
1659             + "log(document.cookie);\n"
1660             + "document.cookie = 'test2=;expires=Fri, 02-Jan-1970 00:00:00 GMT';\n"
1661             + "log(document.cookie);\n"
1662             + "</script></body></html>";
1663 
1664         loadPageVerifyTitle2(html);
1665     }
1666 
1667     /**
1668      * Only IE accepts more than the tag name.
1669      * @throws Exception if the test fails
1670      */
1671     @Test
1672     @Alerts("InvalidCharacterError/DOMException")
1673     public void createElement_notOnlyTagName() throws Exception {
1674         final String html = DOCTYPE_HTML
1675             + "<html><body>\n"
1676             + "<script>\n"
1677             + LOG_TITLE_FUNCTION
1678             + "try {\n"
1679             + "  var t = document.createElement('<input name=x>');\n"
1680             + "  log(t.tagName);\n"
1681             + "} catch(e) {\n"
1682             + "  logEx(e);\n"
1683             + "}\n"
1684             + "</script>\n"
1685             + "</body></html>";
1686 
1687         loadPageVerifyTitle2(html);
1688     }
1689 
1690     /**
1691      * @throws Exception if the test fails
1692      */
1693     @Test
1694     @Alerts({"myattr", ""})
1695     public void createAttributeNameValue() throws Exception {
1696         final String html = DOCTYPE_HTML
1697             + "<html>\n"
1698             + "<head>\n"
1699             + "<script>\n"
1700             + LOG_TITLE_FUNCTION
1701             + "  function test() {\n"
1702             + "    var node = document.createAttribute('myAttr');\n"
1703             + "    log(node.name);\n"
1704             + "    log(node.value);\n"
1705             + "  }\n"
1706             + "</script></head><body onload='test()'>\n"
1707             + "  <div id='tester'></div>\n"
1708             + "</body></html>";
1709 
1710         loadPageVerifyTitle2(html);
1711     }
1712 
1713     /**
1714      * @throws Exception if the test fails
1715      */
1716     @Test
1717     @Alerts("null")
1718     public void getElementById_strict() throws Exception {
1719         getElementById_strict(true);
1720     }
1721 
1722     /**
1723      * @throws Exception if the test fails
1724      */
1725     @Test
1726     @Alerts("null")
1727     public void getElementById_quirks() throws Exception {
1728         getElementById_strict(false);
1729     }
1730 
1731     private void getElementById_strict(final boolean xhtml) throws Exception {
1732         final String header = xhtml ? "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
1733                 + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" : "";
1734         final String html = header + "<html><head>\n"
1735             + "<script>\n"
1736             + LOG_TITLE_FUNCTION
1737             + "  function test() {\n"
1738             + "    log(document.getElementById('myId'));\n"
1739             + "  }\n"
1740             + "</script>\n"
1741             + "</head><body onload=test()>\n"
1742             + "  <a name='myId'/>\n"
1743             + "</body></html>";
1744 
1745         loadPageVerifyTitle2(html);
1746     }
1747 
1748     /**
1749      * @throws Exception if the test fails
1750      */
1751     @Test
1752     @Alerts("null")
1753     public void getElementById_caseSensitivity() throws Exception {
1754         final String html = DOCTYPE_HTML
1755             + "<html>\n"
1756             + "<head>\n"
1757             + "  <script>\n"
1758             + LOG_TITLE_FUNCTION
1759             + "  function test() {\n"
1760             + "    log(document.getElementById('MYDIV'));\n"
1761             + "  }\n"
1762             + "  </script>\n"
1763             + "</head>\n"
1764             + "<body onload='test()'>\n"
1765             + "<div id='myDiv'>\n"
1766             + "  <div></div>\n"
1767             + "</div>\n"
1768             + "</body>\n"
1769             + "</html>";
1770 
1771         loadPageVerifyTitle2(html);
1772     }
1773 
1774     /**
1775      * @throws Exception if the test fails
1776      */
1777     @Test
1778     @Alerts({"null", "null", "null"})
1779     public void getElementById_emptyParams() throws Exception {
1780         final String html = DOCTYPE_HTML
1781             + "<html>\n"
1782             + "<head>\n"
1783             + "  <script>\n"
1784             + LOG_TITLE_FUNCTION
1785             + "  function test() {\n"
1786             + "    log(document.getElementById(''));\n"
1787             + "    log(document.getElementById(undefined));\n"
1788             + "    log(document.getElementById(null));\n"
1789             + "  }\n"
1790             + "  </script>\n"
1791             + "</head>\n"
1792             + "<body onload='test()'>\n"
1793             + "<div id='myDiv'>\n"
1794             + "  <div></div>\n"
1795             + "</div>\n"
1796             + "</body>\n"
1797             + "</html>";
1798 
1799         loadPageVerifyTitle2(html);
1800     }
1801 
1802     /**
1803      * @throws Exception if the test fails
1804      */
1805     @Test
1806     @Alerts("[object HTMLHeadElement]")
1807     public void head() throws Exception {
1808         final String html = DOCTYPE_HTML
1809             + "<html><body>\n"
1810             + "<script>\n"
1811             + LOG_TITLE_FUNCTION
1812             + "  log(document.head);\n"
1813             + "</script>\n"
1814             + "</body></html>";
1815 
1816         loadPageVerifyTitle2(html);
1817     }
1818 
1819     /**
1820      * @throws Exception if an error occurs
1821      */
1822     @Test
1823     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1824     public void alinkColor() throws Exception {
1825         final String html = DOCTYPE_HTML
1826             + "<html>\n"
1827             + "  <head>\n"
1828             + "    <script>\n"
1829             + LOG_TITLE_FUNCTION
1830             + "      function test() {\n"
1831             + "        var b = document.getElementById('body');\n"
1832             + "        log(document.alinkColor);\n"
1833             + "        log(b.aLink);\n"
1834             + "        document.alinkColor = '#0000aa';\n"
1835             + "        log(document.alinkColor);\n"
1836             + "        log(b.aLink);\n"
1837             + "        document.alinkColor = 'x';\n"
1838             + "        log(document.alinkColor);\n"
1839             + "        log(b.aLink);\n"
1840             + "      }\n"
1841             + "    </script>\n"
1842             + "  </head>\n"
1843             + "  <body id='body' onload='test()'>blah</body>\n"
1844             + "</html>";
1845 
1846         loadPageVerifyTitle2(html);
1847     }
1848 
1849     /**
1850      * @throws Exception if an error occurs
1851      */
1852     @Test
1853     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1854     public void linkColor() throws Exception {
1855         final String html = DOCTYPE_HTML
1856             + "<html>\n"
1857             + "  <head>\n"
1858             + "    <script>\n"
1859             + LOG_TITLE_FUNCTION
1860             + "      function test() {\n"
1861             + "        var b = document.getElementById('body');\n"
1862             + "        log(document.linkColor);\n"
1863             + "        log(b.link);\n"
1864             + "        document.linkColor = '#0000aa';\n"
1865             + "        log(document.linkColor);\n"
1866             + "        log(b.link);\n"
1867             + "        document.linkColor = 'x';\n"
1868             + "        log(document.linkColor);\n"
1869             + "        log(b.link);\n"
1870             + "      }\n"
1871             + "    </script>\n"
1872             + "  </head>\n"
1873             + "  <body id='body' onload='test()'>blah</body>\n"
1874             + "</html>";
1875 
1876         loadPageVerifyTitle2(html);
1877     }
1878 
1879     /**
1880      * @throws Exception if an error occurs
1881      */
1882     @Test
1883     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1884     public void vlinkColor() throws Exception {
1885         final String html = DOCTYPE_HTML
1886             + "<html>\n"
1887             + "  <head>\n"
1888             + "    <script>\n"
1889             + LOG_TITLE_FUNCTION
1890             + "      function test() {\n"
1891             + "        var b = document.getElementById('body');\n"
1892             + "        log(document.vlinkColor);\n"
1893             + "        log(b.vLink);\n"
1894             + "        document.vlinkColor = '#0000aa';\n"
1895             + "        log(document.vlinkColor);\n"
1896             + "        log(b.vLink);\n"
1897             + "        document.vlinkColor = 'x';\n"
1898             + "        log(document.vlinkColor);\n"
1899             + "        log(b.vLink);\n"
1900             + "      }\n"
1901             + "    </script>\n"
1902             + "  </head>\n"
1903             + "  <body id='body' onload='test()'>blah</body>\n"
1904             + "</html>";
1905 
1906         loadPageVerifyTitle2(html);
1907     }
1908 
1909     /**
1910      * @throws Exception if an error occurs
1911      */
1912     @Test
1913     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1914     public void fgColor() throws Exception {
1915         final String html = DOCTYPE_HTML
1916             + "<html>\n"
1917             + "  <head>\n"
1918             + "    <script>\n"
1919             + LOG_TITLE_FUNCTION
1920             + "      function test() {\n"
1921             + "        var b = document.getElementById('body');\n"
1922             + "        log(document.fgColor);\n"
1923             + "        log(b.text);\n"
1924             + "        document.fgColor = '#0000aa';\n"
1925             + "        log(document.fgColor);\n"
1926             + "        log(b.text);\n"
1927             + "        document.fgColor = 'x';\n"
1928             + "        log(document.fgColor);\n"
1929             + "        log(b.text);\n"
1930             + "      }\n"
1931             + "    </script>\n"
1932             + "  </head>\n"
1933             + "  <body id='body' onload='test()'>blah</body>\n"
1934             + "</html>";
1935 
1936         loadPageVerifyTitle2(html);
1937     }
1938 
1939     /**
1940      * @throws Exception if an error occurs
1941      */
1942     @Test
1943     @Alerts({"", "true"})
1944     public void getSelection() throws Exception {
1945         final String html = DOCTYPE_HTML
1946             + "<html>\n"
1947             + "  <head>\n"
1948             + "    <script>\n"
1949             + LOG_TITLE_FUNCTION
1950             + "      function test() {\n"
1951             + "        if (document.getSelection) {\n"
1952             + "          log(document.getSelection());\n"
1953             + "          log(document.getSelection() === window.getSelection());\n"
1954             + "        }\n"
1955             + "      }\n"
1956             + "    </script>\n"
1957             + "  </head>\n"
1958             + "  <body id='body' onload='test()'>blah</body>\n"
1959             + "</html>";
1960 
1961         loadPageVerifyTitle2(html);
1962     }
1963 
1964     /**
1965      * @throws Exception if the test fails
1966      */
1967     @Test
1968     @Alerts({"true", "undefined", "false"})
1969     public void document_xxx_formAccess() throws Exception {
1970         final String html = DOCTYPE_HTML
1971             + "<html>\n"
1972             + "<head>\n"
1973             + "  <script>\n"
1974             + LOG_TITLE_FUNCTION
1975             + "    function test() {\n"
1976             + "      log(document.foo == document.forms.foo);\n"
1977             + "      log(document.blah);\n"
1978             + "      log(document.blah == document.forms.foo);\n"
1979             + "    }\n"
1980             + "  </script>\n"
1981             + "</head><body onload='test()'>\n"
1982             + "  <div id='foo'>the div 1</div>\n"
1983             + "  <form name='foo' id='blah'>\n"
1984             + "    <input name='foo'>\n"
1985             + "  </form>\n"
1986             + "</body></html>";
1987 
1988         loadPageVerifyTitle2(html);
1989     }
1990 
1991     /**
1992      * @throws Exception if the test fails
1993      */
1994     @Test
1995     @Alerts({"windows-1252", "windows-1252", "windows-1252", "undefined"})
1996     public void encoding() throws Exception {
1997         final String html = DOCTYPE_HTML
1998             + "<html>\n"
1999             + "<head>\n"
2000             + "  <script>\n"
2001             + LOG_TITLE_FUNCTION
2002             + "    function test() {\n"
2003             + "      log(document.inputEncoding);\n"
2004             + "      log(document.characterSet);\n"
2005             + "      log(document.charset);\n"
2006             + "      log(document.defaultCharset);\n"
2007             + "    }\n"
2008             + "  </script>\n"
2009             + "</head><body onload='test()'>\n"
2010             + "</body></html>";
2011 
2012         loadPageVerifyTitle2(html);
2013     }
2014 
2015     /**
2016      * @throws Exception if the test fails
2017      */
2018     @Test
2019     @Alerts({"windows-1252", "windows-1252", "windows-1252", "undefined"})
2020     public void encoding2() throws Exception {
2021         final String html = DOCTYPE_HTML
2022             + "<html>\n"
2023             + "<head>\n"
2024             + "  <meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1'>\n"
2025             + "  <script>\n"
2026             + LOG_TITLE_FUNCTION
2027             + "    function test() {\n"
2028             + "      log(document.inputEncoding);\n"
2029             + "      log(document.characterSet);\n"
2030             + "      log(document.charset);\n"
2031             + "      log(document.defaultCharset);\n"
2032             + "    }\n"
2033             + "  </script>\n"
2034             + "</head><body onload='test()'>\n"
2035             + "</body></html>";
2036 
2037         loadPageVerifyTitle2(html);
2038     }
2039 
2040     /**
2041      * @throws Exception if the test fails
2042      */
2043     @Test
2044     @Alerts({"windows-1252", "windows-1252", "windows-1252", "undefined"})
2045     public void encoding3() throws Exception {
2046         final String html = DOCTYPE_HTML
2047             + "<html>\n"
2048             + "<head>\n"
2049             + "  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>\n"
2050             + "  <script>\n"
2051             + LOG_TITLE_FUNCTION
2052             + "    function test() {\n"
2053             + "      log(document.inputEncoding);\n"
2054             + "      log(document.characterSet);\n"
2055             + "      log(document.charset);\n"
2056             + "      log(document.defaultCharset);\n"
2057             + "    }\n"
2058             + "  </script>\n"
2059             + "</head><body onload='test()'>\n"
2060             + "</body></html>";
2061 
2062         final String[] expectedAlerts = getExpectedAlerts();
2063         final WebDriver driver = loadPage2(html, URL_FIRST, MimeType.TEXT_HTML, ISO_8859_1);
2064         verifyTitle2(driver, expectedAlerts);
2065     }
2066 
2067     /**
2068      * @throws Exception if the test fails
2069      */
2070     @Test
2071     @Alerts({"UTF-8", "UTF-8", "UTF-8", "undefined"})
2072     public void encoding4() throws Exception {
2073         final String html = DOCTYPE_HTML
2074             + "<html>\n"
2075             + "<head>\n"
2076             + "  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>\n"
2077             + "  <script>\n"
2078             + LOG_TITLE_FUNCTION
2079             + "    function test() {\n"
2080             + "      log(document.inputEncoding);\n"
2081             + "      log(document.characterSet);\n"
2082             + "      log(document.charset);\n"
2083             + "      log(document.defaultCharset);\n"
2084             + "    }\n"
2085             + "  </script>\n"
2086             + "</head><body onload='test()'>\n"
2087             + "</body></html>";
2088 
2089         final String[] expectedAlerts = getExpectedAlerts();
2090         final WebDriver driver = loadPage2(html, URL_FIRST, "text/html;charset=UTF-8", ISO_8859_1);
2091         verifyTitle2(driver, expectedAlerts);
2092     }
2093 
2094     /**
2095      * @throws Exception if the test fails
2096      */
2097     @Test
2098     @Alerts({"UTF-8", "UTF-8", "UTF-8", "undefined"})
2099     public void encoding5() throws Exception {
2100         final String html = DOCTYPE_HTML
2101             + "<html>\n"
2102             + "<head>\n"
2103             + "  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>\n"
2104             + "  <script>\n"
2105             + LOG_TITLE_FUNCTION
2106             + "    function test() {\n"
2107             + "      log(document.inputEncoding);\n"
2108             + "      log(document.characterSet);\n"
2109             + "      log(document.charset);\n"
2110             + "      log(document.defaultCharset);\n"
2111             + "    }\n"
2112             + "  </script>\n"
2113             + "</head><body onload='test()'>\n"
2114             + "</body></html>";
2115 
2116         final String[] expectedAlerts = getExpectedAlerts();
2117         final WebDriver driver = loadPage2(html, URL_FIRST, "text/html;charset=utf-8", ISO_8859_1);
2118         verifyTitle2(driver, expectedAlerts);
2119     }
2120 
2121     /**
2122      * @throws Exception if the test fails
2123      */
2124     @Test
2125     @Alerts({"UTF-8", "UTF-8", "UTF-8", "undefined"})
2126     public void encoding6() throws Exception {
2127         final String html = DOCTYPE_HTML
2128             + "<html>\n"
2129             + "<head>\n"
2130             + "  <meta charset='UTF-8'>\n"
2131             + "  <script>\n"
2132             + LOG_TITLE_FUNCTION
2133             + "    function test() {\n"
2134             + "      log(document.inputEncoding);\n"
2135             + "      log(document.characterSet);\n"
2136             + "      log(document.charset);\n"
2137             + "      log(document.defaultCharset);\n"
2138             + "    }\n"
2139             + "  </script>\n"
2140             + "</head><body onload='test()'>\n"
2141             + "  <a id='myId' href='test?è=è'>test</a>\n"
2142             + "</body></html>";
2143 
2144         final String[] expectedAlerts = getExpectedAlerts();
2145         final WebDriver driver = loadPage2(html, URL_FIRST, MimeType.TEXT_HTML, UTF_8);
2146         verifyTitle2(driver, expectedAlerts);
2147     }
2148 
2149     /**
2150      * @throws Exception if the test fails
2151      */
2152     @Test
2153     @Alerts("?%C3%A8=%C3%A8")
2154     public void encoding7() throws Exception {
2155         final String html = DOCTYPE_HTML
2156             + "<html>\n"
2157             + "<head>\n"
2158             + "<meta charset='UTF-8'>\n"
2159             + "</head><body>\n"
2160             + "  <a id='myId' href='test?\u00E8=\u00E8'>test</a>\n"
2161             + "</body></html>";
2162         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
2163 
2164         final WebDriver driver = loadPage2(html, URL_FIRST, MimeType.TEXT_HTML, UTF_8);
2165         driver.findElement(By.id("myId")).click();
2166         String actualQuery = driver.getCurrentUrl();
2167         actualQuery = actualQuery.substring(actualQuery.indexOf('?'));
2168         assertTrue(actualQuery.endsWith(getExpectedAlerts()[0]));
2169     }
2170 
2171     /**
2172      * @throws Exception if the test fails
2173      */
2174     @Test
2175     @Alerts({"undefined", "BackCompat", "function", "function"})
2176     public void documentMode() throws Exception {
2177         documentMode("", "");
2178     }
2179 
2180     /**
2181      * @throws Exception if the test fails
2182      */
2183     @Test
2184     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2185     public void documentMode_doctypeStrict() throws Exception {
2186         documentMode(DOCTYPE_HTML, "");
2187     }
2188 
2189     /**
2190      * @throws Exception if the test fails
2191      */
2192     @Test
2193     @Alerts({"undefined", "BackCompat", "function", "function"})
2194     public void documentMode_doctypeTransitional() throws Exception {
2195         documentMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\""
2196                 + " \"http://www.w3.org/TR/html4/loose.dtd\">\n", "");
2197     }
2198 
2199     /**
2200      * @throws Exception if the test fails
2201      */
2202     @Test
2203     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2204     public void documentMode_doctypeHTML5() throws Exception {
2205         documentMode("<!DOCTYPE html>\n", "");
2206     }
2207 
2208     /**
2209      * @throws Exception if the test fails
2210      */
2211     @Test
2212     @Alerts({"undefined", "BackCompat", "function", "function"})
2213     public void documentMode_metaIE5() throws Exception {
2214         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=5'>\n");
2215     }
2216 
2217     /**
2218      * @throws Exception if the test fails
2219      */
2220     @Test
2221     @Alerts({"undefined", "BackCompat", "function", "function"})
2222     public void documentMode_metaIE8() throws Exception {
2223         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=8'>\n");
2224     }
2225 
2226     /**
2227      * @throws Exception if the test fails
2228      */
2229     @Test
2230     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2231     public void documentMode_metaIE8_doctypeStrict() throws Exception {
2232         documentMode(DOCTYPE_HTML, "  <meta http-equiv='X-UA-Compatible' content='IE=8'>\n");
2233     }
2234 
2235     /**
2236      * @throws Exception if the test fails
2237      */
2238     @Test
2239     @Alerts({"undefined", "BackCompat", "function", "function"})
2240     public void documentMode_metaEmulateIE8() throws Exception {
2241         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=Emulate8'>\n");
2242     }
2243 
2244     /**
2245      * @throws Exception if the test fails
2246      */
2247     @Test
2248     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2249     public void documentMode_metaEmulateIE8_doctypeStrict() throws Exception {
2250         documentMode(DOCTYPE_HTML,
2251                 "  <meta http-equiv='X-UA-Compatible' content='IE=Emulate8'>\n");
2252     }
2253 
2254     /**
2255      * @throws Exception if the test fails
2256      */
2257     @Test
2258     @Alerts({"undefined", "BackCompat", "function", "function"})
2259     public void documentMode_metaIE9() throws Exception {
2260         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=9'>\n");
2261     }
2262 
2263     /**
2264      * @throws Exception if the test fails
2265      */
2266     @Test
2267     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2268     public void documentMode_metaIE9_doctypeStrict() throws Exception {
2269         documentMode(DOCTYPE_HTML,
2270                 "  <meta http-equiv='X-UA-Compatible' content='IE=9'>\n");
2271     }
2272 
2273     /**
2274      * @throws Exception if the test fails
2275      */
2276     @Test
2277     @Alerts({"undefined", "BackCompat", "function", "function"})
2278     public void documentMode_metaIEEdge() throws Exception {
2279         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=edge'>\n");
2280     }
2281 
2282     /**
2283      * @throws Exception if the test fails
2284      */
2285     @Test
2286     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2287     public void documentMode_metaIEEdge_doctypeStrict() throws Exception {
2288         documentMode(DOCTYPE_HTML,
2289                 "  <meta http-equiv='X-UA-Compatible' content='IE=edge'>\n");
2290     }
2291 
2292     private void documentMode(final String doctype, final String meta) throws Exception {
2293         final String html = doctype
2294             + "<html>\n"
2295             + "<head>\n"
2296             + meta
2297             + "  <script>\n"
2298             + LOG_TITLE_FUNCTION
2299             + "    function test() {\n"
2300             + "      log(document.documentMode);\n"
2301             + "      log(document.compatMode);\n"
2302             + "      log(typeof document.querySelectorAll);\n"
2303             + "      log(typeof document.getElementById('myDiv').querySelector);\n"
2304             + "    }\n"
2305             + "  </script>\n"
2306             + "</head>\n"
2307             + "<body onload='test()'>\n"
2308             + "  <div id='myDiv'></div>\n"
2309             + "</body></html>";
2310 
2311         loadPageVerifyTitle2(html);
2312     }
2313 
2314     /**
2315      * Was producing "TypeError: Object's getDefaultValue() method returned an object" due to Delegator not delegating
2316      * getDefaultValue(hint) to delegee when hint is null.
2317      * @throws Exception if the test fails
2318      */
2319     @Test
2320     @Alerts("false")
2321     public void equalsString() throws Exception {
2322         final String html = DOCTYPE_HTML
2323             + "<html><body>\n"
2324             + "<script>\n"
2325             + LOG_TITLE_FUNCTION
2326             + "  log('foo' == document);\n"
2327             + "</script>\n"
2328             + "</body></html>";
2329 
2330         loadPageVerifyTitle2(html);
2331     }
2332 
2333 
2334     /**
2335      * Simple test that calls setCapture.
2336      * @throws Exception if the test fails
2337      */
2338     @Test
2339     @Alerts("undefined")
2340     public void setCapture() throws Exception {
2341         final String html = DOCTYPE_HTML
2342             + "<html><head>\n"
2343             + "<script>\n"
2344             + LOG_TITLE_FUNCTION
2345             + "  function test() {\n"
2346             + "    try {\n"
2347             + "      log(document.setCapture);\n"
2348             + "    } catch(e) { logEx(e); }\n"
2349             + "  }\n"
2350             + "</script>\n"
2351             + "</head>\n"
2352             + "<body onload='test()'>\n"
2353             + "  <div id='myDiv'></div>\n"
2354             + "</body></html>";
2355         loadPageVerifyTitle2(html);
2356     }
2357 
2358     /**
2359      * Simple test that calls releaseCapture.
2360      * @throws Exception if the test fails
2361      */
2362     @Test
2363     @Alerts(DEFAULT = {"undefined", "releaseCapture available"},
2364             CHROME = "TypeError",
2365             EDGE = "TypeError")
2366     public void releaseCapture() throws Exception {
2367         final String html = DOCTYPE_HTML
2368             + "<html><head>\n"
2369             + "<script>\n"
2370             + LOG_TITLE_FUNCTION
2371             + "  function test() {\n"
2372             + "    try {\n"
2373             + "      log(document.releaseCapture());\n"
2374             + "      log('releaseCapture available');\n"
2375             + "    } catch(e) { logEx(e); }\n"
2376             + "  }\n"
2377             + "</script>\n"
2378             + "</head>\n"
2379             + "<body onload='test()'>\n"
2380             + "  <div id='myDiv'></div>\n"
2381             + "</body></html>";
2382 
2383         loadPageVerifyTitle2(html);
2384     }
2385 
2386     /**
2387      * @throws Exception if the test fails
2388      */
2389     @Test
2390     @Alerts(CHROME = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"},
2391             EDGE = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"},
2392             FF = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"},
2393             FF_ESR = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"})
2394     public void type() throws Exception {
2395         final String html = ""
2396             + "<html><head>\n"
2397             + "<script>\n"
2398             + LOG_TITLE_FUNCTION
2399             + "  function test() {\n"
2400             + "    try {\n"
2401             + "      log(document);\n"
2402             + "      log(HTMLDocument);\n"
2403             + "    } catch(e) { logEx(e); }\n"
2404             + "  }\n"
2405             + "</script>\n"
2406             + "</head>\n"
2407             + "<body onload='test()'>\n"
2408             + "  <div id='myDiv'></div>\n"
2409             + "</body></html>";
2410 
2411         loadPageVerifyTitle2(html);
2412     }
2413 
2414     /**
2415      * @throws Exception if the test fails
2416      */
2417     @Test
2418     @Alerts("§§URL§§")
2419     public void baseURI_noBaseTag() throws Exception {
2420         final String html = DOCTYPE_HTML
2421                 + "<html>\n"
2422                 + "<body>\n"
2423                 + "<script>\n"
2424                 + LOG_TITLE_FUNCTION
2425                 + "  log(document.baseURI);\n"
2426                 + "</script>\n"
2427                 + "</body></html>";
2428 
2429         expandExpectedAlertsVariables(URL_FIRST);
2430         final WebDriver driver = loadPageVerifyTitle2(html);
2431         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2432             final HtmlPage page = (HtmlPage) getEnclosedPage();
2433             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2434         }
2435     }
2436 
2437     /**
2438      * @throws Exception if the test fails
2439      */
2440     @Test
2441     @Alerts("§§URL§§details/abc")
2442     public void baseURI_noBaseTag_urlPath() throws Exception {
2443         final String html = DOCTYPE_HTML
2444                 + "<html>\n"
2445                 + "<body>\n"
2446                 + "<script>\n"
2447                 + LOG_TITLE_FUNCTION
2448                 + "  log(document.baseURI);\n"
2449                 + "</script>\n"
2450                 + "</body></html>";
2451 
2452         expandExpectedAlertsVariables(URL_FIRST);
2453         final URL url = new URL(URL_FIRST.toString() + "details/abc");
2454         final WebDriver driver = loadPage2(html, url);
2455         verifyTitle2(driver, getExpectedAlerts());
2456         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2457             final HtmlPage page = (HtmlPage) getEnclosedPage();
2458             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2459         }
2460     }
2461 
2462     /**
2463      * @throws Exception if the test fails
2464      */
2465     @Test
2466     @Alerts("§§URL§§?x=y&z=zz")
2467     public void baseURI_noBaseTag_urlParams() throws Exception {
2468         final String html = DOCTYPE_HTML
2469                 + "<html>\n"
2470                 + "<body>\n"
2471                 + "<script>\n"
2472                 + LOG_TITLE_FUNCTION
2473                 + "  log(document.baseURI);\n"
2474                 + "</script>\n"
2475                 + "</body></html>";
2476 
2477         expandExpectedAlertsVariables(URL_FIRST);
2478         final URL url = new URL(URL_FIRST.toString() + "?x=y&z=zz");
2479         final WebDriver driver = loadPage2(html, url);
2480         verifyTitle2(driver, getExpectedAlerts());
2481         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2482             final HtmlPage page = (HtmlPage) getEnclosedPage();
2483             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2484         }
2485     }
2486 
2487     /**
2488      * @throws Exception if the test fails
2489      */
2490     @Test
2491     @Alerts("§§URL§§details/abc;jsessionid=42?x=y&z=zz")
2492     public void baseURI_noBaseTag_urlPathAndParams() throws Exception {
2493         final String html = DOCTYPE_HTML
2494                 + "<html>\n"
2495                 + "<body>\n"
2496                 + "<script>\n"
2497                 + LOG_TITLE_FUNCTION
2498                 + "  log(document.baseURI);\n"
2499                 + "</script>\n"
2500                 + "</body></html>";
2501 
2502         final URL url = new URL(URL_FIRST.toString() + "details/abc;jsessionid=42?x=y&z=zz");
2503         expandExpectedAlertsVariables(URL_FIRST);
2504         final WebDriver driver = loadPage2(html, url);
2505         verifyTitle2(driver, getExpectedAlerts());
2506         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2507             final HtmlPage page = (HtmlPage) getEnclosedPage();
2508             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2509         }
2510     }
2511 
2512     /**
2513      * @throws Exception if the test fails
2514      */
2515     @Test
2516     @Alerts("http://myotherwebsite.com/foo")
2517     public void baseURI_withBaseTag() throws Exception {
2518         final String html = DOCTYPE_HTML
2519                 + "<html>\n"
2520                 + "<head>\n"
2521                 + "  <base href='http://myotherwebsite.com/foo'>\n"
2522                 + "</head>\n"
2523                 + "<body>\n"
2524                 + "<script>\n"
2525                 + LOG_TITLE_FUNCTION
2526                 + "  log(document.baseURI);\n"
2527                 + "</script></body></html>";
2528 
2529         loadPageVerifyTitle2(html);
2530     }
2531 
2532     /**
2533      * @throws Exception if the test fails
2534      */
2535     @Test
2536     @Alerts("http://myotherwebsite.com/foo")
2537     public void baseURI_withBaseTagInBody() throws Exception {
2538         final String html = DOCTYPE_HTML
2539                 + "<html>\n"
2540                 + "<body>\n"
2541                 + "<base href='http://myotherwebsite.com/foo'>\n"
2542                 + "<script>\n"
2543                 + LOG_TITLE_FUNCTION
2544                 + "  log(document.baseURI);\n"
2545                 + "</script>\n"
2546                 + "</body></html>";
2547 
2548         loadPageVerifyTitle2(html);
2549     }
2550 
2551     /**
2552      * @throws Exception if the test fails
2553      */
2554     @Test
2555     @Alerts("§§URL§§img/")
2556     public void baseURI_withBaseTag_absolutePath() throws Exception {
2557         final String html = DOCTYPE_HTML
2558                 + "<html>\n"
2559                 + "<head>\n"
2560                 + "  <base href='/img/'>\n"
2561                 + "</head>\n"
2562                 + "<body>\n"
2563                 + "<script>\n"
2564                 + LOG_TITLE_FUNCTION
2565                 + "  log(document.baseURI);\n"
2566                 + "</script>\n"
2567                 + "</body></html>";
2568 
2569         expandExpectedAlertsVariables(URL_FIRST);
2570         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2571         verifyTitle2(getWebDriver(), getExpectedAlerts());
2572     }
2573 
2574     /**
2575      * @throws Exception if the test fails
2576      */
2577     @Test
2578     @Alerts("§§URL§§path/to/img")
2579     public void baseURI_withBaseTag_relativePath() throws Exception {
2580         final String html = DOCTYPE_HTML
2581                 + "<html>\n"
2582                 + "<head>\n"
2583                 + "  <base href='img'>\n"
2584                 + "</head>\n"
2585                 + "<body>\n"
2586                 + "<script>\n"
2587                 + LOG_TITLE_FUNCTION
2588                 + "  log(document.baseURI);\n"
2589                 + "</script>\n"
2590                 + "</body></html>";
2591 
2592         expandExpectedAlertsVariables(URL_FIRST);
2593         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2594         verifyTitle2(getWebDriver(), getExpectedAlerts());
2595     }
2596 
2597     /**
2598      * @throws Exception if the test fails
2599      */
2600     @Test
2601     @Alerts("§§URL§§path/to/img/")
2602     public void baseURI_withBaseTag_relativePath_slash() throws Exception {
2603         final String html = DOCTYPE_HTML
2604                 + "<html>\n"
2605                 + "<head>\n"
2606                 + "  <base href='img/'>\n"
2607                 + "</head>\n"
2608                 + "<body>\n"
2609                 + "<script>\n"
2610                 + LOG_TITLE_FUNCTION
2611                 + "  log(document.baseURI);\n"
2612                 + "</script>\n"
2613                 + "</body></html>";
2614 
2615         expandExpectedAlertsVariables(URL_FIRST);
2616         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2617         verifyTitle2(getWebDriver(), getExpectedAlerts());
2618     }
2619 
2620     /**
2621      * @throws Exception if the test fails
2622      */
2623     @Test
2624     @Alerts("§§URL§§path/img")
2625     public void baseURI_withBaseTag_relativePath_parent() throws Exception {
2626         final String html = DOCTYPE_HTML
2627                 + "<html>\n"
2628                 + "<head>\n"
2629                 + "  <base href='../img'>\n"
2630                 + "</head>\n"
2631                 + "<body>\n"
2632                 + "<script>\n"
2633                 + LOG_TITLE_FUNCTION
2634                 + "  log(document.baseURI);\n"
2635                 + "</script>\n"
2636                 + "</body></html>";
2637 
2638         expandExpectedAlertsVariables(URL_FIRST);
2639         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2640         verifyTitle2(getWebDriver(), getExpectedAlerts());
2641     }
2642 
2643     /**
2644      * @throws Exception if the test fails
2645      */
2646     @Test
2647     @Alerts("§§URL§§img")
2648     public void baseURI_withBaseTag_relativePath_strange() throws Exception {
2649         final String html = DOCTYPE_HTML
2650                 + "<html>\n"
2651                 + "<head>\n"
2652                 + "  <base href='../../../../img'>\n"
2653                 + "</head>\n"
2654                 + "<body>\n"
2655                 + "<script>\n"
2656                 + LOG_TITLE_FUNCTION
2657                 + "  log(document.baseURI);\n"
2658                 + "</script>\n"
2659                 + "</body></html>";
2660 
2661         expandExpectedAlertsVariables(URL_FIRST);
2662         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2663         verifyTitle2(getWebDriver(), getExpectedAlerts());
2664     }
2665 
2666     /**
2667      * @throws Exception if the test fails
2668      */
2669     @Test
2670     @Alerts("true")
2671     @HtmlUnitNYI(CHROME = "false",
2672             EDGE = "false",
2673             FF = "false",
2674             FF_ESR = "false")
2675     public void hasFocus() throws Exception {
2676         final String html = DOCTYPE_HTML
2677             + "<html><head>\n"
2678             + "<script>\n"
2679             + LOG_TITLE_FUNCTION
2680             + "  function test() {\n"
2681             + "    log(document.hasFocus());\n"
2682             + "  }\n"
2683             + "</script>\n"
2684             + "</head>\n"
2685             + "<body onload='test()'>\n"
2686             + "</body></html>";
2687 
2688         loadPageVerifyTitle2(html);
2689     }
2690 
2691     /**
2692      * @throws Exception if the test fails
2693      */
2694     @Test
2695     @Alerts(DEFAULT = "complete,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2696             FF = "uninitialized,[object HTMLBodyElement]-uninitialized,[object HTMLBodyElement]-",
2697             FF_ESR = "uninitialized,[object HTMLBodyElement]-uninitialized,[object HTMLBodyElement]-")
2698     @HtmlUnitNYI(CHROME = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2699             EDGE = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2700             FF = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2701             FF_ESR = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-")
2702     public void readyState() throws Exception {
2703         final String html = DOCTYPE_HTML
2704             + "<html>\n"
2705             + "<head>\n"
2706             + "  <script>\n"
2707             + "  var doc;\n"
2708             + "  function test() {\n"
2709             + "    var iframe = document.createElement('iframe');\n"
2710             + "    var textarea = document.getElementById('myTextarea');\n"
2711             + "    textarea.parentNode.appendChild(iframe);\n"
2712             + "    doc = iframe.contentWindow.document;\n"
2713             + "    check();\n"
2714             + "    setTimeout(check, 100);\n"
2715             + "  }\n"
2716             + "  function check() {\n"
2717             + "    var textarea = document.getElementById('myTextarea');\n"
2718             + "    textarea.value += doc.readyState + ',' + doc.body + '-';\n"
2719             + "  }\n"
2720             + "  </script>\n"
2721             + "</head>\n"
2722             + "<body onload='test()'>\n"
2723             + "<div>\n"
2724             + "  <textarea id='myTextarea' cols='80'></textarea>\n"
2725             + "</div>\n"
2726             + "</body>\n"
2727             + "</html>";
2728 
2729         final WebDriver driver = loadPage2(html);
2730         Thread.sleep(200);
2731 
2732         final List<String> actual = new LinkedList<>();
2733         actual.add(driver.findElement(By.id("myTextarea")).getDomProperty("value"));
2734 
2735         assertEquals(getExpectedAlerts(), actual);
2736     }
2737 
2738     /**
2739      * @throws Exception if the test fails
2740      */
2741     @Test
2742     @Alerts("1")
2743     public void childElementCount() throws Exception {
2744         final String html = DOCTYPE_HTML
2745             + "<html><head>\n"
2746             + "<script>\n"
2747             + LOG_TITLE_FUNCTION
2748             + "  function test() {\n"
2749             + "    log(document.childElementCount);\n"
2750             + "  }\n"
2751             + "</script>\n"
2752             + "</head>\n"
2753             + "<body onload='test()'>\n"
2754             + "  <div/>\n"
2755             + "</body></html>";
2756 
2757         loadPageVerifyTitle2(html);
2758     }
2759 
2760     /**
2761      * @throws Exception if the test fails
2762      */
2763     @Test
2764     @Alerts("TypeError")
2765     public void embeds() throws Exception {
2766         final String html = DOCTYPE_HTML
2767             + "<html><head>\n"
2768             + "<script>\n"
2769             + LOG_TITLE_FUNCTION
2770             + "  function test() {\n"
2771             + "    try {\n"
2772             + "      log(document.embeds(0));\n"
2773             + "    } catch(e) {logEx(e); }\n"
2774             + "  }\n"
2775             + "</script>\n"
2776             + "</head>\n"
2777             + "<body onload='test()'>\n"
2778             + "  <embed>\n"
2779             + "</body></html>";
2780 
2781         loadPageVerifyTitle2(html);
2782     }
2783 
2784     /**
2785      * @throws Exception if the test fails
2786      */
2787     @Test
2788     @Alerts({"1", "TypeError"})
2789     public void plugins() throws Exception {
2790         final String html = DOCTYPE_HTML
2791             + "<html><head>\n"
2792             + "<script>\n"
2793             + LOG_TITLE_FUNCTION
2794             + "  function test() {\n"
2795             + "    try {\n"
2796             + "      log(document.plugins.length);\n"
2797             + "      log(document.plugins(0));\n"
2798             + "    } catch(e) {logEx(e); }\n"
2799             + "  }\n"
2800             + "</script>\n"
2801             + "</head>\n"
2802             + "<body onload='test()'>\n"
2803             + "  <embed>\n"
2804             + "</body></html>";
2805 
2806         loadPageVerifyTitle2(html);
2807     }
2808 
2809     /**
2810      * @throws Exception if the test fails
2811      */
2812     @Test
2813     @Alerts("TypeError")
2814     public void images() throws Exception {
2815         final String html = DOCTYPE_HTML
2816             + "<html><head>\n"
2817             + "<script>\n"
2818             + LOG_TITLE_FUNCTION
2819             + "  function test() {\n"
2820             + "    try {\n"
2821             + "      log(document.images(0));\n"
2822             + "    } catch(e) {logEx(e); }\n"
2823             + "  }\n"
2824             + "</script>\n"
2825             + "</head>\n"
2826             + "<body onload='test()'>\n"
2827             + "  <img>\n"
2828             + "</body></html>";
2829 
2830         loadPageVerifyTitle2(html);
2831     }
2832 
2833     /**
2834      * @throws Exception if the test fails
2835      */
2836     @Test
2837     @Alerts("myBody")
2838     public void body() throws Exception {
2839         final String html = DOCTYPE_HTML
2840             + "<html><head>\n"
2841             + "<script>\n"
2842             + LOG_TITLE_FUNCTION
2843             + "</script>\n"
2844             + "</head>\n"
2845             + "<body id='myBody' onload='log(document.body.id)'>\n"
2846             + "</body>\n"
2847             + "</html>";
2848 
2849         loadPageVerifyTitle2(html);
2850     }
2851 
2852     /**
2853      * @throws Exception if the test fails
2854      */
2855     @Test
2856     @Alerts("myFrameset")
2857     public void bodyFrameset() throws Exception {
2858         final String html = DOCTYPE_HTML
2859             + "<html><head>\n"
2860             + "<script>\n"
2861             + LOG_TITLE_FUNCTION
2862             + "</script>\n"
2863             + "</head>\n"
2864             + "<frameset id='myFrameset' onload='log(document.body.id)'>\n"
2865             + "  <frame />\n"
2866             + "</frameset>\n"
2867             + "</html>";
2868 
2869         loadPageVerifyTitle2(html);
2870     }
2871 
2872     /**
2873      * @throws Exception if the test fails
2874      */
2875     @Test
2876     @Alerts({"myBody", "newBody"})
2877     public void setBody() throws Exception {
2878         final String html = DOCTYPE_HTML
2879             + "<html><head>\n"
2880             + "<script>\n"
2881             + LOG_TITLE_FUNCTION
2882             + "  function test() {\n"
2883             + "    try {\n"
2884             + "      log(document.body.id);\n"
2885 
2886             + "      var newBody = document.createElement('body');\n"
2887             + "      newBody.id = 'newBody';\n"
2888             + "      document.body = newBody;\n"
2889             + "      log(document.body.id);\n"
2890             + "    } catch(e) {logEx(e); }\n"
2891             + "  }\n"
2892             + "</script>\n"
2893             + "</head>\n"
2894             + "<body id='myBody' onload='test()'>\n"
2895             + "</body></html>";
2896 
2897         loadPageVerifyTitle2(html);
2898     }
2899 
2900     /**
2901      * @throws Exception if the test fails
2902      */
2903     @Test
2904     @Alerts({"myBody", "HierarchyRequestError/DOMException"})
2905     public void setBodyDiv() throws Exception {
2906         final String html = DOCTYPE_HTML
2907             + "<html><head>\n"
2908             + "<script>\n"
2909             + LOG_TITLE_FUNCTION
2910             + "  function test() {\n"
2911             + "    try {\n"
2912             + "      log(document.body.id);\n"
2913 
2914             + "      var newDiv = document.createElement('div');\n"
2915             + "      newDiv.id = 'newDiv';\n"
2916             + "      document.body = newDiv;\n"
2917             + "      log(document.body.id);\n"
2918             + "    } catch(e) {logEx(e); }\n"
2919             + "  }\n"
2920             + "</script>\n"
2921             + "</head>\n"
2922             + "<body id='myBody' onload='test()'>\n"
2923             + "</body></html>";
2924 
2925         loadPageVerifyTitle2(html);
2926     }
2927 
2928     /**
2929      * @throws Exception if the test fails
2930      */
2931     @Test
2932     @Alerts({"myBody", "TypeError"})
2933     public void setBodyString() throws Exception {
2934         final String html = DOCTYPE_HTML
2935             + "<html><head>\n"
2936             + "<script>\n"
2937             + LOG_TITLE_FUNCTION
2938             + "  function test() {\n"
2939             + "    try {\n"
2940             + "      log(document.body.id);\n"
2941 
2942             + "      var newBody = '<body id=\"newBody\" onload=\"test()\"></body>';\n"
2943             + "      document.body = newBody;\n"
2944             + "      log(document.body.id);\n"
2945             + "    } catch(e) {logEx(e); }\n"
2946             + "  }\n"
2947             + "</script>\n"
2948             + "</head>\n"
2949             + "<body id='myBody' onload='test()'>\n"
2950             + "</body></html>";
2951 
2952         loadPageVerifyTitle2(html);
2953     }
2954 
2955     /**
2956      * @throws Exception if the test fails
2957      */
2958     @Test
2959     @Alerts({"myBody", "newFrameset"})
2960     public void setBodyFrameset() throws Exception {
2961         final String html = DOCTYPE_HTML
2962             + "<html><head>\n"
2963             + "<script>\n"
2964             + LOG_TITLE_FUNCTION
2965             + "  function test() {\n"
2966             + "    try {\n"
2967             + "      log(document.body.id);\n"
2968 
2969             + "      var newBody = document.createElement('frameset');\n"
2970             + "      newBody.id = 'newFrameset';\n"
2971             + "      document.body = newBody;\n"
2972             + "      log(document.body.id);\n"
2973             + "    } catch(e) {logEx(e); }\n"
2974             + "  }\n"
2975             + "</script>\n"
2976             + "</head>\n"
2977             + "<body id='myBody' onload='test()'>\n"
2978             + "</body></html>";
2979 
2980         loadPageVerifyTitle2(html);
2981     }
2982 
2983     /**
2984      * Property lastModified returns the last modification date of the document.
2985      * @throws Exception if the test fails
2986      */
2987     @Test
2988     @Alerts({"string", "10/16/2009 09:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
2989     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
2990             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
2991     public void lastModified() throws Exception {
2992         final List<NameValuePair> responseHeaders = new ArrayList<>();
2993         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
2994         testLastModified(responseHeaders, getBrowserVersion().getSystemTimezone().getID());
2995     }
2996 
2997     /**
2998      * @throws Exception if the test fails
2999      */
3000     @Test
3001     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3002     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3003             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3004     public void lastModifiedGMT() throws Exception {
3005         final List<NameValuePair> responseHeaders = new ArrayList<>();
3006         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3007         testLastModified(responseHeaders, "GMT");
3008     }
3009 
3010     /**
3011      * @throws Exception if the test fails
3012      */
3013     @Test
3014     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3015     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3016             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3017     public void lastModifiedUTC() throws Exception {
3018         final List<NameValuePair> responseHeaders = new ArrayList<>();
3019         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3020         testLastModified(responseHeaders, "UTC");
3021     }
3022 
3023     /**
3024      * @throws Exception if the test fails
3025      */
3026     @Test
3027     @Alerts({"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3028     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3029             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3030     public void lastModifiedBerlin() throws Exception {
3031         final List<NameValuePair> responseHeaders = new ArrayList<>();
3032         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3033         testLastModified(responseHeaders, "Europe/Berlin");
3034     }
3035 
3036     /**
3037      * @throws Exception if the test fails
3038      */
3039     @Test
3040     @Alerts({"string", "10/16/2009 22:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3041     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3042             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3043     public void lastModifiedJST() throws Exception {
3044         final List<NameValuePair> responseHeaders = new ArrayList<>();
3045         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3046         testLastModified(responseHeaders, "JST");
3047     }
3048 
3049     /**
3050      * Property lastModified returns the last modification date of the document.
3051      * @throws Exception if the test fails
3052      */
3053     @Test
3054     @Alerts({"string", "10/16/2009 09:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3055     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3056             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3057     public void lastModifiedAndDate() throws Exception {
3058         final List<NameValuePair> responseHeaders = new ArrayList<>();
3059         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3060         testLastModified(responseHeaders, getBrowserVersion().getSystemTimezone().getID());
3061 
3062         // Last-Modified header has priority compared to Date header
3063         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3064         testLastModified(responseHeaders, getBrowserVersion().getSystemTimezone().getID());
3065     }
3066 
3067     /**
3068      * @throws Exception if the test fails
3069      */
3070     @Test
3071     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3072     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3073             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3074     public void lastModifiedAndDateGMT() throws Exception {
3075         final List<NameValuePair> responseHeaders = new ArrayList<>();
3076         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3077         testLastModified(responseHeaders, "GMT");
3078 
3079         // Last-Modified header has priority compared to Date header
3080         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3081         testLastModified(responseHeaders, "GMT");
3082     }
3083 
3084     /**
3085      * @throws Exception if the test fails
3086      */
3087     @Test
3088     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3089     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3090             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3091     public void lastModifiedAndDateUTC() throws Exception {
3092         final List<NameValuePair> responseHeaders = new ArrayList<>();
3093         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3094         testLastModified(responseHeaders, "UTC");
3095 
3096         // Last-Modified header has priority compared to Date header
3097         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3098         testLastModified(responseHeaders, "UTC");
3099     }
3100 
3101     /**
3102      * @throws Exception if the test fails
3103      */
3104     @Test
3105     @Alerts({"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3106     public void lastModifiedAndDateBerlin() throws Exception {
3107         final List<NameValuePair> responseHeaders = new ArrayList<>();
3108         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3109         testLastModified(responseHeaders, "Europe/Berlin");
3110 
3111         // Last-Modified header has priority compared to Date header
3112         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3113         testLastModified(responseHeaders, "Europe/Berlin");
3114     }
3115 
3116     /**
3117      * @throws Exception if the test fails
3118      */
3119     @Test
3120     @Alerts({"string", "10/16/2009 22:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3121     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3122             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3123     public void lastModifiedAndDateJST() throws Exception {
3124         final List<NameValuePair> responseHeaders = new ArrayList<>();
3125         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3126         testLastModified(responseHeaders, "JST");
3127 
3128         // Last-Modified header has priority compared to Date header
3129         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3130         testLastModified(responseHeaders, "JST");
3131     }
3132 
3133     /**
3134      * Property lastModified returns the last modification date of the document.
3135      * @throws Exception if the test fails
3136      */
3137     @Test
3138     @Alerts({"string", "§§URL§§"})
3139     public void lastModifiedOnlyDate() throws Exception {
3140         final List<NameValuePair> responseHeaders = new ArrayList<>();
3141         responseHeaders.clear();
3142         responseHeaders.add(new NameValuePair("Date", "Fri, 16 Oct 2009 13:59:47 GMT"));
3143 
3144         expandExpectedAlertsVariables(DateUtils.formatDate(new Date()).substring(0, 17));
3145         final String html = DOCTYPE_HTML
3146                 + "<html><head><script>\n"
3147                 + LOG_TITLE_FUNCTION
3148                 + "function doTest() {\n"
3149                 + "  log(typeof document.lastModified);\n"
3150                 + "  var d = new Date(document.lastModified);\n"
3151                 + "  log(d.toGMTString().substr(0, 17));\n" // to have results not depending on the user's time zone
3152                 + "}\n"
3153                 + "</script></head>\n"
3154                 + "<body onload='doTest()'>\n"
3155                 + "</body></html>";
3156 
3157         getMockWebConnection().setResponse(URL_FIRST, html, 200, "OK", MimeType.TEXT_HTML, responseHeaders);
3158 
3159         final WebDriver driver = loadPage2(URL_FIRST, ISO_8859_1);
3160         verifyTitle2(driver, getExpectedAlerts());
3161 
3162         // for some strange reasons, the selenium driven browser is in an invalid
3163         // state after this test
3164         releaseResources();
3165         shutDownAll();
3166     }
3167 
3168     private void testLastModified(final List<NameValuePair> responseHeaders, final String tz) throws Exception {
3169         final String html = DOCTYPE_HTML
3170             + "<html><head><script>\n"
3171             + LOG_TITLE_FUNCTION
3172             + "function doTest() {\n"
3173             + "  log(typeof document.lastModified);\n"
3174             + "  log(document.lastModified);\n"
3175             + "  var d = new Date(document.lastModified);\n"
3176             + "  log(d.toGMTString());\n" // to have results not depending on the user's time zone
3177             + "}\n"
3178             + "</script></head>\n"
3179             + "<body onload='doTest()'>\n"
3180             + "</body></html>";
3181 
3182         shutDownAll();
3183         try {
3184             getMockWebConnection().setResponse(URL_FIRST, html, 200, "OK", MimeType.TEXT_HTML, responseHeaders);
3185 
3186             final BrowserVersion.BrowserVersionBuilder builder
3187                 = new BrowserVersion.BrowserVersionBuilder(getBrowserVersion());
3188             builder.setSystemTimezone(TimeZone.getTimeZone(tz));
3189             setBrowserVersion(builder.build());
3190 
3191             final WebDriver driver = loadPage2(URL_FIRST, ISO_8859_1);
3192             verifyTitle2(driver, getExpectedAlerts());
3193         }
3194         finally {
3195             shutDownAll();
3196         }
3197     }
3198 
3199     /**
3200      * If neither Date header nor Last-Modified header is present, current time is taken.
3201      * @throws Exception if the test fails
3202      */
3203     @Test
3204     @Alerts({"true", "true"})
3205     public void lastModified_noDateHeader() throws Exception {
3206         final String html = DOCTYPE_HTML
3207             + "<html><head><script>\n"
3208             + LOG_TITLE_FUNCTION
3209             + "function doTest() {\n"
3210             + "  var justBeforeLoading = " + System.currentTimeMillis() + ";\n"
3211             + "  var d = new Date(document.lastModified);\n"
3212             + "  log(d.valueOf() >= justBeforeLoading - 1000);\n" // date string format has no ms, take 1s marge
3213             + "  log(d.valueOf() <= new Date().valueOf());\n"
3214             + "}\n"
3215             + "</script></head>\n"
3216             + "<body onload='doTest()'>\n"
3217             + "</body></html>";
3218 
3219         loadPageVerifyTitle2(html);
3220     }
3221 
3222     /**
3223      * Regression test for bug 2919853 (format of <tt>document.lastModified</tt> was incorrect).
3224      * @throws Exception if an error occurs
3225      */
3226     @Test
3227     public void lastModified_format() throws Exception {
3228         final String html = DOCTYPE_HTML
3229             + "<html><body onload='document.getElementById(\"i\").value = document.lastModified'>\n"
3230             + "<input id='i'></input></body></html>";
3231 
3232         final WebDriver driver = loadPageWithAlerts2(html);
3233         final String lastModified = driver.findElement(By.id("i")).getDomProperty("value");
3234 
3235         try {
3236             new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.ROOT).parse(lastModified);
3237         }
3238         catch (final ParseException e) {
3239             fail(e.getMessage());
3240         }
3241     }
3242 }