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