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;
16  
17  import java.net.URL;
18  import java.util.List;
19  import java.util.Map;
20  
21  import org.htmlunit.HttpHeader;
22  import org.htmlunit.HttpMethod;
23  import org.htmlunit.MockWebConnection;
24  import org.htmlunit.WebDriverTestCase;
25  import org.htmlunit.junit.annotation.Alerts;
26  import org.htmlunit.junit.annotation.HtmlUnitNYI;
27  import org.htmlunit.util.MimeType;
28  import org.htmlunit.util.NameValuePair;
29  import org.junit.jupiter.api.Test;
30  import org.openqa.selenium.By;
31  import org.openqa.selenium.JavascriptExecutor;
32  import org.openqa.selenium.NoAlertPresentException;
33  import org.openqa.selenium.WebDriver;
34  
35  /**
36   * Tests for {@link Location}.
37   *
38   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
39   * @author Michael Ottati
40   * @author Marc Guillemot
41   * @author Daniel Gredler
42   * @author Ahmed Ashour
43   * @author Ronald Brill
44   * @author Frank Danek
45   * @author Atsushi Nakagawa
46   * @author Lai Quang Duong
47   * @author Kanoko Yamamoto
48   */
49  public class Location2Test extends WebDriverTestCase {
50  
51      /**
52       * Regression test for bug 742902.
53       * @throws Exception if the test fails
54       */
55      @Test
56      @Alerts("§§URL§§")
57      public void documentLocationGet() throws Exception {
58          final String html = DOCTYPE_HTML
59              + "<html><head>\n"
60              + "<script>\n"
61              + LOG_TITLE_FUNCTION
62              + "function doTest() {\n"
63              + "  log(top.document.location);\n"
64              + "}\n"
65              + "</script></head><body onload='doTest()'>\n"
66              + "</body></html>";
67  
68          expandExpectedAlertsVariables(URL_FIRST);
69          loadPageVerifyTitle2(html);
70      }
71  
72      /**
73       * @throws Exception if the test fails
74       */
75      @Test
76      @Alerts("ok")
77      public void documentLocationSet() throws Exception {
78          final String html1 = DOCTYPE_HTML
79              + "<html>\n"
80              + "<head>\n"
81              + "  <title>test1</title>\n"
82              + "  <script>\n"
83              + "    function test() {\n"
84              + "      document.location = 'foo.html';\n"
85              + "    }\n"
86              + "  </script>\n"
87              + "</head>\n"
88              + "<body onload='test()'></body>\n"
89              + "</html>";
90          final String html2 = DOCTYPE_HTML
91              + "<html>\n"
92              + "<head>\n"
93              + "  <script>\n"
94              + LOG_TITLE_FUNCTION
95              + "    function test() {\n"
96              + "      log('ok');\n"
97              + "    }\n"
98              + "  </script>\n"
99              + "</head>\n"
100             + "<body onload='test()'></body>\n"
101             + "</html>";
102 
103         getMockWebConnection().setResponse(new URL(URL_FIRST, "foo.html"), html2);
104 
105         final WebDriver driver = loadPage2(html1);
106         verifyTitle2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
107     }
108 
109     /**
110      * @throws Exception if the test fails
111      */
112     @Test
113     @Alerts("§§URL§§")
114     public void documentLocationHref() throws Exception {
115         final String html = DOCTYPE_HTML
116             + "<html><head>\n"
117             + "<script>\n"
118             + LOG_TITLE_FUNCTION
119             + "function doTest() {\n"
120             + "  log(top.document.location.href);\n"
121             + "}\n"
122             + "</script></head><body onload='doTest()'>\n"
123             + "</body></html>";
124 
125         expandExpectedAlertsVariables(URL_FIRST);
126         loadPageVerifyTitle2(html);
127     }
128 
129     /**
130      * @throws Exception if the test fails
131      */
132     @Test
133     @Alerts({"", "about:blank", "blank", "", "about:", ""})
134     public void about_blank_attributes() throws Exception {
135         final String html = DOCTYPE_HTML
136             + "<html><head>\n"
137             + "<script>\n"
138             + LOG_TITLE_FUNCTION
139             + "function doTest() {\n"
140             + "  var location = frames[0].document.location;\n"
141             + "  log(location.hash);\n"
142             + "  log(location.href);\n"
143             + "  log(location.pathname);\n"
144             + "  log(location.port);\n"
145             + "  log(location.protocol);\n"
146             + "  log(location.search);\n"
147             + "}\n</script></head>\n"
148             + "<body onload='doTest()'>\n"
149             + "  <iframe src='about:blank'></iframe>\n"
150             + "</body>\n"
151             + "</html>";
152 
153         loadPageVerifyTitle2(html);
154     }
155 
156     /**
157      * @throws Exception if the test fails
158      */
159     @Test
160     @Alerts(DEFAULT = {"", "about:blank?query", "blank", "", "about:", "?query"},
161             FF = {"", "about:blank?query", "blank", "", "about:", ""},
162             FF_ESR = {"", "about:blank?query", "blank", "", "about:", ""})
163     public void about_blank_query_attributes() throws Exception {
164         final String html = DOCTYPE_HTML
165             + "<html>\n"
166             + "<head>\n"
167             + "  <script>\n"
168             + LOG_TITLE_FUNCTION
169             + "    function doTest() {\n"
170             + "      try {\n"
171             + "        var doc = frames[0].document;\n"
172             + "        var location = doc.location;\n"
173             + "        log(location.hash);\n"
174             + "        log(location.href);\n"
175             + "        log(location.pathname);\n"
176             + "        log(location.port);\n"
177             + "        log(location.protocol);\n"
178             + "        log(location.search);\n"
179             + "      } catch(e) { logEx(e); }\n"
180             + "    }\n"
181             + "  </script>\n"
182             + "</head>\n"
183             + "<body onload='doTest()'>\n"
184             + "  <iframe src='about:blank?query'></iframe>\n"
185             + "</body>\n"
186             + "</html>";
187 
188         loadPageVerifyTitle2(html);
189     }
190 
191     /**
192      * @throws Exception if the test fails
193      */
194     @Test
195     @Alerts({"", "about:blank?", "blank", "", "about:", ""})
196     public void about_blank_emptyquery_attributes() throws Exception {
197         final String html = DOCTYPE_HTML
198             + "<html>\n"
199             + "<head>\n"
200             + "  <script>\n"
201             + LOG_TITLE_FUNCTION
202             + "    function doTest() {\n"
203             + "      try {\n"
204             + "        var doc = frames[0].document;\n"
205             + "        var location = doc.location;\n"
206             + "        log(location.hash);\n"
207             + "        log(location.href);\n"
208             + "        log(location.pathname);\n"
209             + "        log(location.port);\n"
210             + "        log(location.protocol);\n"
211             + "        log(location.search);\n"
212             + "      } catch(e) { logEx(e); }\n"
213             + "    }\n"
214             + "  </script>\n"
215             + "</head>\n"
216             + "<body onload='doTest()'>\n"
217             + "  <iframe src='about:blank?'></iframe>\n"
218             + "</body>\n"
219             + "</html>";
220 
221         loadPageVerifyTitle2(html);
222     }
223 
224     /**
225      * @throws Exception if the test fails
226      */
227     @Test
228     @Alerts({"#hash", "about:blank#hash", "blank", "", "about:", ""})
229     public void about_blank_hash_attributes() throws Exception {
230         final String html = DOCTYPE_HTML
231             + "<html>\n"
232             + "<head>\n"
233             + "  <script>\n"
234             + LOG_TITLE_FUNCTION
235             + "    function doTest() {\n"
236             + "      try {\n"
237             + "        var doc = frames[0].document;\n"
238             + "        var location = doc.location;\n"
239             + "        log(location.hash);\n"
240             + "        log(location.href);\n"
241             + "        log(location.pathname);\n"
242             + "        log(location.port);\n"
243             + "        log(location.protocol);\n"
244             + "        log(location.search);\n"
245             + "      } catch(e) { logEx(e); }\n"
246             + "    }\n"
247             + "  </script>\n"
248             + "</head>\n"
249             + "<body onload='doTest()'>\n"
250             + "  <iframe src='about:blank#hash'></iframe>\n"
251             + "</body>\n"
252             + "</html>";
253 
254         loadPageVerifyTitle2(html);
255     }
256 
257 
258     /**
259      * @throws Exception if the test fails
260      */
261     @Test
262     @Alerts({"#hash", "about:blank?#hash", "blank", "", "about:", ""})
263     public void about_blank_emptyquery_hash_attributes() throws Exception {
264         final String html = DOCTYPE_HTML
265             + "<html>\n"
266             + "<head>\n"
267             + "  <script>\n"
268             + LOG_TITLE_FUNCTION
269             + "    function doTest() {\n"
270             + "      try {\n"
271             + "        var doc = frames[0].document;\n"
272             + "        var location = doc.location;\n"
273             + "        log(location.hash);\n"
274             + "        log(location.href);\n"
275             + "        log(location.pathname);\n"
276             + "        log(location.port);\n"
277             + "        log(location.protocol);\n"
278             + "        log(location.search);\n"
279             + "      } catch(e) { logEx(e); }\n"
280             + "    }\n"
281             + "  </script>\n"
282             + "</head>\n"
283             + "<body onload='doTest()'>\n"
284             + "  <iframe src='about:blank?#hash'></iframe>\n"
285             + "</body>\n"
286             + "</html>";
287 
288         loadPageVerifyTitle2(html);
289     }
290 
291     /**
292      * @throws Exception if the test fails
293      */
294     @Test
295     @Alerts(DEFAULT = {"#hash", "about:blank?query#hash", "blank", "", "about:", "?query"},
296             FF = {"#hash", "about:blank?query#hash", "blank", "", "about:", ""},
297             FF_ESR = {"#hash", "about:blank?query#hash", "blank", "", "about:", ""})
298     public void about_blank_query_hash_attributes() throws Exception {
299         final String html = DOCTYPE_HTML
300             + "<html>\n"
301             + "<head>\n"
302             + "  <script>\n"
303             + LOG_TITLE_FUNCTION
304             + "    function doTest() {\n"
305             + "      try {\n"
306             + "        var doc = frames[0].document;\n"
307             + "        var location = doc.location;\n"
308             + "        log(location.hash);\n"
309             + "        log(location.href);\n"
310             + "        log(location.pathname);\n"
311             + "        log(location.port);\n"
312             + "        log(location.protocol);\n"
313             + "        log(location.search);\n"
314             + "      } catch(e) { logEx(e); }\n"
315             + "    }\n"
316             + "  </script>\n"
317             + "</head>\n"
318             + "<body onload='doTest()'>\n"
319             + "  <iframe src='about:blank?query#hash'></iframe>\n"
320             + "</body>\n"
321             + "</html>";
322 
323         loadPageVerifyTitle2(html);
324     }
325 
326     /**
327      * @throws Exception if the test fails
328      */
329     @Test
330     @Alerts({"", "about:blank", "#foo", "about:blank#foo"})
331     public void about_blank_set_hash() throws Exception {
332         final String html = DOCTYPE_HTML
333             + "<html>\n"
334             + "<head>\n"
335             + "  <script>\n"
336             + LOG_TITLE_FUNCTION
337             + "    function doTest() {\n"
338             + "      try {\n"
339             + "        var doc = frames[0].document;\n"
340             + "        var location = doc.location;\n"
341 
342             + "        log(location.hash);\n"
343             + "        log(location.href);\n"
344             + "        location.hash = 'foo';\n"
345             + "        log(location.hash);\n"
346             + "        log(location.href);\n"
347             + "      } catch(e) { logEx(e); }\n"
348             + "    }\n"
349             + "  </script>\n"
350             + "</head>\n"
351             + "<body onload='doTest()'>\n"
352             + "  <iframe src='about:blank'></iframe>\n"
353             + "</body>\n"
354             + "</html>";
355 
356         loadPageVerifyTitle2(html);
357     }
358 
359     /**
360      * @throws Exception if an error occurs
361      */
362     @Test
363     @Alerts("?foobar")
364     public void search() throws Exception {
365         checkSearch(URL_FIRST + "?foobar");
366     }
367 
368     /**
369      * @throws Exception if an error occurs
370      */
371     @Test
372     @Alerts("")
373     public void emptySearch() throws Exception {
374         checkSearch(URL_FIRST + "?");
375     }
376 
377     /**
378      * @throws Exception if an error occurs
379      */
380     @Test
381     @Alerts("")
382     public void noSearch() throws Exception {
383         checkSearch(URL_FIRST.toExternalForm());
384     }
385 
386     private void checkSearch(final String url) throws Exception {
387         final String html = DOCTYPE_HTML
388             + "<html><body onload='test()'>\n"
389             + "<script>\n"
390             + LOG_TITLE_FUNCTION
391             + "function test() {\n"
392             + "  log(document.location.search);\n"
393             + "}\n"
394             + "</script>\n"
395             + "</body></html>";
396 
397         getMockWebConnection().setDefaultResponse(html);
398         loadPage2(html, new URL(url));
399         verifyTitle2(getWebDriver(), getExpectedAlerts());
400     }
401 
402     /**
403      * @throws Exception if an error occurs
404      */
405     @Test
406     @Alerts({"#a%20b", "§§URL§§#a%20b", "#a%20b", "§§URL§§#a%20b", "#abc;,/?:@&=+$-_.!~*()ABC123foo",
407              "#%25%20%5E%5B%5D%7C%22%3C%3E%7B%7D%5C"})
408     public void hashEncoding() throws Exception {
409         final String html = DOCTYPE_HTML
410             + "<html><head>\n"
411             + "<script>\n"
412             + LOG_TITLE_FUNCTION
413             + "  function test() {\n"
414             + "    window.location.hash = 'a b';\n"
415             + "    log(window.location.hash);\n"
416             + "    log(window.location.href);\n"
417             + "    window.location.hash = 'a%20b';\n"
418             + "    log(window.location.hash);\n"
419             + "    log(window.location.href);\n"
420             + "    window.location.hash = 'abc;,/?:@&=+$-_.!~*()ABC123foo';\n"
421             + "    log(window.location.hash);\n"
422             + "    window.location.hash = '%25%20%5E%5B%5D%7C%22%3C%3E%7B%7D%5C';\n"
423             + "    log(window.location.hash);\n"
424             + "  }\n"
425             + "</script></head><body onload='test()'>\n"
426             + "</body></html>";
427 
428         expandExpectedAlertsVariables(URL_FIRST);
429         loadPageVerifyTitle2(html);
430     }
431 
432     /**
433      * @throws Exception if an error occurs
434      */
435     @Test
436     @Alerts({"#myDataTable=foo%3Dojkoj", "§§URL§§#myDataTable=foo%3Dojkoj"})
437     @HtmlUnitNYI(CHROME = {"#myDataTable=foo=ojkoj", "§§URL§§#myDataTable=foo%3Dojkoj"},
438             EDGE = {"#myDataTable=foo=ojkoj", "§§URL§§#myDataTable=foo%3Dojkoj"},
439             FF = {"#myDataTable=foo=ojkoj", "§§URL§§#myDataTable=foo%3Dojkoj"},
440             FF_ESR = {"#myDataTable=foo=ojkoj", "§§URL§§#myDataTable=foo%3Dojkoj"})
441     public void hashEncoding2() throws Exception {
442         final String html = DOCTYPE_HTML
443             + "<html><body>\n"
444             + "<script>\n"
445             + LOG_TITLE_FUNCTION
446             + "window.location.hash = 'myDataTable=foo%3Dojkoj';\n"
447             + "log(window.location.hash);\n"
448             + "log(window.location.href);\n"
449             + "</script></body></html>";
450 
451         expandExpectedAlertsVariables(URL_FIRST);
452         loadPageVerifyTitle2(html);
453     }
454 
455     /**
456      * @throws Exception if an error occurs
457      */
458     @Test
459     @Alerts({"#%C3%BC%C3%B6%C3%A4", "§§URL§§#%C3%BC%C3%B6%C3%A4"})
460     public void hashEncoding3() throws Exception {
461         final String html = DOCTYPE_HTML
462             + "<html><body>\n"
463             + "<script>\n"
464             + LOG_TITLE_FUNCTION
465             + "window.location.hash = 'üöä';\n"
466             + "log(window.location.hash);\n"
467             + "log(window.location.href);\n"
468             + "</script></body></html>";
469 
470         expandExpectedAlertsVariables(URL_FIRST);
471         loadPageVerifyTitle2(html);
472     }
473 
474     /**
475      * @throws Exception if an error occurs
476      */
477     @Test
478     @Alerts("#%3Ca%3Efoobar%3C/a%3E")
479     public void hash() throws Exception {
480         checkHash(URL_FIRST + "?#<a>foobar</a>");
481     }
482 
483     /**
484      * @throws Exception if an error occurs
485      */
486     @Test
487     @Alerts("")
488     public void emptyHash() throws Exception {
489         checkHash(URL_FIRST + "#");
490     }
491 
492     /**
493      * @throws Exception if an error occurs
494      */
495     @Test
496     @Alerts("")
497     public void noHash() throws Exception {
498         checkHash(URL_FIRST.toExternalForm());
499     }
500 
501     private void checkHash(final String url) throws Exception {
502         final String html = DOCTYPE_HTML
503             + "<html><body onload='test()'>\n"
504             + "<script>\n"
505             + LOG_TITLE_FUNCTION
506             + "function test() {\n"
507             + "  log(document.location.hash);\n"
508             + "}\n"
509             + "</script>\n"
510             + "</body></html>";
511 
512         getMockWebConnection().setDefaultResponse(html);
513         loadPage2(html, new URL(url));
514         verifyTitle2(getWebDriver(), getExpectedAlerts());
515     }
516 
517     /**
518      * @throws Exception if the test fails
519      */
520     @Test
521     @Alerts({"#hello", "#hi"})
522     public void setHash2() throws Exception {
523         final String html = DOCTYPE_HTML
524             + "<html><head>\n"
525             + "<script>\n"
526             + LOG_TITLE_FUNCTION
527             + "  function test() {\n"
528             + "    window.location.hash = 'hello';\n"
529             + "    log(window.location.hash);\n"
530             + "    window.location.hash = '#hi';\n"
531             + "    log(window.location.hash);\n"
532             + "  }\n"
533             + "</script></head><body onload='test()'>\n"
534             + "</body></html>";
535 
536         loadPageVerifyTitle2(html);
537     }
538 
539     /**
540      * Verifies that setting <tt>location.href</tt> to a hash behaves like setting <tt>location.hash</tt>
541      * (ie doesn't result in a server hit). See bug #688.
542      * @throws Exception if an error occurs
543      */
544     @Test
545     public void setHrefWithOnlyHash() throws Exception {
546         final String html = DOCTYPE_HTML
547                 + "<html><body><script>document.location.href = '#x';</script></body></html>";
548         loadPage2(html);
549     }
550 
551     /**
552      * Verifies that setting <tt>location.href</tt> to a new URL with a hash, where the only difference between the
553      * new URL and the old URL is the hash, behaves like setting <tt>location.hash</tt> (ie doesn't result in a
554      * server hit). See bug 2101735.
555      * @throws Exception if an error occurs
556      */
557     @Test
558     public void setHrefWithOnlyHash2() throws Exception {
559         final String html = "<script>document.location.href = '" + URL_FIRST + "#x';</script>";
560         loadPage2(html);
561     }
562 
563     /**
564      * Test for <tt>replace</tt>.
565      * @throws Exception if the test fails
566      */
567     @Test
568     public void replace() throws Exception {
569         final String html = DOCTYPE_HTML
570             + "<html><head><title>First</title><script>\n"
571             + "function doTest() {\n"
572             + "  location.replace('" + URL_SECOND + "');\n"
573             + "}\n"
574             + "</script></head><body onload='doTest()'>\n"
575             + "</body></html>";
576 
577         final String secondContent = DOCTYPE_HTML
578                 + "<html><head><title>Second</title></head><body></body></html>";
579 
580         getMockWebConnection().setResponse(URL_SECOND, secondContent);
581         final WebDriver driver = loadPage2(html);
582 
583         assertTitle(driver, "Second");
584     }
585 
586     /**
587      * Test for <tt>replace</tt>.
588      * @throws Exception if the test fails
589      */
590     @Test
591     public void replaceLastInHistory() throws Exception {
592         final String startContent = DOCTYPE_HTML
593                 + "<html><head><title>First Page</title></head><body></body></html>";
594 
595         final String secondContent = DOCTYPE_HTML
596             + "<html><head><title>Second Page</title><script>\n"
597             + "function doTest() {\n"
598             + "  location.replace('" + URL_THIRD + "');\n"
599             + "}\n"
600             + "</script></head><body onload='doTest()'>\n"
601             + "</body></html>";
602 
603         final String thirdContent = DOCTYPE_HTML
604                 + "<html><head><title>Third Page§</title></head><body></body></html>";
605 
606         getMockWebConnection().setResponse(URL_SECOND, secondContent);
607         getMockWebConnection().setResponse(URL_THIRD, thirdContent);
608 
609         final WebDriver driver = loadPage2(startContent);
610         driver.get(URL_SECOND.toExternalForm());
611 
612         verifyTitle2(DEFAULT_WAIT_TIME, driver, "Third Page");
613 
614         // navigate back
615         driver.navigate().back();
616         assertTitle(driver, "First Page");
617     }
618 
619     /**
620      * Test for <tt>replace</tt>.
621      * @throws Exception if the test fails
622      */
623     @Test
624     @Alerts("on-load")
625     public void replaceOnload() throws Exception {
626         final String html = DOCTYPE_HTML
627             + "<html><head><title>First</title>\n"
628             + "<script>\n"
629             + LOG_WINDOW_NAME_FUNCTION
630             + "function doTest() {\n"
631             + "  location.replace('" + URL_SECOND + "');\n"
632             + "}\n"
633             + "</script></head>\n"
634             + "<body onload='doTest()'>\n"
635             + "</body></html>";
636 
637         final String secondContent = DOCTYPE_HTML
638                 + "<html><head><title>Second</title></head>\n"
639                 + "<body onload='window.top.name += \"on-load\" + \"\\u00a7\";'></body></html>";
640 
641         getMockWebConnection().setResponse(URL_SECOND, secondContent);
642 
643         final WebDriver driver = loadPage2(html);
644 
645         verifyWindowName2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
646         assertTitle(driver, "Second");
647         assertEquals(2, getMockWebConnection().getRequestCount());
648     }
649 
650     /**
651      * Test for <tt>replace</tt>.
652      * @throws Exception if the test fails
653      */
654     @Test
655     public void replaceFirstInHistory() throws Exception {
656         final String firstContent = DOCTYPE_HTML
657             + "<html><head><title>First Page</title><script>\n"
658             + "function doTest() {\n"
659             + "  location.replace('" + URL_SECOND + "');\n"
660             + "}\n"
661             + "</script></head><body onload='doTest()'>\n"
662             + "</body></html>";
663 
664         final String secondContent = DOCTYPE_HTML
665                 + "<html><head><title>Second Page</title></head><body></body></html>";
666 
667         getMockWebConnection().setResponse(URL_SECOND, secondContent);
668 
669         final WebDriver driver = loadPageWithAlerts2(firstContent);
670         assertTitle(driver, "Second Page");
671     }
672 
673     /**
674      * @throws Exception if the test fails
675      */
676     @Test
677     public void assign() throws Exception {
678         final String firstContent = DOCTYPE_HTML
679             + "<html><head><title>First</title><script>\n"
680             + "  function test() {\n"
681             + "    location.assign('" + URL_SECOND + "');\n"
682             + "  }\n"
683             + "</script></head><body onload='test()'>\n"
684             + "</body></html>";
685 
686         final String secondContent = DOCTYPE_HTML
687                 + "<html><head><title>Second</title></head><body></body></html>";
688 
689         getMockWebConnection().setResponse(URL_SECOND, secondContent);
690 
691         final WebDriver driver = loadPage2(firstContent, URL_FIRST);
692         assertTitle(driver, "Second");
693     }
694 
695     /**
696      * @throws Exception if the test fails
697      */
698     @Test
699     @Alerts("on-load")
700     public void assignOnload() throws Exception {
701         final String firstContent = DOCTYPE_HTML
702             + "<html><head><title>First</title><script>\n"
703             + LOG_WINDOW_NAME_FUNCTION
704             + "  function test() {\n"
705             + "    location.assign('" + URL_SECOND + "');\n"
706             + "  }\n"
707             + "</script></head>\n"
708             + "<body onload='test()'>\n"
709             + "</body></html>";
710 
711         final String secondContent = DOCTYPE_HTML
712                 + "<html><head><title>Second</title></head>\n"
713                 + "<body onload='window.top.name += \"on-load\" + \"\\u00a7\";'></body></html>";
714 
715         getMockWebConnection().setResponse(URL_SECOND, secondContent);
716 
717         final WebDriver driver = loadPage2(firstContent);
718 
719         verifyWindowName2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
720         assertTitle(driver, "Second");
721         assertEquals(2, getMockWebConnection().getRequestCount());
722     }
723 
724     /**
725      * @throws Exception if the test fails
726      */
727     @Test
728     public void assingByEquals() throws Exception {
729         final String firstContent = DOCTYPE_HTML
730             + "<html><head><title>First</title><script>\n"
731             + "  function test() {\n"
732             + "    location = '" + URL_SECOND + "';\n"
733             + "  }\n"
734             + "</script></head><body onload='test()'>\n"
735             + "</body></html>";
736 
737         final String secondContent = DOCTYPE_HTML
738                 + "<html><head><title>Second</title></head><body></body></html>";
739 
740         getMockWebConnection().setResponse(URL_SECOND, secondContent);
741 
742         final WebDriver driver = loadPage2(firstContent, URL_FIRST);
743         assertTitle(driver, "Second");
744     }
745 
746     /**
747      * @throws Exception if the test fails
748      */
749     @Test
750     @Alerts("on-load")
751     public void assingByEqualsOnload() throws Exception {
752         final String firstContent = DOCTYPE_HTML
753             + "<html><head><title>First</title><script>\n"
754             + LOG_WINDOW_NAME_FUNCTION
755             + "  function test() {\n"
756             + "    location  = '" + URL_SECOND + "';\n"
757             + "  }\n"
758             + "</script></head>\n"
759             + "<body onload='test()'>\n"
760             + "</body></html>";
761 
762         final String secondContent = DOCTYPE_HTML
763                 + "<html><head><title>Second</title></head>\n"
764                 + "<body onload='window.top.name += \"on-load\" + \"\\u00a7\";'></body></html>";
765 
766         getMockWebConnection().setResponse(URL_SECOND, secondContent);
767 
768         final WebDriver driver = loadPage2(firstContent);
769 
770         verifyWindowName2(DEFAULT_WAIT_TIME, driver, getExpectedAlerts());
771         assertTitle(driver, "Second");
772         assertEquals(2, getMockWebConnection().getRequestCount());
773     }
774 
775     /**
776      * @throws Exception if the test fails
777      */
778     @Test
779     public void changeLocationToNonHtml() throws Exception {
780         final String html = DOCTYPE_HTML
781             + "<html><head>\n"
782             + "  <script>\n"
783             + "      document.location.href = 'foo.txt';\n"
784             + "  </script>\n"
785             + "</head>\n"
786             + "<body></body></html>";
787 
788         getMockWebConnection().setResponse(new URL(URL_FIRST, "foo.txt"), "bla bla", MimeType.TEXT_PLAIN);
789         final WebDriver driver = loadPage2(html, URL_FIRST);
790         assertTrue(driver.getPageSource().contains("bla bla"));
791     }
792 
793     /**
794      * @throws Exception if the test fails
795      */
796     @Test
797     @Alerts("foo")
798     public void jsLocation() throws Exception {
799         final String html = DOCTYPE_HTML
800             + "<html><head>\n"
801             + "  <script>\n"
802             + LOG_TITLE_FUNCTION
803             + "      document.location.href = 'javascript:log(\"foo\")';\n"
804             + "  </script>\n"
805             + "</head>\n"
806             + "<body></body></html>";
807 
808         loadPageVerifyTitle2(html);
809     }
810 
811     /**
812      * @throws Exception if the test fails
813      */
814     @Test
815     @Alerts({"§§URL§§", "§§URL§§", "§§URL§§"})
816     public void testToString() throws Exception {
817         final String html = DOCTYPE_HTML
818             + "<html><body>\n"
819             + "<script>\n"
820             + LOG_TITLE_FUNCTION
821             + "  var l = window.location;\n"
822             + "  log(l);\n"
823             + "  log('' + l);\n"
824             + "  log(l.toString());\n"
825             + "</script>\n"
826             + "</body></html>";
827 
828         expandExpectedAlertsVariables(URL_FIRST);
829         loadPageVerifyTitle2(html);
830     }
831 
832     /**
833      * @throws Exception if the test fails
834      */
835     @Test
836     @Alerts("1 2 3")
837     public void href_postponed() throws Exception {
838         final String firstHtml = DOCTYPE_HTML
839             + "<html><head><script>\n"
840             + "function test() {\n"
841             + "  document.title += ' 1';\n"
842             + "  self.frames['frame1'].document.location.href = '" + URL_SECOND + "';\n"
843             + "  document.title += ' 2';\n"
844             + "}\n"
845             + "</script></head>\n"
846             + "<body onload='test()'>\n"
847             + "  <iframe name='frame1' id='frame1'/>\n"
848             + "</body></html>";
849         final String secondHtml = DOCTYPE_HTML
850                 + "<html><body><script>top.document.title += ' 3';</script></body></html>";
851 
852         getMockWebConnection().setResponse(URL_SECOND, secondHtml);
853 
854         final WebDriver driver = loadPage2(firstHtml);
855 
856         assertTitle(driver, getExpectedAlerts()[0]);
857     }
858 
859     /**
860      * @throws Exception if the test fails
861      */
862     @Test
863     @Alerts({"", "foo3.html", "foo2.html"})
864     public void onlick_set_location_WithHref() throws Exception {
865         final String html = DOCTYPE_HTML
866             + "<html><head></head>\n"
867             + "<body>\n"
868             + "  <a href='foo2.html' onclick='document.location = \"foo3.html\"'>click me</a>\n"
869             + "</body></html>";
870 
871         getMockWebConnection().setDefaultResponse("");
872         final WebDriver driver = loadPage2(html);
873 
874         assertEquals(new String[] {}, getMockWebConnection().getRequestedUrls(URL_FIRST));
875         driver.findElement(By.tagName("a")).click();
876 
877         assertEquals(getExpectedAlerts(), getMockWebConnection().getRequestedUrls(URL_FIRST));
878         assertEquals(URL_FIRST + "foo2.html", driver.getCurrentUrl());
879     }
880 
881     /**
882      * @throws Exception if the test fails
883      */
884     @Test
885     @Alerts({"", "foo3.html"})
886     public void onlick_set_location_WithoutHref() throws Exception {
887         final String html = DOCTYPE_HTML
888             + "<html><head></head>\n"
889             + "<body>\n"
890             + "  <a onclick='document.location = \"foo3.html\"'>click me</a>\n"
891             + "</body></html>";
892 
893         getMockWebConnection().setDefaultResponse("");
894         final WebDriver driver = loadPage2(html);
895         driver.findElement(By.tagName("a")).click();
896 
897         assertEquals(getExpectedAlerts(), getMockWebConnection().getRequestedUrls(URL_FIRST));
898         assertEquals(URL_FIRST + "foo3.html", driver.getCurrentUrl());
899     }
900 
901     /**
902      * @throws Exception if the test fails
903      */
904     @Test
905     @Alerts({"supported", "onhashchange §§URL§§#1 §§URL§§"})
906     public void onHashChange() throws Exception {
907         final String html = DOCTYPE_HTML
908             + "<html><head>\n"
909             + "<script>\n"
910             + LOG_TITLE_FUNCTION
911             + " if ('onhashchange' in window) { log('supported') }\n"
912             + " function locationHashChanged(event) {\n"
913             + "   if (event) {\n"
914             + "     log('onhashchange ' + event.newURL + ' ' + event.oldURL);\n"
915             + "   } else {\n"
916             + "     log('onhashchange -');\n"
917             + "   }\n"
918             + " }\n"
919             + " window.onhashchange = locationHashChanged;\n"
920             + "</script>\n"
921             + "<body>\n"
922             + "  <a id='click' href='#1'>change hash</a>\n"
923             + "</body></html>";
924 
925         expandExpectedAlertsVariables(URL_FIRST);
926 
927         final WebDriver driver = loadPage2(html);
928         verifyTitle2(driver, getExpectedAlerts()[0]);
929         Thread.sleep(100);
930 
931         driver.findElement(By.id("click")).click();
932         verifyTitle2(driver, getExpectedAlerts());
933     }
934 
935     /**
936      * @throws Exception if the test fails
937      */
938     @Test
939     @Alerts("onhashchange #/foo")
940     public void getNextPageWithOnlyHashChangeShouldTriggerHashChangeEvent() throws Exception {
941         final String html = DOCTYPE_HTML
942             + "<html><body><script>\n"
943             + LOG_TITLE_FUNCTION
944             + " window.onhashchange = function(event) {\n"
945             + "    log('onhashchange ' + window.location.hash);\n"
946             + " }\n"
947             + "</script></body></html>";
948 
949         final WebDriver driver = loadPage2(html);
950         driver.navigate().to(driver.getCurrentUrl() + "#/foo");
951 
952         verifyTitle2(driver, getExpectedAlerts());
953     }
954 
955     /**
956      * @throws Exception if the test fails
957      */
958     @Test
959     @Alerts({"supported", "onhashchange §§URL§§#1  §§URL§§"})
960     public void onHashChangeJS() throws Exception {
961         final String html = DOCTYPE_HTML
962             + "<html><head>\n"
963             + "<script>\n"
964             + LOG_WINDOW_NAME_FUNCTION
965             + " if ('onhashchange' in window) { log('supported') }\n"
966             + " function locationHashChanged(event) {\n"
967             + "   if (event) {\n"
968             + "     log('onhashchange ' + event.newURL + '  ' + event.oldURL);\n"
969             + "   } else {\n"
970             + "     log('onhashchange -');\n"
971             + "   }\n"
972             + " }\n"
973             + " window.onhashchange = locationHashChanged;\n"
974             + "</script>\n"
975             + "</head>\n"
976             + "<body>\n"
977             + "  <button id='click' onclick='location.hash=1'>change hash</button>\n"
978             + "</body></html>";
979 
980         expandExpectedAlertsVariables(URL_FIRST);
981         final WebDriver driver = loadPage2(html);
982         verifyWindowName2(driver, getExpectedAlerts()[0]);
983         Thread.sleep(100);
984 
985         driver.findElement(By.id("click")).click();
986         verifyWindowName2(driver, getExpectedAlerts());
987     }
988 
989     /**
990      * @throws Exception if the test fails
991      */
992     @Test
993     @Alerts({"opened", "closed", "href changed", "§§URL§§test.html"})
994     public void locationAfterOpenClosePopup() throws Exception {
995         final String html = DOCTYPE_HTML
996             + "<html>\n"
997             + "<head>\n"
998             + "  <title>test</title>\n"
999             + "  <script>\n"
1000             + LOG_SESSION_STORAGE_FUNCTION
1001             + "    function test() {\n"
1002             + "      var win = window.open('" + URL_SECOND + "','test','',true);\n"
1003             + "      log('opened');\n"
1004             + "      win.close();\n"
1005             + "      log('closed');\n"
1006             + "      location.href = 'test.html';\n"
1007             + "      log('href changed');\n"
1008             + "    }\n"
1009             + "  </script>\n"
1010             + "</head>\n"
1011             + "<body>\n"
1012             + "  <button id='click' onclick='test()'>Test</button>\n"
1013             + "</body>\n"
1014             + "</html>";
1015         final String popup = DOCTYPE_HTML
1016               + "<html>\n"
1017               + "<head>\n"
1018               + "  <title>popup with script</title>\n"
1019               + "  <script>\n"
1020               + LOG_SESSION_STORAGE_FUNCTION
1021               + "    log('the root of all evil');\n"
1022               + "  </script>\n"
1023               + "</head>\n"
1024               + "<body>Popup</body>\n"
1025               + "</html>";
1026         final String target = DOCTYPE_HTML
1027             + "<html>\n"
1028             + "<head>\n"
1029             + "  <title>target</title>\n"
1030             + "</head>\n"
1031             + "<body>Target</body>\n"
1032             + "</html>";
1033 
1034         getMockWebConnection().setResponse(URL_SECOND, popup);
1035         getMockWebConnection().setResponse(new URL(URL_FIRST, "test.html"), target);
1036 
1037         expandExpectedAlertsVariables(URL_FIRST);
1038         final WebDriver driver = loadPage2(html);
1039         driver.findElement(By.id("click")).click();
1040 
1041         verifySessionStorage2(driver, getExpectedAlerts()[0], getExpectedAlerts()[1], getExpectedAlerts()[2]);
1042         assertEquals(getExpectedAlerts()[3], driver.getCurrentUrl());
1043     }
1044 
1045     /**
1046      * @throws Exception if the test fails
1047      */
1048     @Test
1049     @Alerts("§§URL§§")
1050     public void refererHeaderWhenSettingLocation() throws Exception {
1051         final String html = DOCTYPE_HTML
1052                 + "<html><head><title>Base</title></head>\n"
1053                 + "<body>\n"
1054                 + "  <a id='link' href='content.html' target='content'>Link</a>\n"
1055                 + "  <a id='jsLink' href='#' onclick=\"javascript:window.location='content.html';\">jsLink</a>\n"
1056                 + "</body></html>";
1057 
1058         final String content = DOCTYPE_HTML
1059                 + "<html><head><title>Content</title></head><body><p>content</p></body></html>";
1060 
1061         final MockWebConnection conn = getMockWebConnection();
1062         conn.setResponse(new URL(URL_FIRST, "content.html"), content);
1063 
1064         expandExpectedAlertsVariables(URL_FIRST);
1065         final WebDriver driver = loadPage2(html);
1066 
1067         assertEquals(1, conn.getRequestCount());
1068 
1069         // click an anchor with href and target
1070         driver.findElement(By.id("link")).click();
1071         // because real browsers are doing the open async, we have to be a bit patient
1072         Thread.sleep(DEFAULT_WAIT_TIME.toMillis());
1073 
1074         assertEquals(2, conn.getRequestCount());
1075         Map<String, String> lastAdditionalHeaders = conn.getLastAdditionalHeaders();
1076         assertEquals(getExpectedAlerts()[0], lastAdditionalHeaders.get(HttpHeader.REFERER));
1077 
1078         loadPage2(html);
1079         assertEquals(3, conn.getRequestCount());
1080         // click an anchor with onclick which sets frame.location
1081         driver.findElement(By.id("jsLink")).click();
1082         assertEquals(4, conn.getRequestCount());
1083         lastAdditionalHeaders = conn.getLastAdditionalHeaders();
1084         assertEquals(getExpectedAlerts()[0], lastAdditionalHeaders.get(HttpHeader.REFERER));
1085     }
1086 
1087     /**
1088      * @throws Exception if the test fails
1089      */
1090     @Test
1091     @Alerts("§§URL§§menu.html")
1092     public void refererHeaderWhenSettingFrameLocation() throws Exception {
1093         final String html = DOCTYPE_HTML
1094                 + "<html><head><title>Frameset</title></head>\n"
1095                 + "<frameset rows='20%,80%'>\n"
1096                 + "  <frame src='menu.html' name='menu'>\n"
1097                 + "  <frame src='content.html' name='content'>\n"
1098                 + "</frameset></html>";
1099 
1100         final String menu = DOCTYPE_HTML
1101                 + "<html><head><title>Menu</title></head>\n"
1102                 + "<body>\n"
1103                 + "  <a id='link' href='newContent.html' target='content'>Link</a>\n"
1104                 + "  <a id='jsLink' href='#' "
1105                         + "onclick=\"javascript:top.content.location='newContent.html';\">jsLink</a>\n"
1106                 + "</body></html>";
1107 
1108         final String content = DOCTYPE_HTML
1109                 + "<html><head><title>Content</title></head><body><p>content</p></body></html>";
1110         final String newContent = DOCTYPE_HTML
1111                 + "<html><head><title>New Content</title></head><body><p>new content</p></body></html>";
1112 
1113         final MockWebConnection conn = getMockWebConnection();
1114         conn.setResponse(new URL(URL_FIRST, "menu.html"), menu);
1115         conn.setResponse(new URL(URL_FIRST, "content.html"), content);
1116         conn.setResponse(new URL(URL_FIRST, "newContent.html"), newContent);
1117 
1118         expandExpectedAlertsVariables(URL_FIRST);
1119         final WebDriver driver = loadPage2(html);
1120 
1121         assertEquals(3, conn.getRequestCount());
1122 
1123         // click an anchor with href and target
1124         driver.switchTo().frame(0);
1125         driver.findElement(By.id("link")).click();
1126         if (useRealBrowser()) {
1127             Thread.sleep(400);
1128         }
1129         assertEquals(4, conn.getRequestCount());
1130         Map<String, String> lastAdditionalHeaders = conn.getLastAdditionalHeaders();
1131         assertEquals(getExpectedAlerts()[0], lastAdditionalHeaders.get(HttpHeader.REFERER));
1132 
1133         // click an anchor with onclick which sets frame.location
1134         driver.findElement(By.id("jsLink")).click();
1135         if (useRealBrowser()) {
1136             Thread.sleep(400);
1137         }
1138         assertEquals(5, conn.getRequestCount());
1139         lastAdditionalHeaders = conn.getLastAdditionalHeaders();
1140         assertEquals(getExpectedAlerts()[0], lastAdditionalHeaders.get(HttpHeader.REFERER));
1141     }
1142 
1143     /**
1144      * @throws Exception if the test fails
1145      */
1146     @Test
1147     @Alerts("§§URL§§")
1148     public void origin() throws Exception {
1149         final String html = DOCTYPE_HTML
1150                 + "<html><body><script>\n"
1151                 + LOG_TITLE_FUNCTION
1152                 + "  log(window.location.origin);\n"
1153                 + "</script></body></html>";
1154 
1155         final URL url = URL_FIRST;
1156         final String origin = url.getProtocol() + "://" + url.getHost() + ':' + url.getPort();
1157         expandExpectedAlertsVariables(origin);
1158 
1159         loadPageVerifyTitle2(html);
1160     }
1161 
1162     /**
1163      * @throws Exception if the test fails
1164      */
1165     @Test
1166     @Alerts("§§URL§§")
1167     public void documentOrigin() throws Exception {
1168         final String html = DOCTYPE_HTML
1169                 + "<html><body><script>\n"
1170                 + LOG_TITLE_FUNCTION
1171                 + "  log(document.location.origin);\n"
1172                 + "</script></body></html>";
1173 
1174         final URL url = URL_FIRST;
1175         final String origin = url.getProtocol() + "://" + url.getHost() + ':' + url.getPort();
1176         expandExpectedAlertsVariables(origin);
1177 
1178         loadPageVerifyTitle2(html);
1179     }
1180 
1181     /**
1182      * @throws Exception if the test fails
1183      */
1184     @Test
1185     @Alerts(DEFAULT = "null",
1186             CHROME = "§§URL§§a.html?p1=sieben&p2",
1187             EDGE = "§§URL§§a.html?p1=sieben&p2")
1188     public void reloadGet() throws Exception {
1189         final String html = DOCTYPE_HTML
1190             + "<html>\n"
1191             + "  <head></head>\n"
1192             + "  <body>\n"
1193             + "    <a href='javascript:window.location.reload(true);' id='link'>reload</a>\n"
1194             + "  </body>\n"
1195             + "</html>";
1196 
1197         getMockWebConnection().setDefaultResponse(html);
1198         final WebDriver driver = loadPage2(html, new URL(URL_FIRST + "a.html?p1=sieben&p2"));
1199         assertEquals(1, getMockWebConnection().getRequestCount());
1200 
1201         driver.findElement(By.id("link")).click();
1202         assertEquals(2, getMockWebConnection().getRequestCount());
1203 
1204         assertEquals(HttpMethod.GET, getMockWebConnection().getLastWebRequest().getHttpMethod());
1205         assertEquals(URL_FIRST + "a.html?p1=sieben&p2", getMockWebConnection().getLastWebRequest().getUrl());
1206 
1207         final List<NameValuePair> params = getMockWebConnection().getLastWebRequest().getRequestParameters();
1208         assertEquals(2, params.size());
1209         assertEquals("p1", params.get(0).getName());
1210         assertEquals("sieben", params.get(0).getValue());
1211         assertEquals("p2", params.get(1).getName());
1212         assertEquals("", params.get(1).getValue());
1213 
1214         expandExpectedAlertsVariables(URL_FIRST);
1215         final Map<String, String> additionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1216         assertNull(additionalHeaders.get(HttpHeader.ORIGIN));
1217         assertEquals(getExpectedAlerts()[0], "" + additionalHeaders.get(HttpHeader.REFERER));
1218         assertEquals("localhost:" + PORT, additionalHeaders.get(HttpHeader.HOST));
1219     }
1220 
1221     /**
1222      * @throws Exception if the test fails
1223      */
1224     @Test
1225     @Alerts(DEFAULT = "§§URL§§a.html",
1226             FF = "null",
1227             FF_ESR = "null")
1228     public void reloadGetNoHash() throws Exception {
1229         final String html = DOCTYPE_HTML
1230             + "<html>\n"
1231             + "  <head></head>\n"
1232             + "  <body>\n"
1233             + "    <button onclick='window.location.reload();' id='reload'>reload</button>\n"
1234             + "    <button onclick='window.document.title=window.location.toString();' "
1235                         + "id='log'>log location</button>\n"
1236             + "  </body>\n"
1237             + "</html>";
1238 
1239         getMockWebConnection().setDefaultResponse(html);
1240         final WebDriver driver = loadPage2(html, new URL(URL_FIRST + "a.html"));
1241         assertEquals(1, getMockWebConnection().getRequestCount());
1242 
1243         driver.findElement(By.id("reload")).click();
1244         assertEquals(2, getMockWebConnection().getRequestCount());
1245 
1246         assertEquals(HttpMethod.GET, getMockWebConnection().getLastWebRequest().getHttpMethod());
1247         assertEquals(URL_FIRST + "a.html", getMockWebConnection().getLastWebRequest().getUrl());
1248         expandExpectedAlertsVariables(URL_FIRST);
1249         final Map<String, String> additionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1250         assertNull(additionalHeaders.get(HttpHeader.ORIGIN));
1251         assertEquals(getExpectedAlerts()[0], "" + additionalHeaders.get(HttpHeader.REFERER));
1252         assertEquals("localhost:" + PORT, additionalHeaders.get(HttpHeader.HOST));
1253 
1254         assertEquals(URL_FIRST + "a.html", driver.getCurrentUrl());
1255         driver.findElement(By.id("log")).click();
1256         assertEquals(URL_FIRST + "a.html", driver.getTitle());
1257     }
1258 
1259     /**
1260      * @throws Exception if the test fails
1261      */
1262     @Test
1263     @Alerts(DEFAULT = "§§URL§§a.html",
1264             FF = "null",
1265             FF_ESR = "null")
1266     public void reloadGetHashDetails() throws Exception {
1267         final String html = DOCTYPE_HTML
1268             + "<html>\n"
1269             + "  <head>\n"
1270             + "    <script>\n"
1271             + LOG_SESSION_STORAGE_FUNCTION
1272             + "      function test() {\n"
1273             + "        log('1 ' + window.location);\n"
1274             + "        window.location.hash='1';\n"
1275             + "        log('2 ' + window.location);\n"
1276             + "        window.location.reload();\n"
1277             + "        log('3 ' + window.location);"
1278             + "      }\n"
1279             + "      log('load');\n"
1280             + "    </script>\n"
1281             + "  </head>\n"
1282             + "  <body>\n"
1283             + "    <button onclick='test()' id='reload'>reload</button>\n"
1284             + "    <button onclick='log(\"4 \" + window.location.toString());' id='log'>log location</button>\n"
1285             + "  </body>\n"
1286             + "</html>";
1287 
1288         getMockWebConnection().setDefaultResponse(html);
1289         final WebDriver driver = loadPage2(html, new URL(URL_FIRST + "a.html"));
1290         assertEquals(1, getMockWebConnection().getRequestCount());
1291 
1292         driver.findElement(By.id("reload")).click();
1293         // real ff seems to process the reload a bit async
1294         Thread.sleep(100);
1295         assertEquals(2, getMockWebConnection().getRequestCount());
1296 
1297         assertEquals(HttpMethod.GET, getMockWebConnection().getLastWebRequest().getHttpMethod());
1298         assertEquals(URL_FIRST + "a.html", getMockWebConnection().getLastWebRequest().getUrl());
1299         expandExpectedAlertsVariables(URL_FIRST);
1300         final Map<String, String> additionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1301         assertNull(additionalHeaders.get(HttpHeader.ORIGIN));
1302         assertEquals(getExpectedAlerts()[0], "" + additionalHeaders.get(HttpHeader.REFERER));
1303         assertEquals("localhost:" + PORT, additionalHeaders.get(HttpHeader.HOST));
1304 
1305         assertEquals(URL_FIRST + "a.html#1", driver.getCurrentUrl());
1306         driver.findElement(By.id("log")).click();
1307         verifySessionStorage2(driver, new String[] {"load", "1 http://localhost:22222/a.html",
1308             "2 http://localhost:22222/a.html#1", "3 http://localhost:22222/a.html#1",
1309             "load", "4 http://localhost:22222/a.html#1"});
1310     }
1311 
1312     /**
1313      * @throws Exception if the test fails
1314      */
1315     @Test
1316     @Alerts(DEFAULT = "§§URL§§a.html",
1317             FF = "null",
1318             FF_ESR = "null")
1319     public void reloadGetHash() throws Exception {
1320         final String html = DOCTYPE_HTML
1321             + "<html>\n"
1322             + "  <head></head>\n"
1323             + "  <body>\n"
1324             + "    <button onclick='window.location.hash=\"1\";' id='changeHash'>change hash</button>\n"
1325             + "    <button onclick='window.location.reload();' id='reload'>reload</button>\n"
1326             + "    <button onclick='window.document.title=window.location.toString();' id='log'>log location</button>\n"
1327             + "  </body>\n"
1328             + "</html>";
1329 
1330         getMockWebConnection().setDefaultResponse(html);
1331         final WebDriver driver = loadPage2(html, new URL(URL_FIRST + "a.html"));
1332         assertEquals(1, getMockWebConnection().getRequestCount());
1333 
1334         // make sure changing the hash itself does not trigger the reload
1335         driver.findElement(By.id("changeHash")).click();
1336         assertEquals(1, getMockWebConnection().getRequestCount());
1337 
1338         // reload
1339         driver.findElement(By.id("reload")).click();
1340         assertEquals(2, getMockWebConnection().getRequestCount());
1341 
1342         assertEquals(HttpMethod.GET, getMockWebConnection().getLastWebRequest().getHttpMethod());
1343         assertEquals(URL_FIRST + "a.html", getMockWebConnection().getLastWebRequest().getUrl());
1344         expandExpectedAlertsVariables(URL_FIRST);
1345         final Map<String, String> additionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1346         assertNull(additionalHeaders.get(HttpHeader.ORIGIN));
1347         assertEquals(getExpectedAlerts()[0], "" + additionalHeaders.get(HttpHeader.REFERER));
1348         assertEquals("localhost:" + PORT, additionalHeaders.get(HttpHeader.HOST));
1349 
1350         assertEquals(URL_FIRST + "a.html#1", driver.getCurrentUrl());
1351         driver.findElement(By.id("log")).click();
1352         assertEquals(URL_FIRST + "a.html#1", driver.getTitle());
1353     }
1354 
1355     /**
1356      * @throws Exception if the test fails
1357      */
1358     @Test
1359     @Alerts(DEFAULT = "§§URL§§a.html",
1360             FF = "null",
1361             FF_ESR = "null")
1362     public void reloadGetHashChanged() throws Exception {
1363         final String html = DOCTYPE_HTML
1364             + "<html>\n"
1365             + "  <head></head>\n"
1366             + "  <body>\n"
1367             + "    <button onclick='window.location.hash=\"1\";' id='changeHash'>change hash</button>\n"
1368             + "    <button onclick='window.location.reload();' id='reload'>reload</button>\n"
1369             + "    <button onclick='window.document.title=window.location.toString();' id='log'>log location</button>\n"
1370             + "  </body>\n"
1371             + "</html>";
1372 
1373         getMockWebConnection().setDefaultResponse(html);
1374         final WebDriver driver = loadPage2(html, new URL(URL_FIRST + "a.html#abc"));
1375         assertEquals(1, getMockWebConnection().getRequestCount());
1376 
1377         // make sure changing the hash itself does not trigger the reload
1378         driver.findElement(By.id("changeHash")).click();
1379         assertEquals(1, getMockWebConnection().getRequestCount());
1380 
1381         // reload
1382         driver.findElement(By.id("reload")).click();
1383         assertEquals(2, getMockWebConnection().getRequestCount());
1384 
1385         assertEquals(HttpMethod.GET, getMockWebConnection().getLastWebRequest().getHttpMethod());
1386         assertEquals(URL_FIRST + "a.html", getMockWebConnection().getLastWebRequest().getUrl());
1387         expandExpectedAlertsVariables(URL_FIRST);
1388         final Map<String, String> additionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1389         assertNull(additionalHeaders.get(HttpHeader.ORIGIN));
1390         assertEquals(getExpectedAlerts()[0], "" + additionalHeaders.get(HttpHeader.REFERER));
1391         assertEquals("localhost:" + PORT, additionalHeaders.get(HttpHeader.HOST));
1392 
1393         assertEquals(URL_FIRST + "a.html#1", driver.getCurrentUrl());
1394         driver.findElement(By.id("log")).click();
1395         assertEquals(URL_FIRST + "a.html#1", driver.getTitle());
1396     }
1397 
1398     /**
1399      * @throws Exception if the test fails
1400      */
1401     @Test
1402     @Alerts(CHROME = {"3", "§§URL§§", "§§URL§§/second/a.html?urlParam=urlVal"},
1403             EDGE = {"3", "§§URL§§", "§§URL§§/second/a.html?urlParam=urlVal"},
1404             FF = {"3", "§§URL§§", "§§URL§§/"},
1405             FF_ESR = {"3", "§§URL§§", "§§URL§§/"})
1406     public void reloadPost() throws Exception {
1407         final String form = DOCTYPE_HTML
1408               + "<html>\n"
1409               + "  <head></head>\n"
1410               + "  <body>\n"
1411               + "    <form method='POST' name='form' action='" + URL_SECOND + "a.html?urlParam=urlVal'>\n"
1412               + "      <input type='hidden' name='p1' value='seven'>\n"
1413               + "      <input type='hidden' name='p2' value=''>\n"
1414               + "      <input type='submit' id='enter' name='sub' value='ok'>\n"
1415               + "    </form>\n"
1416               + "  </body>\n"
1417               + "</html>";
1418 
1419         final String html = DOCTYPE_HTML
1420             + "<html>\n"
1421             + "  <head></head>\n"
1422             + "  <body>\n"
1423             + "    <a href='javascript:window.location.reload(true);' id='link'>reload</a>\n"
1424             + "  </body>\n"
1425             + "</html>";
1426 
1427         getMockWebConnection().setDefaultResponse(html);
1428 
1429         final WebDriver driver = loadPage2(form, URL_FIRST);
1430         assertEquals(1, getMockWebConnection().getRequestCount());
1431         driver.findElement(By.id("enter")).click();
1432 
1433         assertEquals(2, getMockWebConnection().getRequestCount());
1434 
1435         driver.findElement(By.id("link")).click();
1436 
1437         // works only in the debugger
1438         try {
1439             driver.switchTo().alert().accept();
1440         }
1441         catch (final NoAlertPresentException e) {
1442             // ignore
1443         }
1444         assertEquals(Integer.parseInt(getExpectedAlerts()[0]), getMockWebConnection().getRequestCount());
1445 
1446         assertEquals(HttpMethod.POST, getMockWebConnection().getLastWebRequest().getHttpMethod());
1447         assertEquals(URL_SECOND + "a.html?urlParam=urlVal", getMockWebConnection().getLastWebRequest().getUrl());
1448 
1449         final List<NameValuePair> params = getMockWebConnection().getLastWebRequest().getRequestParameters();
1450         assertEquals(4, params.size());
1451 
1452         assertEquals("urlParam", params.get(0).getName());
1453         assertEquals("urlVal", params.get(0).getValue());
1454 
1455         assertEquals("p1", params.get(1).getName());
1456         assertEquals("seven", params.get(1).getValue());
1457         assertEquals("p2", params.get(2).getName());
1458         assertEquals("", params.get(2).getValue());
1459 
1460         assertEquals("sub", params.get(3).getName());
1461         assertEquals("ok", params.get(3).getValue());
1462 
1463         expandExpectedAlertsVariables("http://localhost:" + PORT);
1464         final Map<String, String> additionalHeaders = getMockWebConnection().getLastAdditionalHeaders();
1465         assertEquals(getExpectedAlerts()[1], "" + additionalHeaders.get(HttpHeader.ORIGIN));
1466         assertEquals(getExpectedAlerts()[2], additionalHeaders.get(HttpHeader.REFERER));
1467         assertEquals("localhost:" + PORT, additionalHeaders.get(HttpHeader.HOST));
1468     }
1469 
1470     /**
1471      * Tests that location.reload() works correctly when invoked across frames.
1472      * @throws Exception if the test fails
1473      */
1474     @Test
1475     @Alerts({"§§URL§§upper.html", "§§URL§§lower.html"})
1476     public void reloadAcrossFrames() throws Exception {
1477         final String framesetContent = DOCTYPE_HTML
1478             + "<html>\n"
1479             + "  <frameset rows='100,*'>\n"
1480             + "    <frame name='upper' src='upper.html'/>\n"
1481             + "    <frame name='lower' src='lower.html'/>\n"
1482             + "  </frameset>\n"
1483             + "</html>";
1484 
1485         final String upperContent = DOCTYPE_HTML
1486             + "<html><body><h1>upper</h1></body></html>";
1487         final String lowerContent = DOCTYPE_HTML
1488             + "<html><head>\n"
1489             + "<script>\n"
1490             + "function test() {\n"
1491             + "  parent.upper.location.reload();\n"
1492             + "}\n"
1493             + "</script>\n"
1494             + "</head>\n"
1495             + "<body><h1>lower</h1><button id='tester' onclick='test()'>test</button></body></html>";
1496 
1497         getMockWebConnection().setResponse(URL_FIRST, framesetContent);
1498         getMockWebConnection().setResponse(new URL(URL_FIRST, "upper.html"), upperContent);
1499         getMockWebConnection().setResponse(new URL(URL_FIRST, "lower.html"), lowerContent);
1500 
1501         final WebDriver driver = loadPage2(framesetContent, URL_FIRST);
1502 
1503         expandExpectedAlertsVariables(URL_FIRST);
1504         driver.switchTo().frame("upper");
1505         assertEquals(getExpectedAlerts()[0],
1506                 ((JavascriptExecutor) driver).executeScript("return document.location.href"));
1507         driver.switchTo().defaultContent();
1508         driver.switchTo().frame("lower");
1509         assertEquals(getExpectedAlerts()[1],
1510                 ((JavascriptExecutor) driver).executeScript("return document.location.href"));
1511 
1512         driver.findElement(By.id("tester")).click();
1513 
1514         driver.switchTo().defaultContent();
1515         driver.switchTo().frame("upper");
1516         assertEquals(getExpectedAlerts()[0],
1517                 ((JavascriptExecutor) driver).executeScript("return document.location.href"));
1518         driver.switchTo().defaultContent();
1519         driver.switchTo().frame("lower");
1520         assertEquals(getExpectedAlerts()[1],
1521                 ((JavascriptExecutor) driver).executeScript("return document.location.href"));
1522     }
1523 
1524     /**
1525      * @throws Exception if the test fails
1526      */
1527     @Test
1528     @Alerts(DEFAULT = "ancestorOrigins,assign,hash,host,hostname,href,origin,"
1529                     + "pathname,port,protocol,reload,replace,search,toString",
1530             FF = "assign,hash,host,hostname,href,origin,"
1531                + "pathname,port,protocol,reload,replace,search,toString",
1532             FF_ESR = "assign,hash,host,hostname,href,origin,"
1533                    + "pathname,port,protocol,reload,replace,search,toString")
1534     @HtmlUnitNYI(CHROME = "assign,hash,host,hostname,href,origin,"
1535                         + "pathname,port,protocol,reload,replace,search,toString",
1536                  EDGE = "assign,hash,host,hostname,href,origin,"
1537                       + "pathname,port,protocol,reload,replace,search,toString")
1538     public void keys() throws Exception {
1539         final String html = DOCTYPE_HTML
1540             + "<html><head></head>\n"
1541             + "<body>\n"
1542             + "<script>\n"
1543             + LOG_TITLE_FUNCTION
1544             + "  var keys = Object.keys(location);\n"
1545             + "  keys.sort();\n"
1546             + "  log(keys);\n"
1547             + "</script></head>\n"
1548             + "</body></html>";
1549 
1550         expandExpectedAlertsVariables(URL_FIRST);
1551         loadPageVerifyTitle2(html);
1552     }
1553 
1554     /**
1555      * @throws Exception if the test fails
1556      */
1557     @Test
1558     @Alerts("")
1559     public void protoKeys() throws Exception {
1560         final String html = DOCTYPE_HTML
1561             + "<html><head></head>\n"
1562             + "<body>\n"
1563             + "<script>\n"
1564             + LOG_TITLE_FUNCTION
1565             + "  var keys = Object.keys(location.__proto__);\n"
1566             + "  keys.sort();\n"
1567             + "  log(keys);\n"
1568             + "</script></head>\n"
1569             + "</body></html>";
1570 
1571         expandExpectedAlertsVariables(URL_FIRST);
1572         loadPageVerifyTitle2(html);
1573     }
1574 
1575     /**
1576      * @throws Exception if the test fails
1577      */
1578     @Test
1579     @Alerts({"assign - {\"writable\":false,\"enumerable\":true,\"configurable\":false}",
1580              "hash - {\"enumerable\":true,\"configurable\":false}",
1581              "host - {\"enumerable\":true,\"configurable\":false}",
1582              "hostname - {\"enumerable\":true,\"configurable\":false}",
1583              "href - {\"enumerable\":true,\"configurable\":false}",
1584              "origin - {\"enumerable\":true,\"configurable\":false}",
1585              "pathname - {\"enumerable\":true,\"configurable\":false}",
1586              "port - {\"enumerable\":true,\"configurable\":false}",
1587              "protocol - {\"enumerable\":true,\"configurable\":false}",
1588              "reload - {\"writable\":false,\"enumerable\":true,\"configurable\":false}",
1589              "replace - {\"writable\":false,\"enumerable\":true,\"configurable\":false}",
1590              "search - {\"enumerable\":true,\"configurable\":false}",
1591              "toString - {\"writable\":false,\"enumerable\":true,\"configurable\":false}"})
1592     public void ownPropertyDescriptor() throws Exception {
1593         final String html = DOCTYPE_HTML
1594             + "<html><head></head>\n"
1595             + "<body>\n"
1596             + "<script>\n"
1597             + LOG_TITLE_FUNCTION
1598             + "  var props = ['assign', 'hash', 'host', 'hostname', 'href', "
1599                     + "'origin', 'pathname', 'port', 'protocol', 'reload', 'replace', 'search', 'toString'];\n"
1600             + "  props.forEach("
1601             + "    item => log(item + ' - ' + JSON.stringify(Object.getOwnPropertyDescriptor(window.location, item)))"
1602             + "  );\n"
1603             + "</script></head>\n"
1604             + "</body></html>";
1605 
1606         expandExpectedAlertsVariables(URL_FIRST);
1607         loadPageVerifyTitle2(html);
1608     }
1609 }