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 static java.nio.charset.StandardCharsets.ISO_8859_1;
18  
19  import java.io.File;
20  
21  import org.apache.commons.io.FileUtils;
22  import org.htmlunit.WebDriverTestCase;
23  import org.htmlunit.junit.BrowserRunner;
24  import org.htmlunit.junit.annotation.Alerts;
25  import org.htmlunit.junit.annotation.HtmlUnitNYI;
26  import org.junit.Assert;
27  import org.junit.Test;
28  import org.junit.runner.RunWith;
29  import org.openqa.selenium.By;
30  import org.openqa.selenium.WebDriver;
31  
32  /**
33   * Tests for {@link URL}.
34   *
35   * @author Ronald Brill
36   */
37  @RunWith(BrowserRunner.class)
38  public class URLTest extends WebDriverTestCase {
39  
40      /**
41       * @throws Exception if an error occurs
42       */
43      @Test
44      @Alerts("function URL() { [native code] }")
45      public void windowURL() throws Exception {
46          final String html = DOCTYPE_HTML
47              + "<html>\n"
48              + "<head>\n"
49              + "  <script>\n"
50              + LOG_TITLE_FUNCTION
51              + "    function test() {\n"
52              + "      log(window.URL);\n"
53              + "    }\n"
54              + "  </script>\n"
55              + "</head>\n"
56              + "<body onload='test()'>\n"
57              + "</body>\n"
58              + "</html>";
59          loadPageVerifyTitle2(html);
60      }
61  
62      /**
63       * @throws Exception if an error occurs
64       */
65      @Test
66      @Alerts({"https://developer.mozilla.org/", "https://developer.mozilla.org/",
67               "https://developer.mozilla.org/en-US/docs", "https://developer.mozilla.org/en-US/docs",
68               "https://developer.mozilla.org/en-US/docs", "https://developer.mozilla.org/en-US/docs",
69               "http://www.example.com/", "type error", "type error" })
70      public void ctor() throws Exception {
71          final String html = DOCTYPE_HTML
72              + "<html>\n"
73              + "<head>\n"
74              + "  <script>\n"
75              + LOG_TITLE_FUNCTION
76              + "    function test() {\n"
77              + "      if (typeof window.URL === 'function') {\n"
78              + "        log(new URL('/', 'https://developer.mozilla.org'));\n"
79              + "        var b = new URL('https://developer.mozilla.org');\n"
80              + "        log(b);\n"
81              + "        log(new URL('en-US/docs', b));\n"
82              + "        var d = new URL('/en-US/docs', b);\n"
83              + "        log(d);\n"
84              + "        log(new URL('/en-US/docs', d));\n"
85              + "        log(new URL('/en-US/docs', 'https://developer.mozilla.org/fr-FR/toto'));\n"
86              + "        log(new URL('http://www.example.com', 'https://developers.mozilla.com'));\n"
87              + "        try {\n"
88              + "          new URL('/en-US/docs', '');\n"
89              + "        } catch(e) { log('type error'); }\n"
90              + "        try {\n"
91              + "          new URL('/en-US/docs');\n"
92              + "        } catch(e) { log('type error'); }\n"
93              + "      }\n"
94              + "    }\n"
95              + "  </script>\n"
96              + "</head>\n"
97              + "<body onload='test()'>\n"
98              + "</body>\n"
99              + "</html>";
100 
101         loadPageVerifyTitle2(html);
102     }
103 
104     /**
105      * @throws Exception if an error occurs
106      */
107     @Test
108     @Alerts("http://developer.mozilla.org")
109     public void origin() throws Exception {
110         final String html = DOCTYPE_HTML
111             + "<html>\n"
112             + "<head>\n"
113             + "  <script>\n"
114             + LOG_TITLE_FUNCTION
115             + "    function test() {\n"
116             + "      if (typeof window.URL === 'function') {\n"
117             + "        var u = new URL('http://developer.mozilla.org/en-US/docs');\n"
118             + "        log(u.origin);\n"
119             + "      }\n"
120             + "    }\n"
121             + "  </script>\n"
122             + "</head>\n"
123             + "<body onload='test()'>\n"
124             + "</body>\n"
125             + "</html>";
126         loadPageVerifyTitle2(html);
127     }
128 
129     /**
130      * @throws Exception if an error occurs
131      */
132     @Test
133     @Alerts("http://developer.mozilla.org")
134     public void originDefaultPort() throws Exception {
135         final String html = DOCTYPE_HTML
136             + "<html>\n"
137             + "<head>\n"
138             + "  <script>\n"
139             + LOG_TITLE_FUNCTION
140             + "    function test() {\n"
141             + "      if (typeof window.URL === 'function') {\n"
142             + "        var u = new URL('http://developer.mozilla.org:80/en-US/docs');\n"
143             + "        log(u.origin);\n"
144             + "      }\n"
145             + "    }\n"
146             + "  </script>\n"
147             + "</head>\n"
148             + "<body onload='test()'>\n"
149             + "</body>\n"
150             + "</html>";
151         loadPageVerifyTitle2(html);
152     }
153 
154     /**
155      * @throws Exception if an error occurs
156      */
157     @Test
158     @Alerts("http://developer.mozilla.org:1234")
159     public void originPort() throws Exception {
160         final String html = DOCTYPE_HTML
161             + "<html>\n"
162             + "<head>\n"
163             + "  <script>\n"
164             + LOG_TITLE_FUNCTION
165             + "    function test() {\n"
166             + "      if (typeof window.URL === 'function') {\n"
167             + "        var u = new URL('http://developer.mozilla.org:1234/en-US/docs');\n"
168             + "        log(u.origin);\n"
169             + "      }\n"
170             + "    }\n"
171             + "  </script>\n"
172             + "</head>\n"
173             + "<body onload='test()'>\n"
174             + "</body>\n"
175             + "</html>";
176         loadPageVerifyTitle2(html);
177     }
178 
179     /**
180      * @throws Exception if the test fails
181      */
182     @Test
183     public void createObjectURL() throws Exception {
184         final String html = DOCTYPE_HTML
185             + "<html>\n"
186             + "<head>\n"
187             + "<script>\n"
188             + "function test() {\n"
189             + "  if (document.testForm.fileupload.files) {\n"
190             + "    var files = document.testForm.fileupload.files;\n"
191 
192             + "    var url = window.URL.createObjectURL(files[0]);\n"
193             + "    alert(url);\n"
194             + "    window.URL.revokeObjectURL(url);\n"
195             + "  }\n"
196             + "}\n"
197             + "</script>\n"
198             + "</head>\n"
199             + "<body>\n"
200             + "  <form name='testForm'>\n"
201             + "    <input type='file' id='fileupload' name='fileupload'>\n"
202             + "  </form>\n"
203             + "  <button id='testBtn' onclick='test()'>Tester</button>\n"
204             + "</body>\n"
205             + "</html>";
206 
207         final WebDriver driver = loadPage2(html);
208 
209         final File tstFile = File.createTempFile("HtmlUnitUploadTest", ".txt");
210         try {
211             FileUtils.writeStringToFile(tstFile, "Hello HtmlUnit", ISO_8859_1);
212 
213             final String path = tstFile.getCanonicalPath();
214             driver.findElement(By.name("fileupload")).sendKeys(path);
215 
216             driver.findElement(By.id("testBtn")).click();
217 
218             final String url = getCollectedAlerts(driver, 1).get(0);
219             Assert.assertTrue(url, url.startsWith("blob:"));
220         }
221         finally {
222             FileUtils.deleteQuietly(tstFile);
223         }
224     }
225 
226     /**
227      * @throws Exception if an error occurs
228      */
229     @Test
230     @Alerts({"", "a=u&x="})
231     public void searchParams() throws Exception {
232         final String html = DOCTYPE_HTML
233             + "<html>\n"
234             + "<head>\n"
235             + "  <script>\n"
236             + LOG_TITLE_FUNCTION
237             + "    function test() {\n"
238             + "      if (typeof window.URL === 'function') {\n"
239             + "        var u = new URL('http://developer.mozilla.org/en-US/docs');\n"
240             + "        log(u.searchParams);\n"
241             + "        u = new URL('http://developer.mozilla.org/en-US/docs?a=u&x');\n"
242             + "        log(u.searchParams);\n"
243             + "      }\n"
244             + "    }\n"
245             + "  </script>\n"
246             + "</head>\n"
247             + "<body onload='test()'>\n"
248             + "</body>\n"
249             + "</html>";
250         loadPageVerifyTitle2(html);
251     }
252 
253     /**
254      * @throws Exception if an error occurs
255      */
256     @Test
257     @Alerts({"", "a=u&x=", "x=22", "x=22"})
258     public void searchParamsSyncedWithUrlChanges() throws Exception {
259         final String html = DOCTYPE_HTML
260             + "<html>\n"
261             + "<head>\n"
262             + "  <script>\n"
263             + LOG_TITLE_FUNCTION
264             + "    function test() {\n"
265             + "      if (typeof window.URL === 'function') {\n"
266             + "        var u = new URL('http://developer.mozilla.org/en-US/docs');\n"
267             + "        log(u.searchParams);\n"
268             + "        u = new URL('http://developer.mozilla.org/en-US/docs?a=u&x');\n"
269 
270             + "        var param = u.searchParams;\n"
271             + "        log(param);\n"
272 
273             + "        u.search = 'x=22';\n"
274             + "        log(u.searchParams);\n"
275             + "        log(param);\n"
276             + "      }\n"
277             + "    }\n"
278             + "  </script>\n"
279             + "</head>\n"
280             + "<body onload='test()'>\n"
281             + "</body>\n"
282             + "</html>";
283         loadPageVerifyTitle2(html);
284     }
285 
286     /**
287      * @throws Exception if the test fails
288      */
289     @Test
290     @Alerts({"/", "/en-US/docs", "/en-US/docs"})
291     public void getPathName() throws Exception {
292         final String html = DOCTYPE_HTML
293                         + "<html>\n"
294                         + "<head>\n"
295                         + "  <script>\n"
296                         + LOG_TITLE_FUNCTION
297                         + "    function test() {\n"
298                         + "      if (typeof window.URL === 'function') {\n"
299                         + "        var u = new URL('http://developer.mozilla.org');\n"
300                         + "        log(u.pathname);\n"
301                         + "        u = new URL('http://developer.mozilla.org/en-US/docs');\n"
302                         + "        log(u.pathname);\n"
303                         + "        u = new URL('http://developer.mozilla.org/en-US/docs?a=u&x');\n"
304                         + "        log(u.pathname);\n"
305                         + "      }\n"
306                         + "    }\n"
307                         + "  </script>\n"
308                         + "</head>\n"
309                         + "<body onload='test()'>\n"
310                         + "</body>\n"
311                         + "</html>";
312         loadPageVerifyTitle2(html);
313     }
314 
315     /**
316      * @throws Exception if the test fails
317      */
318     @Test
319     @Alerts({"/path", "/path",
320              "http://developer.mozilla.org/new/path?a=u&x",
321              "http://developer.mozilla.org/?a=u&x"})
322     public void setPathName() throws Exception {
323         final String html = DOCTYPE_HTML
324                         + "<html>\n"
325                         + "<head>\n"
326                         + "  <script>\n"
327                         + LOG_TITLE_FUNCTION
328                         + "    function test() {\n"
329                         + "      if (typeof window.URL === 'function') {\n"
330                         + "        var u = new URL('http://developer.mozilla.org');\n"
331                         + "        u.pathname = 'path';\n"
332                         + "        log(u.pathname);\n"
333                         + "        u.pathname = '/path';\n"
334                         + "        log(u.pathname);\n"
335                         + "        u = new URL('http://developer.mozilla.org/en-US/docs?a=u&x');\n"
336                         + "        u.pathname = 'new/path';"
337                         + "        log(u.toString());\n"
338                         + "        u.pathname='';\n"
339                         + "        log(u.toString());\n"
340                         + "      }\n"
341                         + "    }\n"
342                         + "  </script>\n"
343                         + "</head>\n"
344                         + "<body onload='test()'>\n"
345                         + "</body>\n"
346                         + "</html>";
347         loadPageVerifyTitle2(html);
348     }
349 
350     /**
351      * @throws Exception if the test fails
352      */
353     @Test
354     @Alerts({"", "#abcd", "#bcd",
355              "#hash", "http://developer.mozilla.org/?a=b#hash",
356              "", "http://developer.mozilla.org/?a=b",
357              "#undefined", "http://developer.mozilla.org/#undefined",
358              "#null", "http://developer.mozilla.org/#null"})
359     public void hash() throws Exception {
360         final String html = DOCTYPE_HTML
361                         + "<html>\n"
362                         + "<head>\n"
363                         + "  <script>\n"
364                         + LOG_TITLE_FUNCTION
365                         + "    function test() {\n"
366                         + "      if (typeof window.URL === 'function') {\n"
367                         + "        var u = new URL('http://developer.mozilla.org');\n"
368                         + "        log(u.hash);\n"
369 
370                         + "        u = new URL('http://developer.mozilla.org#abcd');\n"
371                         + "        log(u.hash);\n"
372 
373                         + "        u = new URL('http://developer.mozilla.org?a=b#bcd');\n"
374                         + "        log(u.hash);\n"
375 
376                         + "        u.hash = 'hash';\n"
377                         + "        log(u.hash);\n"
378                         + "        log(u.toString());\n"
379 
380                         + "        u.hash = '';\n"
381                         + "        log(u.hash);\n"
382                         + "        log(u.toString());\n"
383 
384                         + "        u = new URL('http://developer.mozilla.org#bcd');\n"
385                         + "        u.hash = undefined;\n"
386                         + "        log(u.hash);\n"
387                         + "        log(u.toString());\n"
388 
389                         + "        u = new URL('http://developer.mozilla.org#bcd');\n"
390                         + "        u.hash = null;\n"
391                         + "        log(u.hash);\n"
392                         + "        log(u.toString());\n"
393                         + "      }\n"
394                         + "    }\n"
395                         + "  </script>\n"
396                         + "</head>\n"
397                         + "<body onload='test()'>\n"
398                         + "</body>\n"
399                         + "</html>";
400         loadPageVerifyTitle2(html);
401     }
402 
403     /**
404      * @throws Exception if the test fails
405      */
406     @Test
407     @Alerts({"developer.mozilla.org", "developer.mozilla.org",
408              "new.host", "new.host:1234", "new.host:1234", "0.0.91.160:80",
409              "0.0.0.17:80", "0.0.6.182:80",
410              "new.host", "new.host",
411              "developer.mozilla.org", "developer.mozilla.org:4097", "developer.mozilla.org:80"})
412     public void host() throws Exception {
413         final String html = DOCTYPE_HTML
414                         + "<html>\n"
415                         + "<head>\n"
416                         + "  <script>\n"
417                         + LOG_TITLE_FUNCTION
418                         + "    function test() {\n"
419                         + "      if (typeof window.URL === 'function') {\n"
420                         + "        var u = new URL('https://developer.mozilla.org/en-US/docs/Web/API/URL/host');\n"
421                         + "        log(u.host);\n"
422 
423                         + "        u.host = '';\n"
424                         + "        log(u.host);\n"
425 
426                         + "        u.host = 'new.host';\n"
427                         + "        log(u.host);\n"
428 
429                         + "        u.host = 'new.host:1234';\n"
430                         + "        log(u.host);\n"
431 
432                         + "        u.host = ':447';\n"
433                         + "        log(u.host);\n"
434 
435                         + "        u.host = '23456:80';\n"
436                         + "        log(u.host);\n"
437 
438                         + "        u.host = 17;\n"
439                         + "        log(u.host);\n"
440 
441                         + "        u.host = 1718;\n"
442                         + "        log(u.host);\n"
443 
444                         + "        var u = new URL('https://host.com');\n"
445                         + "        u.host = 'new.host:443';\n" //same port as protocol
446                         + "        log(u.host);\n"
447 
448                         + "        var u = new URL('http://host.com');\n"
449                         + "        u.host = 'new.host:80';\n" //same port as protocol
450                         + "        log(u.host);\n"
451 
452                         + "        u = new URL('https://developer.mozilla.org/en-US/docs/Web/API/URL/host');\n"
453                         + "        log(u.host);"
454 
455                         + "        u = new URL('https://developer.mozilla.org:4097/en-US/docs/Web/API/URL/host');\n"
456                         + "        log(u.host);"
457 
458                         + "        u = new URL('https://developer.mozilla.org:80/en-US/docs/Web/API/URL/host');\n"
459                         + "        log(u.host);"
460                         + "      }\n"
461                         + "    }\n"
462                         + "  </script>\n"
463                         + "</head>\n"
464                         + "<body onload='test()'>\n"
465                         + "</body>\n"
466                         + "</html>";
467         loadPageVerifyTitle2(html);
468     }
469 
470     /**
471      * @throws Exception if the test fails
472      */
473     @Test
474     @Alerts(DEFAULT = {"developer.mozilla.org",
475                        "developer.mozilla.org", "https://developer.mozilla.org/en-US/docs/Web/API/URL/host",
476                        "htmlunit-dev.org", "https://htmlunit-dev.org/en-US/docs/Web/API/URL/host",
477                        "htmlunit-dev.org", "https://htmlunit-dev.org/en-US/docs/Web/API/URL/host"},
478             CHROME =  {"developer.mozilla.org",
479                        "developer.mozilla.org", "https://developer.mozilla.org/en-US/docs/Web/API/URL/host",
480                        "htmlunit-dev.org", "https://htmlunit-dev.org/en-US/docs/Web/API/URL/host",
481                        "%20%20", "https://%20%20/en-US/docs/Web/API/URL/host"},
482             EDGE = {"developer.mozilla.org",
483                     "developer.mozilla.org", "https://developer.mozilla.org/en-US/docs/Web/API/URL/host",
484                     "htmlunit-dev.org", "https://htmlunit-dev.org/en-US/docs/Web/API/URL/host",
485                     "%20%20", "https://%20%20/en-US/docs/Web/API/URL/host"})
486     @HtmlUnitNYI(CHROME =  {"developer.mozilla.org",
487                             "developer.mozilla.org", "https://developer.mozilla.org/en-US/docs/Web/API/URL/host",
488                             "htmlunit-dev.org", "https://htmlunit-dev.org/en-US/docs/Web/API/URL/host",
489                             "%20%20", "https:// /en-US/docs/Web/API/URL/host"},
490                 EDGE = {"developer.mozilla.org",
491                         "developer.mozilla.org", "https://developer.mozilla.org/en-US/docs/Web/API/URL/host",
492                         "htmlunit-dev.org", "https://htmlunit-dev.org/en-US/docs/Web/API/URL/host",
493                         "%20%20", "https:// /en-US/docs/Web/API/URL/host"})
494     public void hostname() throws Exception {
495         final String html = DOCTYPE_HTML
496                         + "<html>\n"
497                         + "<head>\n"
498                         + "  <script>\n"
499                         + LOG_TITLE_FUNCTION
500                         + "    function test() {\n"
501                         + "      if (typeof window.URL === 'function') {\n"
502                         + "        var u = new URL('https://developer.mozilla.org:443/en-US/docs/Web/API/URL/host');\n"
503                         + "        log(u.hostname);\n"
504 
505                         + "        u.hostname = '';\n"
506                         + "        log(u.hostname);\n"
507                         + "        log(u.toString());\n"
508 
509                         + "        u.hostname = 'htmlunit-dev.org';\n"
510                         + "        log(u.hostname);\n"
511                         + "        log(u.toString());\n"
512 
513                         + "        u.hostname = '  ';\n"
514                         + "        log(u.hostname);\n"
515                         + "        log(u.toString());\n"
516                         + "      }\n"
517                         + "    }\n"
518                         + "  </script>\n"
519                         + "</head>\n"
520                         + "<body onload='test()'>\n"
521                         + "</body>\n"
522                         + "</html>";
523         loadPageVerifyTitle2(html);
524     }
525 
526     /**
527      * @throws Exception if the test fails
528      */
529     @Test
530     @Alerts({"https://developer.mozilla.org/en-US/docs/Web/API/URL/host",
531              "http://new.com/href", "http://new.com/hrefWithPort"})
532     public void href() throws Exception {
533         final String html = DOCTYPE_HTML
534                         + "<html>\n"
535                         + "<head>\n"
536                         + "  <script>\n"
537                         + LOG_TITLE_FUNCTION
538                         + "    function test() {\n"
539                         + "      if (typeof window.URL === 'function') {\n"
540                         + "        var u = new URL('https://developer.mozilla.org:443/en-US/docs/Web/API/URL/host');\n"
541                         + "        log(u.href);\n"
542 
543                         + "        u.href = 'http://new.com/href';\n"
544                         + "        log(u.href);\n"
545 
546                         + "        u.href = 'http://new.com:80/hrefWithPort';\n"
547                         + "        log(u.href);\n"
548                         + "      }\n"
549                         + "    }\n"
550                         + "  </script>\n"
551                         + "</head>\n"
552                         + "<body onload='test()'>\n"
553                         + "</body>\n"
554                         + "</html>";
555         loadPageVerifyTitle2(html);
556     }
557 
558     /**
559      * @throws Exception if the test fails
560      */
561     @Test
562     @Alerts({"flabada",
563              "", "https://anonymous@developer.mozilla.org/",
564              "pass", "https://anonymous:pass@developer.mozilla.org/",
565              "17", "https://anonymous:17@developer.mozilla.org/",
566              "undefined", "https://anonymous:undefined@developer.mozilla.org/",
567              "null", "https://anonymous:null@developer.mozilla.org/"})
568     public void password() throws Exception {
569         final String html = DOCTYPE_HTML
570                         + "<html>\n"
571                         + "<head>\n"
572                         + "  <script>\n"
573                         + LOG_TITLE_FUNCTION
574                         + "    function test() {\n"
575                         + "      if (typeof window.URL === 'function') {\n"
576                         + "        var u = new URL('https://anonymous:flabada@developer.mozilla.org');\n"
577                         + "        log(u.password);\n"
578 
579                         + "        u.password = '';\n"
580                         + "        log(u.password);\n"
581                         + "        log(u.toString());\n"
582 
583                         + "        u.password = 'pass';\n"
584                         + "        log(u.password);\n"
585                         + "        log(u.toString());\n"
586 
587                         + "        u.password = 17;\n"
588                         + "        log(u.password);\n"
589                         + "        log(u.toString());\n"
590 
591                         + "        u.password = undefined;\n"
592                         + "        log(u.password);\n"
593                         + "        log(u.toString());\n"
594 
595                         + "        u.password = null;\n"
596                         + "        log(u.password);\n"
597                         + "        log(u.toString());\n"
598                         + "      }\n"
599                         + "    }\n"
600                         + "  </script>\n"
601                         + "</head>\n"
602                         + "<body onload='test()'>\n"
603                         + "</body>\n"
604                         + "</html>";
605         loadPageVerifyTitle2(html);
606     }
607 
608     /**
609      * @throws Exception if the test fails
610      */
611     @Test
612     @Alerts({"80", "123", "", "https://mydomain.com/svn/Repos/",
613              "", "http://mydomain.com/svn/Repos/"})
614     public void port() throws Exception {
615         final String html = DOCTYPE_HTML
616                         + "<html>\n"
617                         + "<head>\n"
618                         + "  <script>\n"
619                         + LOG_TITLE_FUNCTION
620                         + "    function test() {\n"
621                         + "      if (typeof window.URL === 'function') {\n"
622                         + "        var u = new URL('https://mydomain.com:80/svn/Repos/');\n"
623                         + "        log(u.port);\n"
624                         + "        u.port = '123';\n"
625                         + "        log(u.port);\n"
626                         + "        u.port = '443';\n"
627                         + "        log(u.port);\n"
628                         + "        log(u.toString());\n"
629                         + "        u = new URL('http://mydomain.com:123/svn/Repos/');\n"
630                         + "        u.port = '80';\n"
631                         + "        log(u.port);\n"
632                         + "        log(u.toString());\n"
633                         + "      }\n"
634                         + "    }\n"
635                         + "  </script>\n"
636                         + "</head>\n"
637                         + "<body onload='test()'>\n"
638                         + "</body>\n"
639                         + "</html>";
640         loadPageVerifyTitle2(html);
641     }
642 
643     /**
644      * @throws Exception if the test fails
645      */
646     @Test
647     @Alerts({"https:",
648              "http:", "http://mydomain.com/svn/Repos/",
649              "http:", "http://mydomain.com/svn/Repos/",
650              "http:", "http://mydomain.com/svn/Repos/",
651              "http:", "http://mydomain.com/svn/Repos/",
652              "http:", "http://mydomain.com/svn/Repos/",
653              "http:", "http://mydomain.com/svn/Repos/",
654              "http:", "http://mydomain.com/svn/Repos/",
655              "http:", "http://mydomain.com/svn/Repos/",
656              "ex-unknown", "ReferenceError"})
657     public void protocol() throws Exception {
658         final String html = DOCTYPE_HTML
659                         + "<html>\n"
660                         + "<head>\n"
661                         + "  <script>\n"
662                         + LOG_TITLE_FUNCTION
663                         + "    function test() {\n"
664                         + "      if (typeof window.URL === 'function') {\n"
665                         + "        var u = new URL('https://mydomain.com:80/svn/Repos/');\n"
666                         + "        log(u.protocol);\n"
667 
668                         + "        u.protocol = 'http';\n"
669                         + "        log(u.protocol);\n"
670                         + "        log(u.toString());\n"
671 
672                         + "        u.protocol = '';\n"
673                         + "        log(u.protocol);\n"
674                         + "        log(u.toString());\n"
675 
676                         + "        u.protocol = 'axdeg';\n"
677                         + "        log(u.protocol);\n"
678                         + "        log(u.toString());\n"
679 
680                         + "        u.protocol = 'hTTp';\n"
681                         + "        log(u.protocol);\n"
682                         + "        log(u.toString());\n"
683 
684                         + "        u.protocol = ' http ';\n"
685                         + "        log(u.protocol);\n"
686                         + "        log(u.toString());\n"
687 
688                         + "        u.protocol = 'axdeg ';\n"
689                         + "        log(u.protocol);\n"
690                         + "        log(u.toString());\n"
691 
692                         + "        u.protocol = ' axdeg ';\n"
693                         + "        log(u.protocol);\n"
694                         + "        log(u.toString());\n"
695 
696                         + "        try {\n"
697                         + "          u.protocol = null;\n"
698                         + "          log(u.protocol);\n"
699                         + "          log(u.toString());\n"
700                         + "        } catch(e) { log('ex-null'); logEx(e); }\n"
701 
702                         + "        try {\n"
703                         + "          u.protocol = unknown;\n"
704                         + "          log(u.protocol);\n"
705                         + "          log(u.toString());\n"
706                         + "        } catch(e) { log('ex-unknown'); logEx(e); }\n"
707                         + "      }\n"
708                         + "    }\n"
709                         + "  </script>\n"
710                         + "</head>\n"
711                         + "<body onload='test()'>\n"
712                         + "</body>\n"
713                         + "</html>";
714         loadPageVerifyTitle2(html);
715     }
716 
717     /**
718      * @throws Exception if the test fails
719      */
720     @Test
721     @Alerts({"https:",
722              "http:", "http://mydomain.com/svn/Repos/",
723              "http:", "http://mydomain.com/svn/Repos/",
724              "http:", "http://mydomain.com/svn/Repos/",
725              "http:", "http://mydomain.com/svn/Repos/",
726              "http:", "http://mydomain.com/svn/Repos/",
727              "http:", "http://mydomain.com/svn/Repos/",
728              "http:", "http://mydomain.com/svn/Repos/",
729              "ex-unknown", "ReferenceError"})
730     public void protocol2() throws Exception {
731         final String html = DOCTYPE_HTML
732                         + "<html>\n"
733                         + "<head>\n"
734                         + "  <script>\n"
735                         + LOG_TITLE_FUNCTION
736                         + "    function test() {\n"
737                         + "      if (typeof window.URL === 'function') {\n"
738                         + "        var u = new URL('https://mydomain.com:80/svn/Repos/');\n"
739                         + "        log(u.protocol);\n"
740 
741                         + "        u.protocol = 'http:';\n"
742                         + "        log(u.protocol);\n"
743                         + "        log(u.toString());\n"
744 
745                         + "        u.protocol = '';\n"
746                         + "        log(u.protocol);\n"
747                         + "        log(u.toString());\n"
748 
749                         + "        u.protocol = 'axdeg:';\n"
750                         + "        log(u.protocol);\n"
751                         + "        log(u.toString());\n"
752 
753                         + "        u.protocol = 'hTTp:';\n"
754                         + "        log(u.protocol);\n"
755                         + "        log(u.toString());\n"
756 
757                         + "        u.protocol = 'axdeg: ';\n"
758                         + "        log(u.protocol);\n"
759                         + "        log(u.toString());\n"
760 
761                         + "        u.protocol = ' axdeg: ';\n"
762                         + "        log(u.protocol);\n"
763                         + "        log(u.toString());\n"
764 
765                         + "        try {\n"
766                         + "          u.protocol = null;\n"
767                         + "          log(u.protocol);\n"
768                         + "          log(u.toString());\n"
769                         + "        } catch(e) { log('ex-null'); logEx(e); }\n"
770 
771                         + "        try {\n"
772                         + "          u.protocol = unknown;\n"
773                         + "          log(u.protocol);\n"
774                         + "          log(u.toString());\n"
775                         + "        } catch(e) { log('ex-unknown'); logEx(e); }\n"
776                         + "      }\n"
777                         + "    }\n"
778                         + "  </script>\n"
779                         + "</head>\n"
780                         + "<body onload='test()'>\n"
781                         + "</body>\n"
782                         + "</html>";
783         loadPageVerifyTitle2(html);
784     }
785 
786     /**
787      * @throws Exception if the test fails
788      */
789     @Test
790     @Alerts({"https:",
791              "http:", "http://mydomain.com/svn/Repos/",
792              "http:", "http://mydomain.com/svn/Repos/",
793              "http:", "http://mydomain.com/svn/Repos/",
794              "http:", "http://mydomain.com/svn/Repos/",
795              "http:", "http://mydomain.com/svn/Repos/",
796              "http:", "http://mydomain.com/svn/Repos/",
797              "http:", "http://mydomain.com/svn/Repos/",
798              "ex-unknown", "ReferenceError"})
799     public void protocol3() throws Exception {
800         final String html = DOCTYPE_HTML
801                         + "<html>\n"
802                         + "<head>\n"
803                         + "  <script>\n"
804                         + LOG_TITLE_FUNCTION
805                         + "    function test() {\n"
806                         + "      if (typeof window.URL === 'function') {\n"
807                         + "        var u = new URL('https://mydomain.com:80/svn/Repos/');\n"
808                         + "        log(u.protocol);\n"
809 
810                         + "        u.protocol = 'http://www.htmlunit.org';\n"
811                         + "        log(u.protocol);\n"
812                         + "        log(u.toString());\n"
813 
814                         + "        u.protocol = '';\n"
815                         + "        log(u.protocol);\n"
816                         + "        log(u.toString());\n"
817 
818                         + "        u.protocol = 'axdeg://www.htmlunit.org';\n"
819                         + "        log(u.protocol);\n"
820                         + "        log(u.toString());\n"
821 
822                         + "        u.protocol = 'hTTp://www.htmlunit.org';\n"
823                         + "        log(u.protocol);\n"
824                         + "        log(u.toString());\n"
825 
826                         + "        u.protocol = 'axdeg://www.htmlunit.org ';\n"
827                         + "        log(u.protocol);\n"
828                         + "        log(u.toString());\n"
829 
830                         + "        u.protocol = ' axdeg://www.htmlunit.org ';\n"
831                         + "        log(u.protocol);\n"
832                         + "        log(u.toString());\n"
833 
834                         + "        try {\n"
835                         + "          u.protocol = null;\n"
836                         + "          log(u.protocol);\n"
837                         + "          log(u.toString());\n"
838                         + "        } catch(e) { log('ex-null'); logEx(e); }\n"
839 
840                         + "        try {\n"
841                         + "          u.protocol = unknown;\n"
842                         + "          log(u.protocol);\n"
843                         + "          log(u.toString());\n"
844                         + "        } catch(e) { log('ex-unknown'); logEx(e); }\n"
845                         + "      }\n"
846                         + "    }\n"
847                         + "  </script>\n"
848                         + "</head>\n"
849                         + "<body onload='test()'>\n"
850                         + "</body>\n"
851                         + "</html>";
852         loadPageVerifyTitle2(html);
853     }
854 
855     /**
856      * @throws Exception if the test fails
857      */
858     @Test
859     @Alerts(DEFAULT = {"https:",
860                        "http:", "http://mydomain.com/svn/Repos/",
861                        "https:", "https://mydomain.com/svn/Repos/",
862                        "ftp:", "ftp://mydomain.com/svn/Repos/",
863                        "ftp:", "ftp://mydomain.com/svn/Repos/",
864                        "ws:", "ws://mydomain.com/svn/Repos/",
865                        "wss:", "wss://mydomain.com/svn/Repos/",
866                        "file:", "file://mydomain.com/svn/Repos/"},
867             FF = {"https:",
868                   "http:", "http://mydomain.com/svn/Repos/",
869                   "https:", "https://mydomain.com/svn/Repos/",
870                   "ftp:", "ftp://mydomain.com/svn/Repos/",
871                   "ftp:", "ftp://mydomain.com/svn/Repos/",
872                   "ws:", "ws://mydomain.com/svn/Repos/",
873                   "wss:", "wss://mydomain.com/svn/Repos/",
874                   "file:", "file:///svn/Repos/"},
875             FF_ESR = {"https:",
876                       "http:", "http://mydomain.com/svn/Repos/",
877                       "https:", "https://mydomain.com/svn/Repos/",
878                       "ftp:", "ftp://mydomain.com/svn/Repos/",
879                       "ftp:", "ftp://mydomain.com/svn/Repos/",
880                       "ws:", "ws://mydomain.com/svn/Repos/",
881                       "wss:", "wss://mydomain.com/svn/Repos/",
882                       "file:", "file:///svn/Repos/"})
883     @HtmlUnitNYI(
884             FF = {"https:",
885                   "http:", "http://mydomain.com/svn/Repos/",
886                   "https:", "https://mydomain.com/svn/Repos/",
887                   "ftp:", "ftp://mydomain.com/svn/Repos/",
888                   "ftp:", "ftp://mydomain.com/svn/Repos/",
889                   "ws:", "ws://mydomain.com/svn/Repos/",
890                   "wss:", "wss://mydomain.com/svn/Repos/",
891                   "file:", "file://mydomain.com/svn/Repos/"},
892             FF_ESR = {"https:",
893                       "http:", "http://mydomain.com/svn/Repos/",
894                       "https:", "https://mydomain.com/svn/Repos/",
895                       "ftp:", "ftp://mydomain.com/svn/Repos/",
896                       "ftp:", "ftp://mydomain.com/svn/Repos/",
897                       "ws:", "ws://mydomain.com/svn/Repos/",
898                       "wss:", "wss://mydomain.com/svn/Repos/",
899                       "file:", "file://mydomain.com/svn/Repos/"})
900     public void specialScheme() throws Exception {
901         final String html = DOCTYPE_HTML
902                         + "<html>\n"
903                         + "<head>\n"
904                         + "  <script>\n"
905                         + LOG_TITLE_FUNCTION
906                         + "    function test() {\n"
907                         + "      if (typeof window.URL === 'function') {\n"
908                         + "        var u = new URL('https://mydomain.com:80/svn/Repos/');\n"
909                         + "        log(u.protocol);\n"
910 
911                         + "        u.protocol = 'http';\n"
912                         + "        log(u.protocol);\n"
913                         + "        log(u.toString());\n"
914 
915                         + "        u.protocol = 'https';\n"
916                         + "        log(u.protocol);\n"
917                         + "        log(u.toString());\n"
918 
919                         + "        u.protocol = 'ftp';\n"
920                         + "        log(u.protocol);\n"
921                         + "        log(u.toString());\n"
922 
923                         + "        u.protocol = 'ftps';\n"
924                         + "        log(u.protocol);\n"
925                         + "        log(u.toString());\n"
926 
927                         + "        u.protocol = 'ws';\n"
928                         + "        log(u.protocol);\n"
929                         + "        log(u.toString());\n"
930 
931                         + "        u.protocol = 'wss';\n"
932                         + "        log(u.protocol);\n"
933                         + "        log(u.toString());\n"
934 
935                         + "        u.protocol = 'file';\n"
936                         + "        log(u.protocol);\n"
937                         + "        log(u.toString());\n"
938                         + "      }\n"
939                         + "    }\n"
940                         + "  </script>\n"
941                         + "</head>\n"
942                         + "<body onload='test()'>\n"
943                         + "</body>\n"
944                         + "</html>";
945         loadPageVerifyTitle2(html);
946     }
947 
948     /**
949      * @throws Exception if the test fails
950      */
951     @Test
952     @Alerts({"?q=123",
953              "?a=b&c=d", "https://developer.mozilla.org/search?a=b&c=d",
954              "?a=7", "https://developer.mozilla.org/search?a=7",
955              "?17", "https://developer.mozilla.org/search?17",
956              "", "https://developer.mozilla.org/search",
957              "?Html%20Unit", "https://developer.mozilla.org/search?Html%20Unit",
958              "?Html?Unit", "https://developer.mozilla.org/search?Html?Unit",
959              "?Html/Unit", "https://developer.mozilla.org/search?Html/Unit",
960              "?undefined", "https://developer.mozilla.org/search?undefined",
961              "?null", "https://developer.mozilla.org/search?null"})
962     public void search() throws Exception {
963         final String html = DOCTYPE_HTML
964                         + "<html>\n"
965                         + "<head>\n"
966                         + "  <script>\n"
967                         + LOG_TITLE_FUNCTION
968                         + "    function test() {\n"
969                         + "      if (typeof window.URL === 'function') {\n"
970                         + "        var u = new URL('https://developer.mozilla.org/search?q=123');\n"
971                         + "        log(u.search);\n"
972 
973                         + "        u.search = 'a=b&c=d';\n"
974                         + "        log(u.search);\n"
975                         + "        log(u.toString());\n"
976 
977                         + "        u.search = '?a=7';\n"
978                         + "        log(u.search);\n"
979                         + "        log(u.toString());\n"
980 
981                         + "        u.search = 17;\n"
982                         + "        log(u.search);\n"
983                         + "        log(u.toString());\n"
984 
985                         + "        u.search = '';\n"
986                         + "        log(u.search);\n"
987                         + "        log(u.toString());\n"
988 
989                         + "        u.search = 'Html Unit';\n"
990                         + "        log(u.search);\n"
991                         + "        log(u.toString());\n"
992 
993                         + "        u.search = 'Html?Unit';\n"
994                         + "        log(u.search);\n"
995                         + "        log(u.toString());\n"
996 
997                         + "        u.search = 'Html/Unit';\n"
998                         + "        log(u.search);\n"
999                         + "        log(u.toString());\n"
1000 
1001                         + "        u = new URL('https://developer.mozilla.org/search?q=123');\n"
1002                         + "        u.search = undefined;\n"
1003                         + "        log(u.search);\n"
1004                         + "        log(u.toString());\n"
1005 
1006                         + "        u.search = null;\n"
1007                         + "        log(u.search);\n"
1008                         + "        log(u.toString());\n"
1009                         + "      }\n"
1010                         + "    }\n"
1011                         + "  </script>\n"
1012                         + "</head>\n"
1013                         + "<body onload='test()'>\n"
1014                         + "</body>\n"
1015                         + "</html>";
1016         loadPageVerifyTitle2(html);
1017     }
1018 
1019     /**
1020      * @throws Exception if the test fails
1021      */
1022     @Test
1023     @Alerts({"https://developer.mozilla.org/search?q%20a=1%202%203", "?q%20a=1%202%203"})
1024     @HtmlUnitNYI(CHROME = {"https://developer.mozilla.org/search?q a=1 2 3", "?q a=1 2 3"},
1025                  EDGE = {"https://developer.mozilla.org/search?q a=1 2 3", "?q a=1 2 3"},
1026                  FF = {"https://developer.mozilla.org/search?q a=1 2 3", "?q a=1 2 3"},
1027                  FF_ESR = {"https://developer.mozilla.org/search?q a=1 2 3", "?q a=1 2 3"})
1028     public void searchEncoding() throws Exception {
1029         final String html = DOCTYPE_HTML
1030                         + "<html>\n"
1031                         + "<head>\n"
1032                         + "  <script>\n"
1033                         + LOG_TITLE_FUNCTION
1034                         + "    function test() {\n"
1035                         + "      if (typeof window.URL === 'function') {\n"
1036                         + "        var u = new URL('https://developer.mozilla.org/search?q a=1 2 3');\n"
1037                         + "        log(u);\n"
1038                         + "        log(u.search);\n"
1039                         + "      }\n"
1040                         + "    }\n"
1041                         + "  </script>\n"
1042                         + "</head>\n"
1043                         + "<body onload='test()'>\n"
1044                         + "</body>\n"
1045                         + "</html>";
1046         loadPageVerifyTitle2(html);
1047     }
1048 
1049     /**
1050      * @throws Exception if the test fails
1051      */
1052     @Test
1053     @Alerts({"anonymous",
1054              "user", "https://user:flabada@developer.mozilla.org/",
1055              "", "https://:flabada@developer.mozilla.org/",
1056              "anonymous", "anonymous", "", "",
1057              "user", "https://user:pass@developer.mozilla.org/",
1058              "17", "https://17:pass@developer.mozilla.org/",
1059              "undefined", "https://undefined:pass@developer.mozilla.org/",
1060              "null", "https://null:pass@developer.mozilla.org/"})
1061     public void username() throws Exception {
1062         final String html = DOCTYPE_HTML
1063                         + "<html>\n"
1064                         + "<head>\n"
1065                         + "  <script>\n"
1066                         + LOG_TITLE_FUNCTION
1067                         + "    function test() {\n"
1068                         + "      if (typeof window.URL === 'function') {\n"
1069                         + "        var u = new URL('https://anonymous:flabada@developer.mozilla.org');\n"
1070                         + "        log(u.username);\n"
1071 
1072                         + "        u.username = 'user';\n"
1073                         + "        log(u.username);\n"
1074                         + "        log(u.toString());\n"
1075 
1076                         + "        u.username = '';\n"
1077                         + "        log(u.username);\n"
1078                         + "        log(u.toString());\n"
1079 
1080                         + "        u = new URL('https://anonymous@developer.mozilla.org');\n"
1081                         + "        log(u.username);\n"
1082 
1083                         + "        u = new URL('https://anonymous:@developer.mozilla.org');\n"
1084                         + "        log(u.username);\n"
1085 
1086                         + "        u = new URL('https://developer.mozilla.org:443');\n"
1087                         + "        log(u.username);\n"
1088 
1089                         + "        u = new URL('https://:pass@developer.mozilla.org:443');\n"
1090                         + "        log(u.username);\n"
1091 
1092                         + "        u.username = 'user';\n"
1093                         + "        log(u.username);\n"
1094                         + "        log(u.toString());\n"
1095 
1096                         + "        u.username = 17;\n"
1097                         + "        log(u.username);\n"
1098                         + "        log(u.toString());\n"
1099 
1100                         + "        u.username = undefined;\n"
1101                         + "        log(u.username);\n"
1102                         + "        log(u.toString());\n"
1103 
1104                         + "        u.username = null;\n"
1105                         + "        log(u.username);\n"
1106                         + "        log(u.toString());\n"
1107                         + "      }\n"
1108                         + "    }\n"
1109                         + "  </script>\n"
1110                         + "</head>\n"
1111                         + "<body onload='test()'>\n"
1112                         + "</body>\n"
1113                         + "</html>";
1114         loadPageVerifyTitle2(html);
1115     }
1116 
1117     /**
1118      * @throws Exception if the test fails
1119      */
1120     @Test
1121     @Alerts({"function URL() { [native code] }",
1122              "function URL() { [native code] }",
1123              "function URL() { [native code] }",
1124              "https://developer.mozilla.org/",
1125              "https://developer.mozilla.org/",
1126              "https://developer.mozilla.org/"})
1127     public void testToString() throws Exception {
1128         final String html = DOCTYPE_HTML
1129             + "<html><body>\n"
1130             + "<script>\n"
1131             + LOG_TITLE_FUNCTION
1132             + "  if (typeof window.URL === 'function') {\n"
1133             + "    log(URL);\n"
1134             + "    log('' + URL);\n"
1135             + "    log(URL.toString());\n"
1136 
1137             + "    var u = new URL('/', 'https://developer.mozilla.org');\n"
1138             + "    log(u);\n"
1139             + "    log('' + u);\n"
1140             + "    log(u.toString());\n"
1141             + "  }\n"
1142             + "</script>\n"
1143             + "</body></html>";
1144 
1145         loadPageVerifyTitle2(html);
1146     }
1147 
1148     /**
1149      * @throws Exception if an error occurs
1150      */
1151     @Test
1152     @Alerts("https://developer.mozilla.org/")
1153     public void testToJSON() throws Exception {
1154         final String html = DOCTYPE_HTML
1155                 + "<html><body>\n"
1156                 + "<script>\n"
1157                 + LOG_TITLE_FUNCTION
1158                 + "  if (typeof window.URL === 'function') {\n"
1159                 + "    var u = new URL('/', 'https://developer.mozilla.org');\n"
1160                 + "    log(u.toJSON());\n"
1161                 + "  }\n"
1162                 + "</script>\n"
1163                 + "</body></html>";
1164 
1165         loadPageVerifyTitle2(html);
1166     }
1167 
1168     /**
1169      * @throws Exception if the test fails
1170      */
1171     @Test
1172     @Alerts({"https://htmlunit.org/", "https://htmlunit.org/", "true"})
1173     public void webkitURL() throws Exception {
1174         final String html = DOCTYPE_HTML
1175             + "<html><head>\n"
1176             + "<script>\n"
1177             + LOG_TITLE_FUNCTION
1178             + "function test() {\n"
1179             + "  if (typeof window.URL === 'function') {\n"
1180             + "    var url = new URL('https://htmlunit.org');\n"
1181             + "    var wkUrl = new webkitURL('https://htmlunit.org');\n"
1182             + "    log(url);\n"
1183             + "    log(wkUrl);\n"
1184             + "    log(Object.getPrototypeOf(url) == Object.getPrototypeOf(wkUrl));\n"
1185             + "  }\n"
1186             + "}\n"
1187             + "</script></head>\n"
1188             + "<body onload='test()'>\n"
1189             + "</body></html>";
1190 
1191         loadPageVerifyTitle2(html);
1192     }
1193 }