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