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