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({"[object Window]", "true"})
800     public void frameAccessByName() throws Exception {
801         final String html = DOCTYPE_HTML
802             + "<html><head><script>\n"
803             + LOG_TITLE_FUNCTION
804             + "function test() {\n"
805             + "  log(document.foo);\n"
806             + "  log(window.frames[0] == document.foo);\n"
807             + "}\n"
808             + "</script></head>\n"
809             + "<body onload='test()'>\n"
810             + "  <iframe src='about:blank' name='foo'></iframe>\n"
811             + "</body></html>";
812 
813         loadPageVerifyTitle2(html);
814     }
815 
816     /**
817      * @throws Exception if the test fails
818      */
819     @Test
820     @Alerts({"0", "0"})
821     public void getElementsByName_notFound() throws Exception {
822         final String html = DOCTYPE_HTML
823             + "<html><head><script>\n"
824             + LOG_TITLE_FUNCTION
825             + "function doTest() {\n"
826             + "  log(document.getElementsByName(null).length);\n"
827             + "  log(document.getElementsByName('foo').length);\n"
828             + "}\n"
829             + "</script></head><body onload='doTest()'>\n"
830             + "  <div name='test'></div>\n"
831             + "</body></html>";
832 
833         loadPageVerifyTitle2(html);
834     }
835 
836     /**
837      * @throws Exception if the test fails
838      */
839     @Test
840     @Alerts(DEFAULT = {"2", "0", "0"},
841             FF = {"0", "0", "0"},
842             FF_ESR = {"0", "0", "0"})
843     public void getElementsByName_emptyName() throws Exception {
844         final String html = DOCTYPE_HTML
845             + "<html><head><script>\n"
846             + LOG_TITLE_FUNCTION
847             + "  function test() {\n"
848             + "    log(document.getElementsByName('').length);\n"
849             + "    log(document.getElementsByName(' ').length);\n"
850             + "    log(document.getElementsByName(null).length);\n"
851             + "  }\n"
852             + "</script></head><body onload='test()'>\n"
853             + "  <div name=''></div>\n"
854             + "  <div name=''></div>\n"
855             + "  <div></div>\n"
856             + "  <div></div>\n"
857             + "</body></html>";
858 
859         loadPageVerifyTitle2(html);
860     }
861 
862     /**
863      * @throws Exception if the test fails
864      */
865     @Test
866     @Alerts({"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2"})
867     public void getElementsByName_elements() throws Exception {
868         final String html = DOCTYPE_HTML
869             + "<html><head><script>\n"
870             + LOG_TITLE_FUNCTION
871             + "  function test() {\n"
872             + "    try {\n"
873             + "      log(document.getElementsByName('form1').length);\n"
874             + "    } catch(e) { log('exception:f1') }\n"
875             + "    try {\n"
876             + "      log(document.getElementsByName('form2').length);\n"
877             + "    } catch(e) { log('exception:f2') }\n"
878             + "    try {\n"
879             + "      log(document.getElementsByName('frame1').length);\n"
880             + "    } catch(e) { log('exception:f1') }\n"
881             + "    try {\n"
882             + "      log(document.getElementsByName('frame2').length);\n"
883             + "    } catch(e) { log('exception:f2') }\n"
884             + "    try {\n"
885             + "      log(document.getElementsByName('input1').length);\n"
886             + "    } catch(e) { log('exception:i1') }\n"
887             + "    try {\n"
888             + "      log(document.getElementsByName('input2').length);\n"
889             + "    } catch(e) { log('exception:i2') }\n"
890             + "    try {\n"
891             + "      log(document.getElementsByName('anchor1').length);\n"
892             + "    } catch(e) { log('exception:a1') }\n"
893             + "    try {\n"
894             + "      log(document.getElementsByName('anchor2').length);\n"
895             + "    } catch(e) { log('exception:a2') }\n"
896             + "    try {\n"
897             + "      log(document.getElementsByName('image1').length);\n"
898             + "    } catch(e) { log('exception:i1') }\n"
899             + "    try {\n"
900             + "      log(document.getElementsByName('image2').length);\n"
901             + "    } catch(e) { log('exception:i2') }\n"
902             + "    try {\n"
903             + "      log(document.getElementsByName('element1').length);\n"
904             + "    } catch(e) { log('exception:e1') }\n"
905             + "    try {\n"
906             + "      log(document.getElementsByName('element2').length);\n"
907             + "    } catch(e) { log('exception:e2') }\n"
908             + "  }\n"
909             + "</script></head><body onload='test()'>\n"
910             + "  <form name='form1'></form>\n"
911             + "  <form name='form2'></form>\n"
912             + "  <form name='form2'></form>\n"
913             + "  <iframe name='frame1'></iframe>\n"
914             + "  <iframe name='frame2'></iframe>\n"
915             + "  <iframe name='frame2'></iframe>\n"
916             + "  <input type='text' name='input1' value='1'/>\n"
917             + "  <input type='text' name='input2' value='2'/>\n"
918             + "  <input type='text' name='input2' value='3'/>\n"
919             + "  <a name='anchor1'></a>\n"
920             + "  <a name='anchor2'></a>\n"
921             + "  <a name='anchor2'></a>\n"
922             + "  <img name='image1'>\n"
923             + "  <img name='image2'>\n"
924             + "  <img name='image2'>\n"
925             + "  <div name='element1'></table>\n"
926             + "  <div name='element2'></div>\n"
927             + "  <div name='element2'></div>\n"
928             + "</body></html>";
929 
930         loadPageVerifyTitle2(html);
931     }
932 
933     /**
934      * @throws Exception if the test fails
935      */
936     @Test
937     @Alerts({"1", "2"})
938     public void getElementsByName_frame() throws Exception {
939         final String html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\""
940             + "\"http://www.w3.org/TR/html4/frameset.dtd\">\n"
941             + "<html><head><script>\n"
942             + LOG_TITLE_FUNCTION
943             + "  function test() {\n"
944             + "    try {\n"
945             + "      log(document.getElementsByName('frame1').length);\n"
946             + "    } catch(e) { log('exception:f1') }\n"
947             + "    try {\n"
948             + "      log(document.getElementsByName('frame2').length);\n"
949             + "    } catch(e) { log('exception:f2') }\n"
950             + "  }\n"
951             + "</script></head>\n"
952             + "<frameset onload='test()'>\n"
953             + "  <frame src='" + URL_SECOND + "' name='frame1'>\n"
954             + "  <frame src='" + URL_SECOND + "' name='frame2'>\n"
955             + "  <frame src='" + URL_SECOND + "' name='frame2'>\n"
956             + "</frameset>\n"
957             + "</html>";
958 
959         final String frame = DOCTYPE_HTML
960                 + "<html><head><title>frame</title></head><body></body></html>";
961         getMockWebConnection().setDefaultResponse(frame);
962 
963         loadPageVerifyTitle2(html);
964     }
965 
966     /**
967      * @throws Exception if the test fails
968      */
969     @Test
970     @Alerts({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "9"})
971     public void getElementsByName_changedAfterGet() throws Exception {
972         final String html = DOCTYPE_HTML
973             + "<html><head><script>\n"
974             + LOG_TITLE_FUNCTION
975             + "  function test() {\n"
976             // 1
977             + "    var collection = document.getElementsByName('image1');\n"
978             + "    log(collection.length);\n"
979 
980             // 2
981             + "    var newImage1 = document.createElement('img');\n"
982             + "    newImage1.name = 'image1';\n"
983             + "    document.getElementById('outer1').appendChild(newImage1);\n"
984             + "    log(collection.length);\n"
985 
986             // 3
987             + "    var newImage2 = document.createElement('img');\n"
988             + "    newImage2.name = 'image1';\n"
989             + "    document.getElementById('outer2').insertBefore(newImage2, null);\n"
990             + "    log(collection.length);\n"
991 
992             // 4
993             + "    var newImage3 = document.createElement('img');\n"
994             + "    newImage3.name = 'image1';\n"
995             + "    document.getElementById('outer3').replaceChild(newImage3, document.getElementById('inner3'));\n"
996             + "    log(collection.length);\n"
997 
998             // 5
999             + "    document.getElementById('outer4').outerHTML = '<img name=\"image1\">';\n"
1000             + "    log(collection.length);\n"
1001 
1002             // 6
1003             + "    document.getElementById('outer5').innerHTML = '<img name=\"image1\">';\n"
1004             + "    log(collection.length);\n"
1005 
1006             // 7
1007             + "    document.getElementById('outer6').insertAdjacentHTML('beforeend', '<img name=\"image1\">');\n"
1008             + "    log(collection.length);\n"
1009 
1010             // 8
1011             + "    document.getElementById('image3').setAttribute('name', 'image1');\n"
1012             + "    log(collection.length);\n"
1013 
1014             // 9
1015             + "    var newAttr = document.createAttribute('name');\n"
1016             + "    newAttr.nodeValue = 'image1';\n"
1017             + "    document.getElementById('image4').setAttributeNode(newAttr);\n"
1018             + "    log(collection.length);\n"
1019 
1020             // 10
1021             + "    try {\n"
1022             + "      document.getElementById('image5').setAttributeNS(null, 'name', 'image1');\n"
1023             + "      log(collection.length);\n"
1024             + "    } catch(e) { log('exception:setAttributeNS') }\n"
1025 
1026             // 9
1027             + "    document.getElementById('outer1').removeChild(newImage1);\n"
1028             + "    log(collection.length);\n"
1029             + "  }\n"
1030             + "</script></head><body onload='test()'>\n"
1031             + "  <img name='image1'>\n"
1032             + "  <div id='outer1'></div>\n"
1033             + "  <div id='outer2'></div>\n"
1034             + "  <div id='outer3'><div id='inner3'></div></div>\n"
1035             + "  <div id='outer4'></div>\n"
1036             + "  <div id='outer5'></div>\n"
1037             + "  <div id='outer6'></div>\n"
1038             + "  <img id='image2'>\n"
1039             + "  <img id='image3'>\n"
1040             + "  <img id='image4'>\n"
1041             + "  <img id='image5'>\n"
1042             + "</body></html>";
1043 
1044         loadPageVerifyTitle2(html);
1045     }
1046 
1047     /**
1048      * Contains the cases of test {@link #getElementsByName_changedAfterGet()} that are not yet implemented.<br>
1049      * If a case gets implemented, move it to {@link #getElementsByName_changedAfterGet()}.
1050      * @throws Exception if the test fails
1051      */
1052     @Test
1053     @Alerts({"1", "2"})
1054     public void getElementsByName_changedAfterGet2() throws Exception {
1055         final String html = DOCTYPE_HTML
1056             + "<html><head><script>\n"
1057             + LOG_TITLE_FUNCTION
1058             + "  function test() {\n"
1059             + "    var collection = document.getElementsByName('image1');\n"
1060             + "    log(collection.length);\n"
1061             + "    document.getElementById('image2').name = 'image1';\n"
1062             + "    log(collection.length);\n"
1063             + "  }\n"
1064             + "</script></head><body onload='test()'>\n"
1065             + "  <img name='image1'>\n"
1066             + "  <img id='image2'>\n"
1067             + "</body></html>";
1068 
1069         loadPageVerifyTitle2(html);
1070     }
1071 
1072     /**
1073      * @throws Exception if the test fails
1074      */
1075     @Test
1076     @Alerts({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "9"})
1077     public void getElementsByName_changedAfterGet_nested() throws Exception {
1078         final String html = DOCTYPE_HTML
1079             + "<html><head><script>\n"
1080             + LOG_TITLE_FUNCTION
1081             + "  function test() {\n"
1082             // 1
1083             + "    var collection = document.getElementsByName('image1');\n"
1084             + "    log(collection.length);\n"
1085 
1086             // 2
1087             + "    var newImage1 = document.createElement('img');\n"
1088             + "    newImage1.name = 'image1';\n"
1089             + "    document.getElementById('outer1').appendChild(newImage1);\n"
1090             + "    log(collection.length);\n"
1091 
1092             // 3
1093             + "    var newImage2 = document.createElement('img');\n"
1094             + "    newImage2.name = 'image1';\n"
1095             + "    document.getElementById('outer2').insertBefore(newImage2, null);\n"
1096             + "    log(collection.length);\n"
1097 
1098             // 4
1099             + "    var newImage3 = document.createElement('img');\n"
1100             + "    newImage3.name = 'image1';\n"
1101             + "    document.getElementById('outer3').replaceChild(newImage3, document.getElementById('inner3'));\n"
1102             + "    log(collection.length);\n"
1103 
1104             // 5
1105             + "    document.getElementById('outer4').outerHTML = '<img name=\"image1\">';\n"
1106             + "    log(collection.length);\n"
1107 
1108             // 6
1109             + "    document.getElementById('outer5').innerHTML = '<img name=\"image1\">';\n"
1110             + "    log(collection.length);\n"
1111 
1112             // 7
1113             + "    document.getElementById('outer6').insertAdjacentHTML('beforeend', '<img name=\"image1\">');\n"
1114             + "    log(collection.length);\n"
1115 
1116             // 8
1117             + "    document.getElementById('image3').setAttribute('name', 'image1');\n"
1118             + "    log(collection.length);\n"
1119 
1120             // 9
1121             + "    var newAttr = document.createAttribute('name');\n"
1122             + "    newAttr.nodeValue = 'image1';\n"
1123             + "    document.getElementById('image4').setAttributeNode(newAttr);\n"
1124             + "    log(collection.length);\n"
1125 
1126             // 10
1127             + "    try {\n"
1128             + "      document.getElementById('image5').setAttributeNS(null, 'name', 'image1');\n"
1129             + "      log(collection.length);\n"
1130             + "    } catch(e) { log('exception:setAttributeNS') }\n"
1131 
1132             // 9
1133             + "    document.getElementById('outer1').removeChild(newImage1);\n"
1134             + "    log(collection.length);\n"
1135             + "  }\n"
1136             + "</script></head><body onload='test()'>\n"
1137             + "  <div>\n"
1138             + "    <img name='image1'>\n"
1139             + "    <div id='outer1'></div>\n"
1140             + "    <div id='outer2'></div>\n"
1141             + "    <div id='outer3'><div id='inner3'></div></div>\n"
1142             + "    <div id='outer4'></div>\n"
1143             + "    <div id='outer5'></div>\n"
1144             + "    <div id='outer6'></div>\n"
1145             + "    <img id='image2'>\n"
1146             + "    <img id='image3'>\n"
1147             + "    <img id='image4'>\n"
1148             + "    <img id='image5'>\n"
1149             + "  </div>\n"
1150             + "</body></html>";
1151 
1152         loadPageVerifyTitle2(html);
1153     }
1154 
1155     /**
1156      * Contains the cases of test {@link #getElementsByName_changedAfterGet_nested()} that are not yet implemented.<br>
1157      * If a case gets implemented, move it to {@link #getElementsByName_changedAfterGet_nested()}.
1158      * @throws Exception if the test fails
1159      */
1160     @Test
1161     @Alerts({"1", "2"})
1162     public void getElementsByName_changedAfterGet_nested2() throws Exception {
1163         final String html = DOCTYPE_HTML
1164             + "<html><head><script>\n"
1165             + LOG_TITLE_FUNCTION
1166             + "  function test() {\n"
1167             + "    var collection = document.getElementsByName('image1');\n"
1168             + "    log(collection.length);\n"
1169             + "    document.getElementById('image2').name = 'image1';\n"
1170             + "    log(collection.length);\n"
1171             + "  }\n"
1172             + "</script></head><body onload='test()'>\n"
1173             + "  <div>\n"
1174             + "    <img name='image1'>\n"
1175             + "    <img id='image2'>\n"
1176             + "  </div>\n"
1177             + "</body></html>";
1178 
1179         loadPageVerifyTitle2(html);
1180     }
1181 
1182     /**
1183      * Regression test for a bug introduced by the document proxy and detected by the Dojo JavaScript library tests.
1184      * @throws Exception if an error occurs
1185      */
1186     @Test
1187     @Alerts("true")
1188     public void equalityViaDifferentPaths() throws Exception {
1189         final String html = DOCTYPE_HTML
1190             + "<html><body>\n"
1191             + "<script>"
1192             + LOG_TITLE_FUNCTION
1193             + "log(document.body.parentNode.parentNode === document)\n"
1194             + "</script>\n"
1195             + "</body></html>";
1196         loadPageVerifyTitle2(html);
1197     }
1198 
1199     /**
1200      * @throws Exception if the test fails
1201      */
1202     @Test
1203     @Alerts("TypeError")
1204     public void getBoxObjectFor() throws Exception {
1205         final String html = DOCTYPE_HTML
1206             + "<html><head><script>\n"
1207             + LOG_TITLE_FUNCTION
1208             + "function doTest() {\n"
1209             + "  var e = document.getElementById('log');\n"
1210             + "  try {\n"
1211             + "    var a = document.getBoxObjectFor(e);\n"
1212             + "    log(a);\n"
1213             + "    log(a === document.getBoxObjectFor(e));\n"
1214             + "    log(a.screenX > 0);\n"
1215             + "    log(a.screenY > 0);\n"
1216             + "  } catch(e) { logEx(e) }\n"
1217             + "}\n"
1218             + "</script></head><body onload='doTest()'>\n"
1219             + "<div id='log'></div>\n"
1220             + "</body></html>";
1221 
1222         loadPageVerifyTitle2(html);
1223     }
1224 
1225     /**
1226      * @throws Exception if the test fails
1227      */
1228     @Test
1229     @Alerts({"32 commands supported", "not supported: foo, 123"})
1230     @BuggyWebDriver({"31 commands supported", "not supported: Paste, foo, 123"})
1231     public void queryCommandSupported_common() throws Exception {
1232         final String[] commands = {"BackColor", "Bold",
1233             "Copy", "CreateLink", "Cut", "Delete",
1234             "FontName", "FontSize", "ForeColor", "FormatBlock",
1235             "Indent", "InsertHorizontalRule", "InsertImage", "InsertOrderedList",
1236             "InsertParagraph", "InsertUnorderedList", "Italic",
1237             "JustifyCenter", "JustifyFull", "JustifyLeft", "JustifyRight",
1238             "Outdent", "Paste", "Redo", "RemoveFormat",
1239             "SelectAll", "StrikeThrough", "Subscript", "Superscript",
1240             "Underline", "Undo", "Unlink",
1241             "foo", "123" };
1242         queryCommandSupported(commands);
1243     }
1244 
1245     /**
1246      * @throws Exception if the test fails
1247      */
1248     @Test
1249     @Alerts(DEFAULT = {"3 commands supported", "not supported: 2D-Position, AbsolutePosition, "
1250                     + "BlockDirLTR, BlockDirRTL, BrowseMode, ClearAuthenticationCache, CreateBookmark, "
1251                     + "DirLTR, DirRTL, EditMode, InlineDirLTR, InlineDirRTL, InsertButton, InsertFieldset, "
1252                     + "InsertIFrame, InsertInputButton, InsertInputCheckbox, InsertInputFileUpload, "
1253                     + "InsertInputHidden, InsertInputImage, InsertInputPassword, InsertInputRadio, "
1254                     + "InsertInputReset, InsertInputSubmit, InsertInputText, InsertMarquee, InsertSelectDropdown, "
1255                     + "InsertSelectListbox, InsertTextArea, LiveResize, MultipleSelection, "
1256                     + "Open, OverWrite, PlayImage, Refresh, RemoveParaFormat, SaveAs, SizeToControl, "
1257                     + "SizeToControlHeight, SizeToControlWidth, Stop, StopImage, UnBookmark"},
1258             FF = "0 commands supported",
1259             FF_ESR = "0 commands supported")
1260     public void queryCommandSupported_disctinct() throws Exception {
1261         final String[] commands = {"2D-Position", "AbsolutePosition",
1262             "BlockDirLTR", "BlockDirRTL", "BrowseMode",
1263             "ClearAuthenticationCache", "CreateBookmark",
1264             "DirLTR", "DirRTL", "EditMode",
1265             "InlineDirLTR", "InlineDirRTL", "InsertButton", "InsertFieldset",
1266             "InsertIFrame", "InsertInputButton", "InsertInputCheckbox", "InsertInputFileUpload",
1267             "InsertInputHidden", "InsertInputImage", "InsertInputPassword", "InsertInputRadio",
1268             "InsertInputReset", "InsertInputSubmit", "InsertInputText", "InsertMarquee",
1269             "InsertSelectDropdown", "InsertSelectListbox", "InsertTextArea",
1270             "JustifyNone",
1271             "LiveResize", "MultipleSelection", "Open", "OverWrite",
1272             "PlayImage", "Print", "Refresh", "RemoveParaFormat",
1273             "SaveAs", "SizeToControl", "SizeToControlHeight", "SizeToControlWidth", "Stop", "StopImage",
1274             "UnBookmark", "Unselect"};
1275 
1276         queryCommandSupported(commands);
1277     }
1278 
1279     private void queryCommandSupported(final String... commands) throws Exception {
1280         final String jsCommandArray = "['" + String.join("', '", commands) + "']";
1281         final String html = DOCTYPE_HTML
1282             + "<html><head><script>\n"
1283             + LOG_TITLE_FUNCTION
1284             + "function doTest() {\n"
1285             + "  var cmds = " + jsCommandArray + ";\n"
1286             + "  var nbSupported = 0;\n"
1287             + "  var cmdsNotSupported = [];\n"
1288             + "  try {\n"
1289             + "    for (var i = 0; i < cmds.length; i++) {\n"
1290             + "      var cmd = cmds[i];\n"
1291             + "      var b = document.queryCommandSupported(cmd);\n"
1292             + "      if (b)\n"
1293             + "        nbSupported++;\n"
1294             + "      else\n"
1295             + "        cmdsNotSupported[cmdsNotSupported.length] = cmd;\n"
1296             + "    }\n"
1297             + "  } catch(e) { logEx(e); }\n"
1298             + "  log(nbSupported + ' commands supported');\n"
1299             + "  if (nbSupported != 0 && cmdsNotSupported.length > 0)\n"
1300             + "    log('not supported: ' + cmdsNotSupported.join(', '));\n"
1301             + "}\n"
1302             + "</script></head><body onload='doTest()'>\n"
1303             + "<div id='log'></div>\n"
1304             + "</body></html>";
1305 
1306         loadPageVerifyTitle2(html);
1307     }
1308 
1309     /**
1310      * @throws Exception if the test fails
1311      */
1312     @Test
1313     @Alerts({"3", "div1"})
1314     public void querySelectorAll() throws Exception {
1315         final String html = DOCTYPE_HTML
1316             + "<html><head>\n"
1317             + "<style>\n"
1318             + "  .red   {color:#FF0000;}\n"
1319             + "  .green {color:#00FF00;}\n"
1320             + "  .blue  {color:#0000FF;}\n"
1321             + "</style>\n"
1322             + "<script>\n"
1323             + "function test() {\n"
1324             + LOG_TITLE_FUNCTION
1325             + "  var redTags = document.querySelectorAll('.green,.red');\n"
1326             + "  log(redTags.length);\n"
1327             + "  log(redTags.item(0).id);\n"
1328             + "}\n"
1329             + "</script></head><body onload='test()'>\n"
1330             + "  <div id='div1' class='red'>First</div>\n"
1331             + "  <div id='div2' class='red'>Second</div>\n"
1332             + "  <div id='div3' class='green'>Third</div>\n"
1333             + "  <div id='div4' class='blue'>Fourth</div>\n"
1334             + "</body></html>";
1335 
1336         loadPageVerifyTitle2(html);
1337     }
1338 
1339     /**
1340      * @throws Exception if the test fails
1341      */
1342     @Test
1343     @Alerts("[object NodeList]")
1344     public void querySelectorAllType() throws Exception {
1345         final String html = DOCTYPE_HTML
1346             + "<html><head>\n"
1347             + "<script>\n"
1348             + LOG_TITLE_FUNCTION
1349             + "function test() {\n"
1350             + "  log(document.querySelectorAll('html'));\n"
1351             + "}\n"
1352             + "</script></head>\n"
1353             + "<body onload='test()'>\n"
1354             + "</body></html>";
1355 
1356         loadPageVerifyTitle2(html);
1357     }
1358 
1359     /**
1360      * @throws Exception if the test fails
1361      */
1362     @Test
1363     @Alerts("SyntaxError/DOMException")
1364     public void querySelectorAll_badSelector() throws Exception {
1365         for (final String selector : JQUERY_CUSTOM_SELECTORS) {
1366             doTestQuerySelectorAll_badSelector(selector);
1367         }
1368     }
1369 
1370     private void doTestQuerySelectorAll_badSelector(final String selector) throws Exception {
1371         final String html = DOCTYPE_HTML
1372             + "<html><body><script>\n"
1373             + LOG_TITLE_FUNCTION
1374             + "try {\n"
1375             + "  document.querySelectorAll('" + selector + "');\n"
1376             + "  log('working');\n"
1377             + "} catch(e) { logEx(e); }\n"
1378             + "</script></body></html>";
1379 
1380         loadPageVerifyTitle2(html);
1381     }
1382 
1383     /**
1384      * @throws Exception if the test fails
1385      */
1386     @Test
1387     @Alerts("SyntaxError/DOMException")
1388     public void querySelector_badSelector() throws Exception {
1389         for (final String selector : JQUERY_CUSTOM_SELECTORS) {
1390             doTestQuerySelector_badSelector(selector);
1391         }
1392     }
1393 
1394     private void doTestQuerySelector_badSelector(final String selector) throws Exception {
1395         final String html = DOCTYPE_HTML
1396             + "<html><body><script>\n"
1397             + LOG_TITLE_FUNCTION
1398             + "try {\n"
1399             + "  document.querySelector('" + selector + "');\n"
1400             + "  log('working: " + selector + "');\n"
1401             + "} catch(e) { logEx(e); }\n"
1402             + "</script></body></html>";
1403 
1404         loadPageVerifyTitle2(html);
1405     }
1406 
1407     /**
1408      * @throws Exception if the test fails
1409      */
1410     @Test
1411     @Alerts({"3", "div1"})
1412     public void querySelectorAll_quirks() throws Exception {
1413         final String html = DOCTYPE_HTML
1414             + "<html>\n"
1415             + "<head>\n"
1416             + "<meta http-equiv='X-UA-Compatible' content='IE=7' />\n"
1417             + "<style>\n"
1418             + "  .red   {color:#FF0000;}\n"
1419             + "  .green {color:#00FF00;}\n"
1420             + "  .blue  {color:#0000FF;}\n"
1421             + "</style>\n"
1422             + "<script>\n"
1423             + LOG_TITLE_FUNCTION
1424             + "function test() {\n"
1425             + "  if(document.querySelectorAll) {\n"
1426             + "    var redTags = document.querySelectorAll('.green,.red');\n"
1427             + "    log(redTags.length);\n"
1428             + "    log(redTags.item(0).id);\n"
1429             + "  }\n"
1430             + "  else\n"
1431             + "    log('undefined');\n"
1432             + "}\n"
1433             + "</script></head>\n"
1434             + "<body onload='test()'>\n"
1435             + "  <div id='div1' class='red'>First</div>\n"
1436             + "  <div id='div2' class='red'>Second</div>\n"
1437             + "  <div id='div3' class='green'>Third</div>\n"
1438             + "  <div id='div4' class='blue'>Fourth</div>\n"
1439             + "</body></html>";
1440 
1441         loadPageVerifyTitle2(html);
1442     }
1443 
1444     /**
1445      * @throws Exception if the test fails
1446      */
1447     @Test
1448     @Alerts("3")
1449     public void querySelectorAll_implicitAttribute() throws Exception {
1450         final String html = DOCTYPE_HTML
1451             + "<html><head>\n"
1452             + "<script>\n"
1453             + LOG_TITLE_FUNCTION
1454             + "function test() {\n"
1455             + "  var result = document.querySelectorAll('[disabled]');\n"
1456             + "  log(result.length);\n"
1457             + "}\n"
1458             + "</script></head><body onload='test()'>\n"
1459             + "  <select name='select4' id='select4' multiple='multiple'>\n"
1460             + "    <optgroup disabled='disabled'>\n"
1461             + "      <option id='option4a' class='emptyopt' value=''>Nothing</option>\n"
1462             + "      <option id='option4b' disabled='disabled' selected='selected' value='1'>1</option>\n"
1463             + "      <option id='option4c' selected='selected' value='2'>2</option>\n"
1464             + "    </optgroup>\n"
1465             + "    <option selected='selected' disabled='disabled' id='option4d' value='3'>3</option>\n"
1466             + "    <option id='option4e'>no value</option>\n"
1467             + "    </select>\n"
1468             + "</body></html>";
1469 
1470         loadPageVerifyTitle2(html);
1471     }
1472 
1473     /**
1474      * @throws Exception if the test fails
1475      */
1476     @Test
1477     @Alerts({"div1", "null"})
1478     public void querySelector() throws Exception {
1479         final String html = DOCTYPE_HTML
1480             + "<html><head>\n"
1481             + "<style>\n"
1482             + "  .red   {color:#FF0000;}\n"
1483             + "  .green {color:#00FF00;}\n"
1484             + "  .blue  {color:#0000FF;}\n"
1485             + "</style>\n"
1486             + "<script>\n"
1487             + LOG_TITLE_FUNCTION
1488             + "function test() {\n"
1489             + "  log(document.querySelector('.green,.red').id);\n"
1490             + "  log(document.querySelector('.orange'));\n"
1491             + "}\n"
1492             + "</script></head><body onload='test()'>\n"
1493             + "  <div id='div1' class='red'>First</div>\n"
1494             + "  <div id='div2' class='red'>Second</div>\n"
1495             + "  <div id='div3' class='green'>Third</div>\n"
1496             + "  <div id='div4' class='blue'>Fourth</div>\n"
1497             + "</body></html>";
1498 
1499         loadPageVerifyTitle2(html);
1500     }
1501 
1502     /**
1503      * @throws Exception if the test fails
1504      */
1505     @Test
1506     @Alerts({"1", "0"})
1507     public void getElementsByTagName2() throws Exception {
1508         final String html = "<html xmlns:ns1='http://example.com'>\n"
1509             + "<head>\n"
1510             + "  <script>\n"
1511             + LOG_TITLE_FUNCTION
1512             + "    function test() {\n"
1513             + "      log(document.getElementsByTagName('ns1:ele').length);\n"
1514             + "      log(document.getElementsByTagName('ele').length);\n"
1515             + "    }\n"
1516             + "  </script>\n"
1517             + "</head>\n"
1518             + "<body onload='test()'>\n"
1519             + "  <ns1:ele>&nbsp;</ns1:ele>\n"
1520             + "</body>\n"
1521             + "</html>";
1522 
1523         loadPageVerifyTitle2(html);
1524     }
1525 
1526     /**
1527      * @throws Exception if the test fails
1528      */
1529     @Test
1530     @Alerts({"1", "0"})
1531     public void getElementsByTagName3() throws Exception {
1532         final String html = DOCTYPE_HTML
1533             + "<html>\n"
1534             + "<head>\n"
1535             + "  <script>\n"
1536             + LOG_TITLE_FUNCTION
1537             + "    function test() {\n"
1538             + "      log(document.getElementsByTagName('ns1:ele').length);\n"
1539             + "      log(document.getElementsByTagName('ele').length);\n"
1540             + "    }\n"
1541             + "  </script>\n"
1542             + "</head>\n"
1543             + "<body onload='test()'>\n"
1544             + "  <ns1:ele>&nbsp;</ns1:ele>\n"
1545             + "</body>\n"
1546             + "</html>";
1547 
1548         loadPageVerifyTitle2(html);
1549     }
1550 
1551     /**
1552      * Even if clear() does nothing, it was missing until HtmlUnit-2.8 and this test was failing.
1553      * @throws Exception if the test fails
1554      */
1555     @Test
1556     public void clear() throws Exception {
1557         final String html = DOCTYPE_HTML
1558             + "<html><head>\n"
1559             + "<script>\n"
1560             + "document.clear();\n"
1561             + "</script>\n"
1562             + "</head><body>\n"
1563             + "</body></html>";
1564 
1565         loadPageWithAlerts2(html);
1566     }
1567 
1568     /**
1569      * @throws Exception if an error occurs
1570      */
1571     @Test
1572     @Alerts({"true", "", "foo=bar", "foo=hello world"})
1573     public void cookie_write_cookiesEnabled() throws Exception {
1574         final String html = DOCTYPE_HTML
1575               + "<html><head><script>\n"
1576               + LOG_TITLE_FUNCTION
1577               + "  log(navigator.cookieEnabled);\n"
1578               + "  log(document.cookie);\n"
1579               + "  document.cookie = 'foo=bar';\n"
1580               + "  log(document.cookie);\n"
1581               + "  document.cookie = 'foo=hello world';\n"
1582               + "  log(document.cookie);\n"
1583               + "</script>\n"
1584               + "</head>\n"
1585               + "<body>abc</body>\n"
1586               + "</html>";
1587 
1588         loadPageVerifyTitle2(html);
1589     }
1590 
1591     /**
1592      * @throws Exception if an error occurs
1593      */
1594     @Test
1595     @Alerts({"", "a", "a", "b", "b"})
1596     public void cookie_write2() throws Exception {
1597         final String html = DOCTYPE_HTML
1598             + "<html>\n"
1599             + "  <head>\n"
1600             + "    <script>\n"
1601             + LOG_TITLE_FUNCTION
1602             + "      log(document.cookie);\n"
1603             + "      document.cookie = 'a';\n"
1604             + "      log(document.cookie);\n"
1605             + "      document.cookie = '';\n"
1606             + "      log(document.cookie);\n"
1607             + "      document.cookie = 'b';\n"
1608             + "      log(document.cookie);\n"
1609             + "      document.cookie = ' ';\n"
1610             + "      log(document.cookie);\n"
1611             + "    </script>\n"
1612             + "  </head>\n"
1613             + "  <body>abc</body>\n"
1614             + "</html>";
1615 
1616         loadPageVerifyTitle2(html);
1617     }
1618 
1619     /**
1620      * @throws Exception if an error occurs
1621      */
1622     @Test
1623     @Alerts({"", "a", "b"})
1624     public void cookie_write_valueOnly() throws Exception {
1625         final String html = DOCTYPE_HTML
1626             + "<html>\n"
1627             + "  <head>\n"
1628             + "    <script>\n"
1629             + LOG_TITLE_FUNCTION
1630             + "      log(document.cookie);\n"
1631             + "      document.cookie = 'a';\n"
1632             + "      log(document.cookie);\n"
1633             + "      document.cookie = '=b';\n"
1634             + "      log(document.cookie);\n"
1635             + "    </script>\n"
1636             + "  </head>\n"
1637             + "  <body>abc</body>\n"
1638             + "</html>";
1639 
1640         loadPageVerifyTitle2(html);
1641     }
1642 
1643     /**
1644      * Regression test for bug 3030247: expired cookie was saved.
1645      * @see <a href="http://sourceforge.net/tracker/?func=detail&aid=3030247&group_id=47038&atid=448266">1139</a>
1646      * @throws Exception if the test fails
1647      */
1648     @Test
1649     @Alerts({"", "test2=1", ""})
1650     public void writeCookieExpired() throws Exception {
1651         final String html = DOCTYPE_HTML
1652             + "<html><body>\n"
1653             + "<script>\n"
1654             + LOG_TITLE_FUNCTION
1655             + "log(document.cookie);\n"
1656             + "document.cookie = 'test2=1';\n"
1657             + "log(document.cookie);\n"
1658             + "document.cookie = 'test2=;expires=Fri, 02-Jan-1970 00:00:00 GMT';\n"
1659             + "log(document.cookie);\n"
1660             + "</script></body></html>";
1661 
1662         loadPageVerifyTitle2(html);
1663     }
1664 
1665     /**
1666      * Only IE accepts more than the tag name.
1667      * @throws Exception if the test fails
1668      */
1669     @Test
1670     @Alerts("InvalidCharacterError/DOMException")
1671     public void createElement_notOnlyTagName() throws Exception {
1672         final String html = DOCTYPE_HTML
1673             + "<html><body>\n"
1674             + "<script>\n"
1675             + LOG_TITLE_FUNCTION
1676             + "try {\n"
1677             + "  var t = document.createElement('<input name=x>');\n"
1678             + "  log(t.tagName);\n"
1679             + "} catch(e) {\n"
1680             + "  logEx(e);\n"
1681             + "}\n"
1682             + "</script>\n"
1683             + "</body></html>";
1684 
1685         loadPageVerifyTitle2(html);
1686     }
1687 
1688     /**
1689      * @throws Exception if the test fails
1690      */
1691     @Test
1692     @Alerts({"myattr", ""})
1693     public void createAttributeNameValue() throws Exception {
1694         final String html = DOCTYPE_HTML
1695             + "<html>\n"
1696             + "<head>\n"
1697             + "<script>\n"
1698             + LOG_TITLE_FUNCTION
1699             + "  function test() {\n"
1700             + "    var node = document.createAttribute('myAttr');\n"
1701             + "    log(node.name);\n"
1702             + "    log(node.value);\n"
1703             + "  }\n"
1704             + "</script></head><body onload='test()'>\n"
1705             + "  <div id='tester'></div>\n"
1706             + "</body></html>";
1707 
1708         loadPageVerifyTitle2(html);
1709     }
1710 
1711     /**
1712      * @throws Exception if the test fails
1713      */
1714     @Test
1715     @Alerts("null")
1716     public void getElementById_strict() throws Exception {
1717         getElementById_strict(true);
1718     }
1719 
1720     /**
1721      * @throws Exception if the test fails
1722      */
1723     @Test
1724     @Alerts("null")
1725     public void getElementById_quirks() throws Exception {
1726         getElementById_strict(false);
1727     }
1728 
1729     private void getElementById_strict(final boolean xhtml) throws Exception {
1730         final String header = xhtml ? "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
1731                 + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" : "";
1732         final String html = header + "<html><head>\n"
1733             + "<script>\n"
1734             + LOG_TITLE_FUNCTION
1735             + "  function test() {\n"
1736             + "    log(document.getElementById('myId'));\n"
1737             + "  }\n"
1738             + "</script>\n"
1739             + "</head><body onload=test()>\n"
1740             + "  <a name='myId'/>\n"
1741             + "</body></html>";
1742 
1743         loadPageVerifyTitle2(html);
1744     }
1745 
1746     /**
1747      * @throws Exception if the test fails
1748      */
1749     @Test
1750     @Alerts("null")
1751     public void getElementById_caseSensitivity() throws Exception {
1752         final String html = DOCTYPE_HTML
1753             + "<html>\n"
1754             + "<head>\n"
1755             + "  <script>\n"
1756             + LOG_TITLE_FUNCTION
1757             + "  function test() {\n"
1758             + "    log(document.getElementById('MYDIV'));\n"
1759             + "  }\n"
1760             + "  </script>\n"
1761             + "</head>\n"
1762             + "<body onload='test()'>\n"
1763             + "<div id='myDiv'>\n"
1764             + "  <div></div>\n"
1765             + "</div>\n"
1766             + "</body>\n"
1767             + "</html>";
1768 
1769         loadPageVerifyTitle2(html);
1770     }
1771 
1772     /**
1773      * @throws Exception if the test fails
1774      */
1775     @Test
1776     @Alerts({"null", "null", "null"})
1777     public void getElementById_emptyParams() throws Exception {
1778         final String html = DOCTYPE_HTML
1779             + "<html>\n"
1780             + "<head>\n"
1781             + "  <script>\n"
1782             + LOG_TITLE_FUNCTION
1783             + "  function test() {\n"
1784             + "    log(document.getElementById(''));\n"
1785             + "    log(document.getElementById(undefined));\n"
1786             + "    log(document.getElementById(null));\n"
1787             + "  }\n"
1788             + "  </script>\n"
1789             + "</head>\n"
1790             + "<body onload='test()'>\n"
1791             + "<div id='myDiv'>\n"
1792             + "  <div></div>\n"
1793             + "</div>\n"
1794             + "</body>\n"
1795             + "</html>";
1796 
1797         loadPageVerifyTitle2(html);
1798     }
1799 
1800     /**
1801      * @throws Exception if the test fails
1802      */
1803     @Test
1804     @Alerts("[object HTMLHeadElement]")
1805     public void head() throws Exception {
1806         final String html = DOCTYPE_HTML
1807             + "<html><body>\n"
1808             + "<script>\n"
1809             + LOG_TITLE_FUNCTION
1810             + "  log(document.head);\n"
1811             + "</script>\n"
1812             + "</body></html>";
1813 
1814         loadPageVerifyTitle2(html);
1815     }
1816 
1817     /**
1818      * @throws Exception if an error occurs
1819      */
1820     @Test
1821     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1822     public void alinkColor() throws Exception {
1823         final String html = DOCTYPE_HTML
1824             + "<html>\n"
1825             + "  <head>\n"
1826             + "    <script>\n"
1827             + LOG_TITLE_FUNCTION
1828             + "      function test() {\n"
1829             + "        var b = document.getElementById('body');\n"
1830             + "        log(document.alinkColor);\n"
1831             + "        log(b.aLink);\n"
1832             + "        document.alinkColor = '#0000aa';\n"
1833             + "        log(document.alinkColor);\n"
1834             + "        log(b.aLink);\n"
1835             + "        document.alinkColor = 'x';\n"
1836             + "        log(document.alinkColor);\n"
1837             + "        log(b.aLink);\n"
1838             + "      }\n"
1839             + "    </script>\n"
1840             + "  </head>\n"
1841             + "  <body id='body' onload='test()'>blah</body>\n"
1842             + "</html>";
1843 
1844         loadPageVerifyTitle2(html);
1845     }
1846 
1847     /**
1848      * @throws Exception if an error occurs
1849      */
1850     @Test
1851     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1852     public void linkColor() throws Exception {
1853         final String html = DOCTYPE_HTML
1854             + "<html>\n"
1855             + "  <head>\n"
1856             + "    <script>\n"
1857             + LOG_TITLE_FUNCTION
1858             + "      function test() {\n"
1859             + "        var b = document.getElementById('body');\n"
1860             + "        log(document.linkColor);\n"
1861             + "        log(b.link);\n"
1862             + "        document.linkColor = '#0000aa';\n"
1863             + "        log(document.linkColor);\n"
1864             + "        log(b.link);\n"
1865             + "        document.linkColor = 'x';\n"
1866             + "        log(document.linkColor);\n"
1867             + "        log(b.link);\n"
1868             + "      }\n"
1869             + "    </script>\n"
1870             + "  </head>\n"
1871             + "  <body id='body' onload='test()'>blah</body>\n"
1872             + "</html>";
1873 
1874         loadPageVerifyTitle2(html);
1875     }
1876 
1877     /**
1878      * @throws Exception if an error occurs
1879      */
1880     @Test
1881     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1882     public void vlinkColor() throws Exception {
1883         final String html = DOCTYPE_HTML
1884             + "<html>\n"
1885             + "  <head>\n"
1886             + "    <script>\n"
1887             + LOG_TITLE_FUNCTION
1888             + "      function test() {\n"
1889             + "        var b = document.getElementById('body');\n"
1890             + "        log(document.vlinkColor);\n"
1891             + "        log(b.vLink);\n"
1892             + "        document.vlinkColor = '#0000aa';\n"
1893             + "        log(document.vlinkColor);\n"
1894             + "        log(b.vLink);\n"
1895             + "        document.vlinkColor = 'x';\n"
1896             + "        log(document.vlinkColor);\n"
1897             + "        log(b.vLink);\n"
1898             + "      }\n"
1899             + "    </script>\n"
1900             + "  </head>\n"
1901             + "  <body id='body' onload='test()'>blah</body>\n"
1902             + "</html>";
1903 
1904         loadPageVerifyTitle2(html);
1905     }
1906 
1907     /**
1908      * @throws Exception if an error occurs
1909      */
1910     @Test
1911     @Alerts({"", "", "#0000aa", "#0000aa", "x", "x"})
1912     public void fgColor() throws Exception {
1913         final String html = DOCTYPE_HTML
1914             + "<html>\n"
1915             + "  <head>\n"
1916             + "    <script>\n"
1917             + LOG_TITLE_FUNCTION
1918             + "      function test() {\n"
1919             + "        var b = document.getElementById('body');\n"
1920             + "        log(document.fgColor);\n"
1921             + "        log(b.text);\n"
1922             + "        document.fgColor = '#0000aa';\n"
1923             + "        log(document.fgColor);\n"
1924             + "        log(b.text);\n"
1925             + "        document.fgColor = 'x';\n"
1926             + "        log(document.fgColor);\n"
1927             + "        log(b.text);\n"
1928             + "      }\n"
1929             + "    </script>\n"
1930             + "  </head>\n"
1931             + "  <body id='body' onload='test()'>blah</body>\n"
1932             + "</html>";
1933 
1934         loadPageVerifyTitle2(html);
1935     }
1936 
1937     /**
1938      * @throws Exception if an error occurs
1939      */
1940     @Test
1941     @Alerts({"", "true"})
1942     public void getSelection() throws Exception {
1943         final String html = DOCTYPE_HTML
1944             + "<html>\n"
1945             + "  <head>\n"
1946             + "    <script>\n"
1947             + LOG_TITLE_FUNCTION
1948             + "      function test() {\n"
1949             + "        if (document.getSelection) {\n"
1950             + "          log(document.getSelection());\n"
1951             + "          log(document.getSelection() === window.getSelection());\n"
1952             + "        }\n"
1953             + "      }\n"
1954             + "    </script>\n"
1955             + "  </head>\n"
1956             + "  <body id='body' onload='test()'>blah</body>\n"
1957             + "</html>";
1958 
1959         loadPageVerifyTitle2(html);
1960     }
1961 
1962     /**
1963      * @throws Exception if the test fails
1964      */
1965     @Test
1966     @Alerts({"true", "undefined", "false"})
1967     public void document_xxx_formAccess() throws Exception {
1968         final String html = DOCTYPE_HTML
1969             + "<html>\n"
1970             + "<head>\n"
1971             + "  <script>\n"
1972             + LOG_TITLE_FUNCTION
1973             + "    function test() {\n"
1974             + "      log(document.foo == document.forms.foo);\n"
1975             + "      log(document.blah);\n"
1976             + "      log(document.blah == document.forms.foo);\n"
1977             + "    }\n"
1978             + "  </script>\n"
1979             + "</head><body onload='test()'>\n"
1980             + "  <div id='foo'>the div 1</div>\n"
1981             + "  <form name='foo' id='blah'>\n"
1982             + "    <input name='foo'>\n"
1983             + "  </form>\n"
1984             + "</body></html>";
1985 
1986         loadPageVerifyTitle2(html);
1987     }
1988 
1989     /**
1990      * @throws Exception if the test fails
1991      */
1992     @Test
1993     @Alerts({"windows-1252", "windows-1252", "windows-1252", "undefined"})
1994     public void encoding() throws Exception {
1995         final String html = DOCTYPE_HTML
1996             + "<html>\n"
1997             + "<head>\n"
1998             + "  <script>\n"
1999             + LOG_TITLE_FUNCTION
2000             + "    function test() {\n"
2001             + "      log(document.inputEncoding);\n"
2002             + "      log(document.characterSet);\n"
2003             + "      log(document.charset);\n"
2004             + "      log(document.defaultCharset);\n"
2005             + "    }\n"
2006             + "  </script>\n"
2007             + "</head><body onload='test()'>\n"
2008             + "</body></html>";
2009 
2010         loadPageVerifyTitle2(html);
2011     }
2012 
2013     /**
2014      * @throws Exception if the test fails
2015      */
2016     @Test
2017     @Alerts({"windows-1252", "windows-1252", "windows-1252", "undefined"})
2018     public void encoding2() throws Exception {
2019         final String html = DOCTYPE_HTML
2020             + "<html>\n"
2021             + "<head>\n"
2022             + "  <meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1'>\n"
2023             + "  <script>\n"
2024             + LOG_TITLE_FUNCTION
2025             + "    function test() {\n"
2026             + "      log(document.inputEncoding);\n"
2027             + "      log(document.characterSet);\n"
2028             + "      log(document.charset);\n"
2029             + "      log(document.defaultCharset);\n"
2030             + "    }\n"
2031             + "  </script>\n"
2032             + "</head><body onload='test()'>\n"
2033             + "</body></html>";
2034 
2035         loadPageVerifyTitle2(html);
2036     }
2037 
2038     /**
2039      * @throws Exception if the test fails
2040      */
2041     @Test
2042     @Alerts({"windows-1252", "windows-1252", "windows-1252", "undefined"})
2043     public void encoding3() throws Exception {
2044         final String html = DOCTYPE_HTML
2045             + "<html>\n"
2046             + "<head>\n"
2047             + "  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>\n"
2048             + "  <script>\n"
2049             + LOG_TITLE_FUNCTION
2050             + "    function test() {\n"
2051             + "      log(document.inputEncoding);\n"
2052             + "      log(document.characterSet);\n"
2053             + "      log(document.charset);\n"
2054             + "      log(document.defaultCharset);\n"
2055             + "    }\n"
2056             + "  </script>\n"
2057             + "</head><body onload='test()'>\n"
2058             + "</body></html>";
2059 
2060         final String[] expectedAlerts = getExpectedAlerts();
2061         final WebDriver driver = loadPage2(html, URL_FIRST, MimeType.TEXT_HTML, ISO_8859_1);
2062         verifyTitle2(driver, expectedAlerts);
2063     }
2064 
2065     /**
2066      * @throws Exception if the test fails
2067      */
2068     @Test
2069     @Alerts({"UTF-8", "UTF-8", "UTF-8", "undefined"})
2070     public void encoding4() throws Exception {
2071         final String html = DOCTYPE_HTML
2072             + "<html>\n"
2073             + "<head>\n"
2074             + "  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>\n"
2075             + "  <script>\n"
2076             + LOG_TITLE_FUNCTION
2077             + "    function test() {\n"
2078             + "      log(document.inputEncoding);\n"
2079             + "      log(document.characterSet);\n"
2080             + "      log(document.charset);\n"
2081             + "      log(document.defaultCharset);\n"
2082             + "    }\n"
2083             + "  </script>\n"
2084             + "</head><body onload='test()'>\n"
2085             + "</body></html>";
2086 
2087         final String[] expectedAlerts = getExpectedAlerts();
2088         final WebDriver driver = loadPage2(html, URL_FIRST, "text/html;charset=UTF-8", ISO_8859_1);
2089         verifyTitle2(driver, expectedAlerts);
2090     }
2091 
2092     /**
2093      * @throws Exception if the test fails
2094      */
2095     @Test
2096     @Alerts({"UTF-8", "UTF-8", "UTF-8", "undefined"})
2097     public void encoding5() throws Exception {
2098         final String html = DOCTYPE_HTML
2099             + "<html>\n"
2100             + "<head>\n"
2101             + "  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>\n"
2102             + "  <script>\n"
2103             + LOG_TITLE_FUNCTION
2104             + "    function test() {\n"
2105             + "      log(document.inputEncoding);\n"
2106             + "      log(document.characterSet);\n"
2107             + "      log(document.charset);\n"
2108             + "      log(document.defaultCharset);\n"
2109             + "    }\n"
2110             + "  </script>\n"
2111             + "</head><body onload='test()'>\n"
2112             + "</body></html>";
2113 
2114         final String[] expectedAlerts = getExpectedAlerts();
2115         final WebDriver driver = loadPage2(html, URL_FIRST, "text/html;charset=utf-8", ISO_8859_1);
2116         verifyTitle2(driver, expectedAlerts);
2117     }
2118 
2119     /**
2120      * @throws Exception if the test fails
2121      */
2122     @Test
2123     @Alerts({"UTF-8", "UTF-8", "UTF-8", "undefined"})
2124     public void encoding6() throws Exception {
2125         final String html = DOCTYPE_HTML
2126             + "<html>\n"
2127             + "<head>\n"
2128             + "  <meta charset='UTF-8'>\n"
2129             + "  <script>\n"
2130             + LOG_TITLE_FUNCTION
2131             + "    function test() {\n"
2132             + "      log(document.inputEncoding);\n"
2133             + "      log(document.characterSet);\n"
2134             + "      log(document.charset);\n"
2135             + "      log(document.defaultCharset);\n"
2136             + "    }\n"
2137             + "  </script>\n"
2138             + "</head><body onload='test()'>\n"
2139             + "  <a id='myId' href='test?è=è'>test</a>\n"
2140             + "</body></html>";
2141 
2142         final String[] expectedAlerts = getExpectedAlerts();
2143         final WebDriver driver = loadPage2(html, URL_FIRST, MimeType.TEXT_HTML, UTF_8);
2144         verifyTitle2(driver, expectedAlerts);
2145     }
2146 
2147     /**
2148      * @throws Exception if the test fails
2149      */
2150     @Test
2151     @Alerts("?%C3%A8=%C3%A8")
2152     public void encoding7() throws Exception {
2153         final String html = DOCTYPE_HTML
2154             + "<html>\n"
2155             + "<head>\n"
2156             + "<meta charset='UTF-8'>\n"
2157             + "</head><body>\n"
2158             + "  <a id='myId' href='test?\u00E8=\u00E8'>test</a>\n"
2159             + "</body></html>";
2160         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
2161 
2162         final WebDriver driver = loadPage2(html, URL_FIRST, MimeType.TEXT_HTML, UTF_8);
2163         driver.findElement(By.id("myId")).click();
2164         String actualQuery = driver.getCurrentUrl();
2165         actualQuery = actualQuery.substring(actualQuery.indexOf('?'));
2166         assertTrue(actualQuery.endsWith(getExpectedAlerts()[0]));
2167     }
2168 
2169     /**
2170      * @throws Exception if the test fails
2171      */
2172     @Test
2173     @Alerts({"undefined", "BackCompat", "function", "function"})
2174     public void documentMode() throws Exception {
2175         documentMode("", "");
2176     }
2177 
2178     /**
2179      * @throws Exception if the test fails
2180      */
2181     @Test
2182     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2183     public void documentMode_doctypeStrict() throws Exception {
2184         documentMode(DOCTYPE_HTML, "");
2185     }
2186 
2187     /**
2188      * @throws Exception if the test fails
2189      */
2190     @Test
2191     @Alerts({"undefined", "BackCompat", "function", "function"})
2192     public void documentMode_doctypeTransitional() throws Exception {
2193         documentMode("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\""
2194                 + " \"http://www.w3.org/TR/html4/loose.dtd\">\n", "");
2195     }
2196 
2197     /**
2198      * @throws Exception if the test fails
2199      */
2200     @Test
2201     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2202     public void documentMode_doctypeHTML5() throws Exception {
2203         documentMode("<!DOCTYPE html>\n", "");
2204     }
2205 
2206     /**
2207      * @throws Exception if the test fails
2208      */
2209     @Test
2210     @Alerts({"undefined", "BackCompat", "function", "function"})
2211     public void documentMode_metaIE5() throws Exception {
2212         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=5'>\n");
2213     }
2214 
2215     /**
2216      * @throws Exception if the test fails
2217      */
2218     @Test
2219     @Alerts({"undefined", "BackCompat", "function", "function"})
2220     public void documentMode_metaIE8() throws Exception {
2221         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=8'>\n");
2222     }
2223 
2224     /**
2225      * @throws Exception if the test fails
2226      */
2227     @Test
2228     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2229     public void documentMode_metaIE8_doctypeStrict() throws Exception {
2230         documentMode(DOCTYPE_HTML, "  <meta http-equiv='X-UA-Compatible' content='IE=8'>\n");
2231     }
2232 
2233     /**
2234      * @throws Exception if the test fails
2235      */
2236     @Test
2237     @Alerts({"undefined", "BackCompat", "function", "function"})
2238     public void documentMode_metaEmulateIE8() throws Exception {
2239         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=Emulate8'>\n");
2240     }
2241 
2242     /**
2243      * @throws Exception if the test fails
2244      */
2245     @Test
2246     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2247     public void documentMode_metaEmulateIE8_doctypeStrict() throws Exception {
2248         documentMode(DOCTYPE_HTML,
2249                 "  <meta http-equiv='X-UA-Compatible' content='IE=Emulate8'>\n");
2250     }
2251 
2252     /**
2253      * @throws Exception if the test fails
2254      */
2255     @Test
2256     @Alerts({"undefined", "BackCompat", "function", "function"})
2257     public void documentMode_metaIE9() throws Exception {
2258         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=9'>\n");
2259     }
2260 
2261     /**
2262      * @throws Exception if the test fails
2263      */
2264     @Test
2265     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2266     public void documentMode_metaIE9_doctypeStrict() throws Exception {
2267         documentMode(DOCTYPE_HTML,
2268                 "  <meta http-equiv='X-UA-Compatible' content='IE=9'>\n");
2269     }
2270 
2271     /**
2272      * @throws Exception if the test fails
2273      */
2274     @Test
2275     @Alerts({"undefined", "BackCompat", "function", "function"})
2276     public void documentMode_metaIEEdge() throws Exception {
2277         documentMode("", "  <meta http-equiv='X-UA-Compatible' content='IE=edge'>\n");
2278     }
2279 
2280     /**
2281      * @throws Exception if the test fails
2282      */
2283     @Test
2284     @Alerts({"undefined", "CSS1Compat", "function", "function"})
2285     public void documentMode_metaIEEdge_doctypeStrict() throws Exception {
2286         documentMode(DOCTYPE_HTML,
2287                 "  <meta http-equiv='X-UA-Compatible' content='IE=edge'>\n");
2288     }
2289 
2290     private void documentMode(final String doctype, final String meta) throws Exception {
2291         final String html = doctype
2292             + "<html>\n"
2293             + "<head>\n"
2294             + meta
2295             + "  <script>\n"
2296             + LOG_TITLE_FUNCTION
2297             + "    function test() {\n"
2298             + "      log(document.documentMode);\n"
2299             + "      log(document.compatMode);\n"
2300             + "      log(typeof document.querySelectorAll);\n"
2301             + "      log(typeof document.getElementById('myDiv').querySelector);\n"
2302             + "    }\n"
2303             + "  </script>\n"
2304             + "</head>\n"
2305             + "<body onload='test()'>\n"
2306             + "  <div id='myDiv'></div>\n"
2307             + "</body></html>";
2308 
2309         loadPageVerifyTitle2(html);
2310     }
2311 
2312     /**
2313      * Was producing "TypeError: Object's getDefaultValue() method returned an object" due to Delegator not delegating
2314      * getDefaultValue(hint) to delegee when hint is null.
2315      * @throws Exception if the test fails
2316      */
2317     @Test
2318     @Alerts("false")
2319     public void equalsString() throws Exception {
2320         final String html = DOCTYPE_HTML
2321             + "<html><body>\n"
2322             + "<script>\n"
2323             + LOG_TITLE_FUNCTION
2324             + "  log('foo' == document);\n"
2325             + "</script>\n"
2326             + "</body></html>";
2327 
2328         loadPageVerifyTitle2(html);
2329     }
2330 
2331 
2332     /**
2333      * Simple test that calls setCapture.
2334      * @throws Exception if the test fails
2335      */
2336     @Test
2337     @Alerts("undefined")
2338     public void setCapture() throws Exception {
2339         final String html = DOCTYPE_HTML
2340             + "<html><head>\n"
2341             + "<script>\n"
2342             + LOG_TITLE_FUNCTION
2343             + "  function test() {\n"
2344             + "    try {\n"
2345             + "      log(document.setCapture);\n"
2346             + "    } catch(e) { logEx(e); }\n"
2347             + "  }\n"
2348             + "</script>\n"
2349             + "</head>\n"
2350             + "<body onload='test()'>\n"
2351             + "  <div id='myDiv'></div>\n"
2352             + "</body></html>";
2353         loadPageVerifyTitle2(html);
2354     }
2355 
2356     /**
2357      * Simple test that calls releaseCapture.
2358      * @throws Exception if the test fails
2359      */
2360     @Test
2361     @Alerts(DEFAULT = {"undefined", "releaseCapture available"},
2362             CHROME = "TypeError",
2363             EDGE = "TypeError")
2364     public void releaseCapture() throws Exception {
2365         final String html = DOCTYPE_HTML
2366             + "<html><head>\n"
2367             + "<script>\n"
2368             + LOG_TITLE_FUNCTION
2369             + "  function test() {\n"
2370             + "    try {\n"
2371             + "      log(document.releaseCapture());\n"
2372             + "      log('releaseCapture available');\n"
2373             + "    } catch(e) { logEx(e); }\n"
2374             + "  }\n"
2375             + "</script>\n"
2376             + "</head>\n"
2377             + "<body onload='test()'>\n"
2378             + "  <div id='myDiv'></div>\n"
2379             + "</body></html>";
2380 
2381         loadPageVerifyTitle2(html);
2382     }
2383 
2384     /**
2385      * @throws Exception if the test fails
2386      */
2387     @Test
2388     @Alerts(CHROME = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"},
2389             EDGE = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"},
2390             FF = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"},
2391             FF_ESR = {"[object HTMLDocument]", "function HTMLDocument() { [native code] }"})
2392     public void type() throws Exception {
2393         final String html = ""
2394             + "<html><head>\n"
2395             + "<script>\n"
2396             + LOG_TITLE_FUNCTION
2397             + "  function test() {\n"
2398             + "    try {\n"
2399             + "      log(document);\n"
2400             + "      log(HTMLDocument);\n"
2401             + "    } catch(e) { logEx(e); }\n"
2402             + "  }\n"
2403             + "</script>\n"
2404             + "</head>\n"
2405             + "<body onload='test()'>\n"
2406             + "  <div id='myDiv'></div>\n"
2407             + "</body></html>";
2408 
2409         loadPageVerifyTitle2(html);
2410     }
2411 
2412     /**
2413      * @throws Exception if the test fails
2414      */
2415     @Test
2416     @Alerts("§§URL§§")
2417     public void baseURI_noBaseTag() throws Exception {
2418         final String html = DOCTYPE_HTML
2419                 + "<html>\n"
2420                 + "<body>\n"
2421                 + "<script>\n"
2422                 + LOG_TITLE_FUNCTION
2423                 + "  log(document.baseURI);\n"
2424                 + "</script>\n"
2425                 + "</body></html>";
2426 
2427         expandExpectedAlertsVariables(URL_FIRST);
2428         final WebDriver driver = loadPageVerifyTitle2(html);
2429         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2430             final HtmlPage page = (HtmlPage) getEnclosedPage();
2431             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2432         }
2433     }
2434 
2435     /**
2436      * @throws Exception if the test fails
2437      */
2438     @Test
2439     @Alerts("§§URL§§details/abc")
2440     public void baseURI_noBaseTag_urlPath() throws Exception {
2441         final String html = DOCTYPE_HTML
2442                 + "<html>\n"
2443                 + "<body>\n"
2444                 + "<script>\n"
2445                 + LOG_TITLE_FUNCTION
2446                 + "  log(document.baseURI);\n"
2447                 + "</script>\n"
2448                 + "</body></html>";
2449 
2450         expandExpectedAlertsVariables(URL_FIRST);
2451         final URL url = new URL(URL_FIRST.toString() + "details/abc");
2452         final WebDriver driver = loadPage2(html, url);
2453         verifyTitle2(driver, getExpectedAlerts());
2454         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2455             final HtmlPage page = (HtmlPage) getEnclosedPage();
2456             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2457         }
2458     }
2459 
2460     /**
2461      * @throws Exception if the test fails
2462      */
2463     @Test
2464     @Alerts("§§URL§§?x=y&z=zz")
2465     public void baseURI_noBaseTag_urlParams() throws Exception {
2466         final String html = DOCTYPE_HTML
2467                 + "<html>\n"
2468                 + "<body>\n"
2469                 + "<script>\n"
2470                 + LOG_TITLE_FUNCTION
2471                 + "  log(document.baseURI);\n"
2472                 + "</script>\n"
2473                 + "</body></html>";
2474 
2475         expandExpectedAlertsVariables(URL_FIRST);
2476         final URL url = new URL(URL_FIRST.toString() + "?x=y&z=zz");
2477         final WebDriver driver = loadPage2(html, url);
2478         verifyTitle2(driver, getExpectedAlerts());
2479         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2480             final HtmlPage page = (HtmlPage) getEnclosedPage();
2481             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2482         }
2483     }
2484 
2485     /**
2486      * @throws Exception if the test fails
2487      */
2488     @Test
2489     @Alerts("§§URL§§details/abc;jsessionid=42?x=y&z=zz")
2490     public void baseURI_noBaseTag_urlPathAndParams() throws Exception {
2491         final String html = DOCTYPE_HTML
2492                 + "<html>\n"
2493                 + "<body>\n"
2494                 + "<script>\n"
2495                 + LOG_TITLE_FUNCTION
2496                 + "  log(document.baseURI);\n"
2497                 + "</script>\n"
2498                 + "</body></html>";
2499 
2500         final URL url = new URL(URL_FIRST.toString() + "details/abc;jsessionid=42?x=y&z=zz");
2501         expandExpectedAlertsVariables(URL_FIRST);
2502         final WebDriver driver = loadPage2(html, url);
2503         verifyTitle2(driver, getExpectedAlerts());
2504         if (driver instanceof HtmlUnitDriver && !"undefined".equals(getExpectedAlerts()[0])) {
2505             final HtmlPage page = (HtmlPage) getEnclosedPage();
2506             assertEquals(getExpectedAlerts()[0], page.getBaseURL().toString());
2507         }
2508     }
2509 
2510     /**
2511      * @throws Exception if the test fails
2512      */
2513     @Test
2514     @Alerts("http://myotherwebsite.com/foo")
2515     public void baseURI_withBaseTag() throws Exception {
2516         final String html = DOCTYPE_HTML
2517                 + "<html>\n"
2518                 + "<head>\n"
2519                 + "  <base href='http://myotherwebsite.com/foo'>\n"
2520                 + "</head>\n"
2521                 + "<body>\n"
2522                 + "<script>\n"
2523                 + LOG_TITLE_FUNCTION
2524                 + "  log(document.baseURI);\n"
2525                 + "</script></body></html>";
2526 
2527         loadPageVerifyTitle2(html);
2528     }
2529 
2530     /**
2531      * @throws Exception if the test fails
2532      */
2533     @Test
2534     @Alerts("http://myotherwebsite.com/foo")
2535     public void baseURI_withBaseTagInBody() throws Exception {
2536         final String html = DOCTYPE_HTML
2537                 + "<html>\n"
2538                 + "<body>\n"
2539                 + "<base href='http://myotherwebsite.com/foo'>\n"
2540                 + "<script>\n"
2541                 + LOG_TITLE_FUNCTION
2542                 + "  log(document.baseURI);\n"
2543                 + "</script>\n"
2544                 + "</body></html>";
2545 
2546         loadPageVerifyTitle2(html);
2547     }
2548 
2549     /**
2550      * @throws Exception if the test fails
2551      */
2552     @Test
2553     @Alerts("§§URL§§img/")
2554     public void baseURI_withBaseTag_absolutePath() throws Exception {
2555         final String html = DOCTYPE_HTML
2556                 + "<html>\n"
2557                 + "<head>\n"
2558                 + "  <base href='/img/'>\n"
2559                 + "</head>\n"
2560                 + "<body>\n"
2561                 + "<script>\n"
2562                 + LOG_TITLE_FUNCTION
2563                 + "  log(document.baseURI);\n"
2564                 + "</script>\n"
2565                 + "</body></html>";
2566 
2567         expandExpectedAlertsVariables(URL_FIRST);
2568         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2569         verifyTitle2(getWebDriver(), getExpectedAlerts());
2570     }
2571 
2572     /**
2573      * @throws Exception if the test fails
2574      */
2575     @Test
2576     @Alerts("§§URL§§path/to/img")
2577     public void baseURI_withBaseTag_relativePath() throws Exception {
2578         final String html = DOCTYPE_HTML
2579                 + "<html>\n"
2580                 + "<head>\n"
2581                 + "  <base href='img'>\n"
2582                 + "</head>\n"
2583                 + "<body>\n"
2584                 + "<script>\n"
2585                 + LOG_TITLE_FUNCTION
2586                 + "  log(document.baseURI);\n"
2587                 + "</script>\n"
2588                 + "</body></html>";
2589 
2590         expandExpectedAlertsVariables(URL_FIRST);
2591         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2592         verifyTitle2(getWebDriver(), getExpectedAlerts());
2593     }
2594 
2595     /**
2596      * @throws Exception if the test fails
2597      */
2598     @Test
2599     @Alerts("§§URL§§path/to/img/")
2600     public void baseURI_withBaseTag_relativePath_slash() throws Exception {
2601         final String html = DOCTYPE_HTML
2602                 + "<html>\n"
2603                 + "<head>\n"
2604                 + "  <base href='img/'>\n"
2605                 + "</head>\n"
2606                 + "<body>\n"
2607                 + "<script>\n"
2608                 + LOG_TITLE_FUNCTION
2609                 + "  log(document.baseURI);\n"
2610                 + "</script>\n"
2611                 + "</body></html>";
2612 
2613         expandExpectedAlertsVariables(URL_FIRST);
2614         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2615         verifyTitle2(getWebDriver(), getExpectedAlerts());
2616     }
2617 
2618     /**
2619      * @throws Exception if the test fails
2620      */
2621     @Test
2622     @Alerts("§§URL§§path/img")
2623     public void baseURI_withBaseTag_relativePath_parent() throws Exception {
2624         final String html = DOCTYPE_HTML
2625                 + "<html>\n"
2626                 + "<head>\n"
2627                 + "  <base href='../img'>\n"
2628                 + "</head>\n"
2629                 + "<body>\n"
2630                 + "<script>\n"
2631                 + LOG_TITLE_FUNCTION
2632                 + "  log(document.baseURI);\n"
2633                 + "</script>\n"
2634                 + "</body></html>";
2635 
2636         expandExpectedAlertsVariables(URL_FIRST);
2637         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2638         verifyTitle2(getWebDriver(), getExpectedAlerts());
2639     }
2640 
2641     /**
2642      * @throws Exception if the test fails
2643      */
2644     @Test
2645     @Alerts("§§URL§§img")
2646     public void baseURI_withBaseTag_relativePath_strange() throws Exception {
2647         final String html = DOCTYPE_HTML
2648                 + "<html>\n"
2649                 + "<head>\n"
2650                 + "  <base href='../../../../img'>\n"
2651                 + "</head>\n"
2652                 + "<body>\n"
2653                 + "<script>\n"
2654                 + LOG_TITLE_FUNCTION
2655                 + "  log(document.baseURI);\n"
2656                 + "</script>\n"
2657                 + "</body></html>";
2658 
2659         expandExpectedAlertsVariables(URL_FIRST);
2660         loadPage2(html, new URL("http://localhost:" + PORT + "/path/to/page.html"));
2661         verifyTitle2(getWebDriver(), getExpectedAlerts());
2662     }
2663 
2664     /**
2665      * @throws Exception if the test fails
2666      */
2667     @Test
2668     @Alerts("true")
2669     @HtmlUnitNYI(CHROME = "false",
2670             EDGE = "false",
2671             FF = "false",
2672             FF_ESR = "false")
2673     public void hasFocus() throws Exception {
2674         final String html = DOCTYPE_HTML
2675             + "<html><head>\n"
2676             + "<script>\n"
2677             + LOG_TITLE_FUNCTION
2678             + "  function test() {\n"
2679             + "    log(document.hasFocus());\n"
2680             + "  }\n"
2681             + "</script>\n"
2682             + "</head>\n"
2683             + "<body onload='test()'>\n"
2684             + "</body></html>";
2685 
2686         loadPageVerifyTitle2(html);
2687     }
2688 
2689     /**
2690      * @throws Exception if the test fails
2691      */
2692     @Test
2693     @Alerts(DEFAULT = "complete,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2694             FF = "uninitialized,[object HTMLBodyElement]-uninitialized,[object HTMLBodyElement]-",
2695             FF_ESR = "uninitialized,[object HTMLBodyElement]-uninitialized,[object HTMLBodyElement]-")
2696     @HtmlUnitNYI(CHROME = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2697             EDGE = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2698             FF = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-",
2699             FF_ESR = "loading,[object HTMLBodyElement]-complete,[object HTMLBodyElement]-")
2700     public void readyState() throws Exception {
2701         final String html = DOCTYPE_HTML
2702             + "<html>\n"
2703             + "<head>\n"
2704             + "  <script>\n"
2705             + "  var doc;\n"
2706             + "  function test() {\n"
2707             + "    var iframe = document.createElement('iframe');\n"
2708             + "    var textarea = document.getElementById('myTextarea');\n"
2709             + "    textarea.parentNode.appendChild(iframe);\n"
2710             + "    doc = iframe.contentWindow.document;\n"
2711             + "    check();\n"
2712             + "    setTimeout(check, 100);\n"
2713             + "  }\n"
2714             + "  function check() {\n"
2715             + "    var textarea = document.getElementById('myTextarea');\n"
2716             + "    textarea.value += doc.readyState + ',' + doc.body + '-';\n"
2717             + "  }\n"
2718             + "  </script>\n"
2719             + "</head>\n"
2720             + "<body onload='test()'>\n"
2721             + "<div>\n"
2722             + "  <textarea id='myTextarea' cols='80'></textarea>\n"
2723             + "</div>\n"
2724             + "</body>\n"
2725             + "</html>";
2726 
2727         final WebDriver driver = loadPage2(html);
2728         Thread.sleep(200);
2729 
2730         final List<String> actual = new LinkedList<>();
2731         actual.add(driver.findElement(By.id("myTextarea")).getDomProperty("value"));
2732 
2733         assertEquals(getExpectedAlerts(), actual);
2734     }
2735 
2736     /**
2737      * @throws Exception if the test fails
2738      */
2739     @Test
2740     @Alerts("1")
2741     public void childElementCount() throws Exception {
2742         final String html = DOCTYPE_HTML
2743             + "<html><head>\n"
2744             + "<script>\n"
2745             + LOG_TITLE_FUNCTION
2746             + "  function test() {\n"
2747             + "    log(document.childElementCount);\n"
2748             + "  }\n"
2749             + "</script>\n"
2750             + "</head>\n"
2751             + "<body onload='test()'>\n"
2752             + "  <div/>\n"
2753             + "</body></html>";
2754 
2755         loadPageVerifyTitle2(html);
2756     }
2757 
2758     /**
2759      * @throws Exception if the test fails
2760      */
2761     @Test
2762     @Alerts("TypeError")
2763     public void embeds() throws Exception {
2764         final String html = DOCTYPE_HTML
2765             + "<html><head>\n"
2766             + "<script>\n"
2767             + LOG_TITLE_FUNCTION
2768             + "  function test() {\n"
2769             + "    try {\n"
2770             + "      log(document.embeds(0));\n"
2771             + "    } catch(e) {logEx(e); }\n"
2772             + "  }\n"
2773             + "</script>\n"
2774             + "</head>\n"
2775             + "<body onload='test()'>\n"
2776             + "  <embed>\n"
2777             + "</body></html>";
2778 
2779         loadPageVerifyTitle2(html);
2780     }
2781 
2782     /**
2783      * @throws Exception if the test fails
2784      */
2785     @Test
2786     @Alerts({"1", "TypeError"})
2787     public void plugins() throws Exception {
2788         final String html = DOCTYPE_HTML
2789             + "<html><head>\n"
2790             + "<script>\n"
2791             + LOG_TITLE_FUNCTION
2792             + "  function test() {\n"
2793             + "    try {\n"
2794             + "      log(document.plugins.length);\n"
2795             + "      log(document.plugins(0));\n"
2796             + "    } catch(e) {logEx(e); }\n"
2797             + "  }\n"
2798             + "</script>\n"
2799             + "</head>\n"
2800             + "<body onload='test()'>\n"
2801             + "  <embed>\n"
2802             + "</body></html>";
2803 
2804         loadPageVerifyTitle2(html);
2805     }
2806 
2807     /**
2808      * @throws Exception if the test fails
2809      */
2810     @Test
2811     @Alerts("TypeError")
2812     public void images() throws Exception {
2813         final String html = DOCTYPE_HTML
2814             + "<html><head>\n"
2815             + "<script>\n"
2816             + LOG_TITLE_FUNCTION
2817             + "  function test() {\n"
2818             + "    try {\n"
2819             + "      log(document.images(0));\n"
2820             + "    } catch(e) {logEx(e); }\n"
2821             + "  }\n"
2822             + "</script>\n"
2823             + "</head>\n"
2824             + "<body onload='test()'>\n"
2825             + "  <img>\n"
2826             + "</body></html>";
2827 
2828         loadPageVerifyTitle2(html);
2829     }
2830 
2831     /**
2832      * @throws Exception if the test fails
2833      */
2834     @Test
2835     @Alerts("myBody")
2836     public void body() throws Exception {
2837         final String html = DOCTYPE_HTML
2838             + "<html><head>\n"
2839             + "<script>\n"
2840             + LOG_TITLE_FUNCTION
2841             + "</script>\n"
2842             + "</head>\n"
2843             + "<body id='myBody' onload='log(document.body.id)'>\n"
2844             + "</body>\n"
2845             + "</html>";
2846 
2847         loadPageVerifyTitle2(html);
2848     }
2849 
2850     /**
2851      * @throws Exception if the test fails
2852      */
2853     @Test
2854     @Alerts("myFrameset")
2855     public void bodyFrameset() throws Exception {
2856         final String html = DOCTYPE_HTML
2857             + "<html><head>\n"
2858             + "<script>\n"
2859             + LOG_TITLE_FUNCTION
2860             + "</script>\n"
2861             + "</head>\n"
2862             + "<frameset id='myFrameset' onload='log(document.body.id)'>\n"
2863             + "  <frame />\n"
2864             + "</frameset>\n"
2865             + "</html>";
2866 
2867         loadPageVerifyTitle2(html);
2868     }
2869 
2870     /**
2871      * @throws Exception if the test fails
2872      */
2873     @Test
2874     @Alerts({"myBody", "newBody"})
2875     public void setBody() throws Exception {
2876         final String html = DOCTYPE_HTML
2877             + "<html><head>\n"
2878             + "<script>\n"
2879             + LOG_TITLE_FUNCTION
2880             + "  function test() {\n"
2881             + "    try {\n"
2882             + "      log(document.body.id);\n"
2883 
2884             + "      var newBody = document.createElement('body');\n"
2885             + "      newBody.id = 'newBody';\n"
2886             + "      document.body = newBody;\n"
2887             + "      log(document.body.id);\n"
2888             + "    } catch(e) {logEx(e); }\n"
2889             + "  }\n"
2890             + "</script>\n"
2891             + "</head>\n"
2892             + "<body id='myBody' onload='test()'>\n"
2893             + "</body></html>";
2894 
2895         loadPageVerifyTitle2(html);
2896     }
2897 
2898     /**
2899      * @throws Exception if the test fails
2900      */
2901     @Test
2902     @Alerts({"myBody", "HierarchyRequestError/DOMException"})
2903     public void setBodyDiv() throws Exception {
2904         final String html = DOCTYPE_HTML
2905             + "<html><head>\n"
2906             + "<script>\n"
2907             + LOG_TITLE_FUNCTION
2908             + "  function test() {\n"
2909             + "    try {\n"
2910             + "      log(document.body.id);\n"
2911 
2912             + "      var newDiv = document.createElement('div');\n"
2913             + "      newDiv.id = 'newDiv';\n"
2914             + "      document.body = newDiv;\n"
2915             + "      log(document.body.id);\n"
2916             + "    } catch(e) {logEx(e); }\n"
2917             + "  }\n"
2918             + "</script>\n"
2919             + "</head>\n"
2920             + "<body id='myBody' onload='test()'>\n"
2921             + "</body></html>";
2922 
2923         loadPageVerifyTitle2(html);
2924     }
2925 
2926     /**
2927      * @throws Exception if the test fails
2928      */
2929     @Test
2930     @Alerts({"myBody", "TypeError"})
2931     public void setBodyString() throws Exception {
2932         final String html = DOCTYPE_HTML
2933             + "<html><head>\n"
2934             + "<script>\n"
2935             + LOG_TITLE_FUNCTION
2936             + "  function test() {\n"
2937             + "    try {\n"
2938             + "      log(document.body.id);\n"
2939 
2940             + "      var newBody = '<body id=\"newBody\" onload=\"test()\"></body>';\n"
2941             + "      document.body = newBody;\n"
2942             + "      log(document.body.id);\n"
2943             + "    } catch(e) {logEx(e); }\n"
2944             + "  }\n"
2945             + "</script>\n"
2946             + "</head>\n"
2947             + "<body id='myBody' onload='test()'>\n"
2948             + "</body></html>";
2949 
2950         loadPageVerifyTitle2(html);
2951     }
2952 
2953     /**
2954      * @throws Exception if the test fails
2955      */
2956     @Test
2957     @Alerts({"myBody", "newFrameset"})
2958     public void setBodyFrameset() throws Exception {
2959         final String html = DOCTYPE_HTML
2960             + "<html><head>\n"
2961             + "<script>\n"
2962             + LOG_TITLE_FUNCTION
2963             + "  function test() {\n"
2964             + "    try {\n"
2965             + "      log(document.body.id);\n"
2966 
2967             + "      var newBody = document.createElement('frameset');\n"
2968             + "      newBody.id = 'newFrameset';\n"
2969             + "      document.body = newBody;\n"
2970             + "      log(document.body.id);\n"
2971             + "    } catch(e) {logEx(e); }\n"
2972             + "  }\n"
2973             + "</script>\n"
2974             + "</head>\n"
2975             + "<body id='myBody' onload='test()'>\n"
2976             + "</body></html>";
2977 
2978         loadPageVerifyTitle2(html);
2979     }
2980 
2981     /**
2982      * Property lastModified returns the last modification date of the document.
2983      * @throws Exception if the test fails
2984      */
2985     @Test
2986     @Alerts({"string", "10/16/2009 09:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
2987     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
2988             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
2989     public void lastModified() throws Exception {
2990         final List<NameValuePair> responseHeaders = new ArrayList<>();
2991         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
2992         testLastModified(responseHeaders, getBrowserVersion().getSystemTimezone().getID());
2993     }
2994 
2995     /**
2996      * @throws Exception if the test fails
2997      */
2998     @Test
2999     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3000     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3001             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3002     public void lastModifiedGMT() throws Exception {
3003         final List<NameValuePair> responseHeaders = new ArrayList<>();
3004         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3005         testLastModified(responseHeaders, "GMT");
3006     }
3007 
3008     /**
3009      * @throws Exception if the test fails
3010      */
3011     @Test
3012     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3013     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3014             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3015     public void lastModifiedUTC() throws Exception {
3016         final List<NameValuePair> responseHeaders = new ArrayList<>();
3017         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3018         testLastModified(responseHeaders, "UTC");
3019     }
3020 
3021     /**
3022      * @throws Exception if the test fails
3023      */
3024     @Test
3025     @Alerts({"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3026     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3027             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3028     public void lastModifiedBerlin() throws Exception {
3029         final List<NameValuePair> responseHeaders = new ArrayList<>();
3030         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3031         testLastModified(responseHeaders, "Europe/Berlin");
3032     }
3033 
3034     /**
3035      * @throws Exception if the test fails
3036      */
3037     @Test
3038     @Alerts({"string", "10/16/2009 22:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3039     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3040             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3041     public void lastModifiedJST() throws Exception {
3042         final List<NameValuePair> responseHeaders = new ArrayList<>();
3043         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3044         testLastModified(responseHeaders, "JST");
3045     }
3046 
3047     /**
3048      * Property lastModified returns the last modification date of the document.
3049      * @throws Exception if the test fails
3050      */
3051     @Test
3052     @Alerts({"string", "10/16/2009 09:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3053     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3054             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3055     public void lastModifiedAndDate() throws Exception {
3056         final List<NameValuePair> responseHeaders = new ArrayList<>();
3057         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3058         testLastModified(responseHeaders, getBrowserVersion().getSystemTimezone().getID());
3059 
3060         // Last-Modified header has priority compared to Date header
3061         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3062         testLastModified(responseHeaders, getBrowserVersion().getSystemTimezone().getID());
3063     }
3064 
3065     /**
3066      * @throws Exception if the test fails
3067      */
3068     @Test
3069     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3070     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3071             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3072     public void lastModifiedAndDateGMT() throws Exception {
3073         final List<NameValuePair> responseHeaders = new ArrayList<>();
3074         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3075         testLastModified(responseHeaders, "GMT");
3076 
3077         // Last-Modified header has priority compared to Date header
3078         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3079         testLastModified(responseHeaders, "GMT");
3080     }
3081 
3082     /**
3083      * @throws Exception if the test fails
3084      */
3085     @Test
3086     @Alerts({"string", "10/16/2009 13:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3087     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3088             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3089     public void lastModifiedAndDateUTC() throws Exception {
3090         final List<NameValuePair> responseHeaders = new ArrayList<>();
3091         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3092         testLastModified(responseHeaders, "UTC");
3093 
3094         // Last-Modified header has priority compared to Date header
3095         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3096         testLastModified(responseHeaders, "UTC");
3097     }
3098 
3099     /**
3100      * @throws Exception if the test fails
3101      */
3102     @Test
3103     @Alerts({"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3104     public void lastModifiedAndDateBerlin() throws Exception {
3105         final List<NameValuePair> responseHeaders = new ArrayList<>();
3106         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3107         testLastModified(responseHeaders, "Europe/Berlin");
3108 
3109         // Last-Modified header has priority compared to Date header
3110         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3111         testLastModified(responseHeaders, "Europe/Berlin");
3112     }
3113 
3114     /**
3115      * @throws Exception if the test fails
3116      */
3117     @Test
3118     @Alerts({"string", "10/16/2009 22:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3119     @BuggyWebDriver(FF = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"},
3120             FF_ESR = {"string", "10/16/2009 15:59:47", "Fri, 16 Oct 2009 13:59:47 GMT"})
3121     public void lastModifiedAndDateJST() throws Exception {
3122         final List<NameValuePair> responseHeaders = new ArrayList<>();
3123         responseHeaders.add(new NameValuePair("Last-Modified", "Fri, 16 Oct 2009 13:59:47 GMT"));
3124         testLastModified(responseHeaders, "JST");
3125 
3126         // Last-Modified header has priority compared to Date header
3127         responseHeaders.add(new NameValuePair("Date", "Fri, 17 Oct 2009 13:59:47 GMT"));
3128         testLastModified(responseHeaders, "JST");
3129     }
3130 
3131     /**
3132      * Property lastModified returns the last modification date of the document.
3133      * @throws Exception if the test fails
3134      */
3135     @Test
3136     @Alerts({"string", "§§URL§§"})
3137     public void lastModifiedOnlyDate() throws Exception {
3138         final List<NameValuePair> responseHeaders = new ArrayList<>();
3139         responseHeaders.clear();
3140         responseHeaders.add(new NameValuePair("Date", "Fri, 16 Oct 2009 13:59:47 GMT"));
3141 
3142         expandExpectedAlertsVariables(DateUtils.formatDate(new Date()).substring(0, 17));
3143         final String html = DOCTYPE_HTML
3144                 + "<html><head><script>\n"
3145                 + LOG_TITLE_FUNCTION
3146                 + "function doTest() {\n"
3147                 + "  log(typeof document.lastModified);\n"
3148                 + "  var d = new Date(document.lastModified);\n"
3149                 + "  log(d.toGMTString().substr(0, 17));\n" // to have results not depending on the user's time zone
3150                 + "}\n"
3151                 + "</script></head>\n"
3152                 + "<body onload='doTest()'>\n"
3153                 + "</body></html>";
3154 
3155         getMockWebConnection().setResponse(URL_FIRST, html, 200, "OK", MimeType.TEXT_HTML, responseHeaders);
3156 
3157         final WebDriver driver = loadPage2(URL_FIRST, ISO_8859_1);
3158         verifyTitle2(driver, getExpectedAlerts());
3159 
3160         // for some strange reasons, the selenium driven browser is in an invalid
3161         // state after this test
3162         releaseResources();
3163         shutDownAll();
3164     }
3165 
3166     private void testLastModified(final List<NameValuePair> responseHeaders, final String tz) throws Exception {
3167         final String html = DOCTYPE_HTML
3168             + "<html><head><script>\n"
3169             + LOG_TITLE_FUNCTION
3170             + "function doTest() {\n"
3171             + "  log(typeof document.lastModified);\n"
3172             + "  log(document.lastModified);\n"
3173             + "  var d = new Date(document.lastModified);\n"
3174             + "  log(d.toGMTString());\n" // to have results not depending on the user's time zone
3175             + "}\n"
3176             + "</script></head>\n"
3177             + "<body onload='doTest()'>\n"
3178             + "</body></html>";
3179 
3180         shutDownAll();
3181         try {
3182             getMockWebConnection().setResponse(URL_FIRST, html, 200, "OK", MimeType.TEXT_HTML, responseHeaders);
3183 
3184             final BrowserVersion.BrowserVersionBuilder builder
3185                 = new BrowserVersion.BrowserVersionBuilder(getBrowserVersion());
3186             builder.setSystemTimezone(TimeZone.getTimeZone(tz));
3187             setBrowserVersion(builder.build());
3188 
3189             final WebDriver driver = loadPage2(URL_FIRST, ISO_8859_1);
3190             verifyTitle2(driver, getExpectedAlerts());
3191         }
3192         finally {
3193             shutDownAll();
3194         }
3195     }
3196 
3197     /**
3198      * If neither Date header nor Last-Modified header is present, current time is taken.
3199      * @throws Exception if the test fails
3200      */
3201     @Test
3202     @Alerts({"true", "true"})
3203     public void lastModified_noDateHeader() throws Exception {
3204         final String html = DOCTYPE_HTML
3205             + "<html><head><script>\n"
3206             + LOG_TITLE_FUNCTION
3207             + "function doTest() {\n"
3208             + "  var justBeforeLoading = " + System.currentTimeMillis() + ";\n"
3209             + "  var d = new Date(document.lastModified);\n"
3210             + "  log(d.valueOf() >= justBeforeLoading - 1000);\n" // date string format has no ms, take 1s marge
3211             + "  log(d.valueOf() <= new Date().valueOf());\n"
3212             + "}\n"
3213             + "</script></head>\n"
3214             + "<body onload='doTest()'>\n"
3215             + "</body></html>";
3216 
3217         loadPageVerifyTitle2(html);
3218     }
3219 
3220     /**
3221      * Regression test for bug 2919853 (format of <tt>document.lastModified</tt> was incorrect).
3222      * @throws Exception if an error occurs
3223      */
3224     @Test
3225     public void lastModified_format() throws Exception {
3226         final String html = DOCTYPE_HTML
3227             + "<html><body onload='document.getElementById(\"i\").value = document.lastModified'>\n"
3228             + "<input id='i'></input></body></html>";
3229 
3230         final WebDriver driver = loadPageWithAlerts2(html);
3231         final String lastModified = driver.findElement(By.id("i")).getDomProperty("value");
3232 
3233         try {
3234             new SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.ROOT).parse(lastModified);
3235         }
3236         catch (final ParseException e) {
3237             fail(e.getMessage());
3238         }
3239     }
3240 
3241     /**
3242      * @throws Exception if the test fails
3243      */
3244     @Test
3245     @Alerts(DEFAULT = "HierarchyRequestError/DOMException",
3246             FF_ESR = "no moveBefore()")
3247     @HtmlUnitNYI(CHROME = "success", EDGE = "success", FF = "success")
3248     public void moveBefore_basic() throws Exception {
3249         final String html = DOCTYPE_HTML
3250             + "<html><head><script>\n"
3251             + LOG_TITLE_FUNCTION
3252             + "  function test() {\n"
3253             + "    var div = document.getElementById('div1');\n"
3254 
3255             + "    if (!document.moveBefore) { log('no moveBefore()'); return; }\n"
3256 
3257             + "    try {\n"
3258             + "      document.moveBefore(div, null);\n"
3259             + "      log('success');\n"
3260             + "    } catch(e) {\n"
3261             + "      logEx(e);\n"
3262             + "    }\n"
3263             + "  }\n"
3264             + "</script></head>\n"
3265             + "<body onload='test()'>\n"
3266             + "  <div id='div1'>1</div>\n"
3267             + "</body></html>";
3268         loadPageVerifyTitle2(html);
3269     }
3270 }