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 org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.corejs.javascript.NativePromise;
19  import org.htmlunit.junit.annotation.Alerts;
20  import org.junit.jupiter.api.Test;
21  import org.openqa.selenium.By;
22  import org.openqa.selenium.WebDriver;
23  
24  /**
25   * Tests for {@link NativePromise}.
26   *
27   * @author Ahmed Ashour
28   * @author Marc Guillemot
29   * @author Madis Pärn
30   * @author Ronald Brill
31   * @author Rural Hunter
32   */
33  public class PromiseTest extends WebDriverTestCase {
34  
35      /**
36       * @throws Exception if an error occurs
37       */
38      @Test
39      @Alerts({"function", "function", "undefined", "undefined",
40               "undefined", "undefined", "function", "function"})
41      public void staticMethods() 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              + "      if (window.Promise) {\n"
49              + "        log(typeof Promise.resolve);\n"
50              + "        log(typeof Promise.reject);\n"
51              + "        log(typeof Promise.then);\n"
52              + "        log(typeof Promise.catch);\n"
53              + "        var p = Promise.resolve('something');\n"
54              + "        log(typeof p.resolve);\n"
55              + "        log(typeof p.reject);\n"
56              + "        log(typeof p.then);\n"
57              + "        log(typeof p.catch);\n"
58              + "      }\n"
59              + "    }\n"
60              + "  </script>\n"
61              + "</head>\n"
62              + "<body onload='test()'>\n"
63              + "</body>\n"
64              + "</html>";
65  
66          loadPageVerifyTitle2(html);
67      }
68  
69      /**
70       * @throws Exception if an error occurs
71       */
72      @Test
73      @Alerts("1")
74      public void length() throws Exception {
75          final String html =
76              "<html>\n"
77              + "<head>\n"
78              + "  <script>\n"
79              + LOG_TEXTAREA_FUNCTION
80              + "    function test() {\n"
81              + "      if (window.Promise) {\n"
82              + "        log(Promise.length);\n"
83              + "      }\n"
84              + "    }\n"
85              + "  </script>\n"
86              + "</head>\n"
87              + "<body onload='test()'>\n"
88              + LOG_TEXTAREA
89              + "</body>\n"
90              + "</html>";
91  
92          loadPageVerifyTextArea2(html);
93      }
94  
95      /**
96       * @throws Exception if an error occurs
97       */
98      @Test
99      @Alerts(DEFAULT = {"function () { [native code] }",
100                        "function () { [native code] }",
101                        "[object Window]",
102                        "done", "resolved value"},
103             FF = {"function () {\n    [native code]\n}",
104                   "function () {\n    [native code]\n}",
105                   "[object Window]",
106                   "done", "resolved value"},
107             FF_ESR = {"function () {\n    [native code]\n}",
108                       "function () {\n    [native code]\n}",
109                       "[object Window]",
110                       "done", "resolved value"})
111     public void constructor() throws Exception {
112         final String html = DOCTYPE_HTML
113                 + "<html>\n"
114                 + "<head>\n"
115                 + "  <script>\n"
116                 + LOG_TEXTAREA_FUNCTION
117                 + "    function test() {\n"
118                 + "      if (window.Promise) {\n"
119                 + "        var p = new Promise(function(resolve, reject) {\n"
120                 + "          log(resolve);\n"
121                 + "          log(reject);\n"
122                 + "          log(this);\n"
123                 + "          resolve('resolved value');\n"
124                 + "        });\n"
125                 + "        p.then(function(value) {log(value);});\n"
126                 + "        log('done');\n"
127                 + "      }\n"
128                 + "    }\n"
129                 + "\n"
130                 + "  </script>\n"
131                 + "</head>\n"
132                 + "<body onload='test()'>\n"
133                 + LOG_TEXTAREA
134                 + "</body>\n"
135                 + "</html>";
136 
137         loadPageVerifyTextArea2(html);
138     }
139 
140     /**
141      * @throws Exception if an error occurs
142      */
143     @Test
144     @Alerts(DEFAULT = {"function () { [native code] }",
145                        "function () { [native code] }",
146                        "undefined",
147                        "done", "resolved value"},
148             FF = {"function () {\n    [native code]\n}",
149                   "function () {\n    [native code]\n}",
150                   "undefined",
151                   "done", "resolved value"},
152             FF_ESR = {"function () {\n    [native code]\n}",
153                       "function () {\n    [native code]\n}",
154                       "undefined",
155                       "done", "resolved value"})
156     public void constructorStrict() throws Exception {
157         final String html = DOCTYPE_HTML
158                 + "<html>\n"
159                 + "<head>\n"
160                 + "  <script>\n"
161                 + "    'use strict';"
162                 + LOG_TEXTAREA_FUNCTION
163                 + "    function test() {\n"
164                 + "      if (window.Promise) {\n"
165                 + "        var p = new Promise(function(resolve, reject) {\n"
166                 + "          log(resolve);\n"
167                 + "          log(reject);\n"
168                 + "          log(this);\n"
169                 + "          resolve('resolved value');\n"
170                 + "        });\n"
171                 + "        p.then(function(value) {log(value);});\n"
172                 + "        log('done');\n"
173                 + "      }\n"
174                 + "    }\n"
175                 + "\n"
176                 + "  </script>\n"
177                 + "</head>\n"
178                 + "<body onload='test()'>\n"
179                 + LOG_TEXTAREA
180                 + "</body>\n"
181                 + "</html>";
182 
183         loadPageVerifyTextArea2(html);
184     }
185 
186     /**
187      * @throws Exception if an error occurs
188      */
189     @Test
190     @Alerts({"true", "true", "true"})
191     public void constructorWithoutFunction() throws Exception {
192         final String html = DOCTYPE_HTML
193                 + "<html>\n"
194                 + "<head>\n"
195                 + "  <script>\n"
196                 + LOG_TEXTAREA_FUNCTION
197                 + "    function test() {\n"
198                 + "      if (window.Promise) {\n"
199                 + "        try{\n"
200                 + "          var p = new Promise();\n"
201                 + "          log('done');\n"
202                 + "        } catch(e) { log(e instanceof TypeError); }\n"
203 
204                 + "        try{\n"
205                 + "          var p = new Promise([1, 2, 4]);\n"
206                 + "          log('done');\n"
207                 + "        } catch(e) { log(e instanceof TypeError); }\n"
208 
209                 + "        try{\n"
210                 + "          var original = Promise.resolve(42);\n"
211                 + "          var p = new Promise(original);\n"
212                 + "          log('done');\n"
213                 + "        } catch(e) { log(e instanceof TypeError); }\n"
214                 + "      }\n"
215                 + "    }\n"
216                 + "\n"
217                 + "  </script>\n"
218                 + "</head>\n"
219                 + "<body onload='test()'>\n"
220                 + LOG_TEXTAREA
221                 + "</body>\n"
222                 + "</html>";
223 
224         loadPageVerifyTextArea2(html);
225     }
226 
227     /**
228      * @throws Exception if an error occurs
229      */
230     @Test
231     @Alerts({"done", "Rejected"})
232     public void reject() throws Exception {
233         final String html = DOCTYPE_HTML
234             + "<html>\n"
235             + "<head>\n"
236             + "  <script>\n"
237             + LOG_TEXTAREA_FUNCTION
238             + "    function test() {\n"
239             + "      if (window.Promise) {\n"
240             + "        Promise.reject('Rejected').then(function(value) {\n"
241             + "            log('failure');\n"
242             + "        }, function(value) {\n"
243             + "            log(value);\n"
244             + "        });\n"
245             + "        log('done');\n"
246             + "      }\n"
247             + "    }\n"
248             + "  </script>\n"
249             + "</head>\n"
250             + "<body onload='test()'>\n"
251             + LOG_TEXTAREA
252             + "</body>\n"
253             + "</html>";
254 
255         loadPageVerifyTextArea2(html);
256     }
257 
258     /**
259      * @throws Exception if an error occurs
260      */
261     @Test
262     @Alerts({"done", "false", "[object Promise]"})
263     public void rejectPromise() throws Exception {
264         final String html = DOCTYPE_HTML
265             + "<html>\n"
266             + "<head>\n"
267             + "  <script>\n"
268             + LOG_TEXTAREA_FUNCTION
269             + "    function test() {\n"
270             + "      if (window.Promise) {\n"
271             + "        var original = Promise.reject(42);\n"
272             + "        var cast = Promise.reject(original);\n"
273             + "        cast.then(function(v) {\n"
274             + "          log('failure');\n"
275             + "        }, function(value) {\n"
276             + "          log(value);\n"
277             + "        });\n"
278             + "        log('done');\n"
279             + "        log(original === cast);\n"
280             + "      }\n"
281             + "    }\n"
282             + "  </script>\n"
283             + "</head>\n"
284             + "<body onload='test()'>\n"
285             + LOG_TEXTAREA
286             + "</body>\n"
287             + "</html>";
288 
289         loadPageVerifyTextArea2(html);
290     }
291 
292     /**
293      * @throws Exception if an error occurs
294      */
295     @Test
296     @Alerts({"done", "Resolved"})
297     public void resolve() throws Exception {
298         final String html = DOCTYPE_HTML
299             + "<html>\n"
300             + "<head>\n"
301             + "  <script>\n"
302             + LOG_TEXTAREA_FUNCTION
303             + "    function test() {\n"
304             + "      if (window.Promise) {\n"
305             + "        Promise.resolve('Resolved').then(function(value) {\n"
306             + "            log(value);\n"
307             + "        }, function(value) {\n"
308             + "            log('failure');\n"
309             + "        });\n"
310             + "        log('done');\n"
311             + "      }\n"
312             + "    }\n"
313             + "  </script>\n"
314             + "</head>\n"
315             + "<body onload='test()'>\n"
316             + LOG_TEXTAREA
317             + "</body>\n"
318             + "</html>";
319 
320         loadPageVerifyTextArea2(html);
321     }
322 
323     /**
324      * @throws Exception if an error occurs
325      */
326     @Test
327     @Alerts({"done", "undefined"})
328     public void resolveEmpty() throws Exception {
329         final String html = DOCTYPE_HTML
330             + "<html>\n"
331             + "<head>\n"
332             + "  <script>\n"
333             + LOG_TEXTAREA_FUNCTION
334             + "    function test() {\n"
335             + "      if (window.Promise) {\n"
336             + "        Promise.resolve().then(function(value) {\n"
337             + "            log(value);\n"
338             + "        }, function(value) {\n"
339             + "            log('failure');\n"
340             + "        });\n"
341             + "        log('done');\n"
342             + "      }\n"
343             + "    }\n"
344             + "  </script>\n"
345             + "</head>\n"
346             + "<body onload='test()'>\n"
347             + LOG_TEXTAREA
348             + "</body>\n"
349             + "</html>";
350 
351         loadPageVerifyTextArea2(html);
352     }
353 
354     /**
355      * @throws Exception if an error occurs
356      */
357     @Test
358     @Alerts({"done", "1"})
359     public void resolveArray() throws Exception {
360         final String html = DOCTYPE_HTML
361             + "<html>\n"
362             + "<head>\n"
363             + "  <script>\n"
364             + LOG_TEXTAREA_FUNCTION
365             + "    function test() {\n"
366             + "      if (window.Promise) {\n"
367             + "        var p = Promise.resolve([1,2,3]);\n"
368             + "        p.then(function(v) {\n"
369             + "            log(v[0]);\n"
370             + "        });\n"
371             + "        log('done');\n"
372             + "      }\n"
373             + "    }\n"
374             + "  </script>\n"
375             + "</head>\n"
376             + "<body onload='test()'>\n"
377             + LOG_TEXTAREA
378             + "</body>\n"
379             + "</html>";
380 
381         loadPageVerifyTextArea2(html);
382     }
383 
384     /**
385      * @throws Exception if an error occurs
386      */
387     @Test
388     @Alerts({"done", "HtmlUnit"})
389     public void resolveString() throws Exception {
390         final String html = DOCTYPE_HTML
391             + "<html>\n"
392             + "<head>\n"
393             + "  <script>\n"
394             + LOG_TEXTAREA_FUNCTION
395             + "    function test() {\n"
396             + "      if (window.Promise) {\n"
397             + "        var p = Promise.resolve('HtmlUnit');\n"
398             + "        p.then(function(v) {\n"
399             + "            log(v);\n"
400             + "        });\n"
401             + "        log('done');\n"
402             + "      }\n"
403             + "    }\n"
404             + "  </script>\n"
405             + "</head>\n"
406             + "<body onload='test()'>\n"
407             + LOG_TEXTAREA
408             + "</body>\n"
409             + "</html>";
410 
411         loadPageVerifyTextArea2(html);
412     }
413 
414     /**
415      * @throws Exception if an error occurs
416      */
417     @Test
418     @Alerts({"done", "true", "42"})
419     public void resolvePromise() throws Exception {
420         final String html = DOCTYPE_HTML
421             + "<html>\n"
422             + "<head>\n"
423             + "  <script>\n"
424             + LOG_TEXTAREA_FUNCTION
425             + "    function test() {\n"
426             + "      if (window.Promise) {\n"
427             + "        var original = Promise.resolve(42);\n"
428             + "        var cast = Promise.resolve(original);\n"
429             + "        cast.then(function(v) {\n"
430             + "          log(v);\n"
431             + "        });\n"
432             + "        log('done');\n"
433             + "        log(original === cast);\n"
434             + "      }\n"
435             + "    }\n"
436             + "  </script>\n"
437             + "</head>\n"
438             + "<body onload='test()'>\n"
439             + LOG_TEXTAREA
440             + "</body>\n"
441             + "</html>";
442 
443         loadPageVerifyTextArea2(html);
444     }
445 
446     /**
447      * @throws Exception if an error occurs
448      */
449     @Test
450     @Alerts({"true", "fulfilled!"})
451     public void resolveThenable() throws Exception {
452         final String html = DOCTYPE_HTML
453             + "<html>\n"
454             + "<head>\n"
455             + "  <script>\n"
456             + LOG_TEXTAREA_FUNCTION
457             + "    function test() {\n"
458             + "      if (window.Promise) {\n"
459 
460             + "        var p1 = Promise.resolve({\n"
461             + "          then: function(onFulfill, onReject) {\n"
462             + "            onFulfill('fulfilled!');\n"
463             + "          }\n"
464             + "        });\n"
465             + "        log(p1 instanceof Promise);\n"
466             + "\n"
467             + "        p1.then(function(v) {\n"
468             + "            log(v);\n"
469             + "        }, function(e) {\n"
470             + "            log('failure');\n"
471             + "        });\n"
472 
473             + "      }\n"
474             + "    }\n"
475             + "  </script>\n"
476             + "</head>\n"
477             + "<body onload='test()'>\n"
478             + LOG_TEXTAREA
479             + "</body>\n"
480             + "</html>";
481 
482         loadPageVerifyTextArea2(html);
483     }
484 
485     /**
486      * @throws Exception if an error occurs
487      */
488     @Test
489     @Alerts({"true", "aaa"})
490     public void resolveThenablePrototype() throws Exception {
491         final String html = DOCTYPE_HTML
492             + "<html>\n"
493             + "<head>\n"
494             + "  <script>\n"
495             + LOG_TEXTAREA_FUNCTION
496             + "    function test() {\n"
497             + "      if (window.Promise) {\n"
498             + "        function MyThenable() {\n"
499             + "          this.value = 'aaa';\n"
500             + "        };"
501             + "        MyThenable.prototype = { then: function(onFulfill, onReject) { onFulfill(this.value); }};\n"
502             + "        var thenable = new MyThenable();\n"
503             + "        var p1 = Promise.resolve(1);\n"
504             + "        log(p1 instanceof Promise);\n"
505             + "\n"
506             + "        p1=p1.then(function(v) {\n"
507             + "            return thenable;\n"
508             + "        }, function(e) {\n"
509             + "            log('failure');\n"
510             + "        });\n"
511             + "\n"
512             + "        p1=p1.then(function(v) {\n"
513             + "            log(v);\n"
514             + "        }, function(e) {\n"
515             + "            log('failure');\n"
516             + "        });\n"
517 
518             + "      }\n"
519             + "    }\n"
520             + "  </script>\n"
521             + "</head>\n"
522             + "<body onload='test()'>\n"
523             + LOG_TEXTAREA
524             + "</body>\n"
525             + "</html>";
526 
527         loadPageVerifyTextArea2(html);
528     }
529 
530     /**
531      * @throws Exception if an error occurs
532      */
533     @Test
534     @Alerts("TypeError: Throwing 1")
535     public void resolveThenableThrows() throws Exception {
536         final String html = DOCTYPE_HTML
537             + "<html>\n"
538             + "<head>\n"
539             + "  <script>\n"
540             + LOG_TEXTAREA_FUNCTION
541             + "    function test() {\n"
542             + "      if (window.Promise) {\n"
543 
544             + "        var thenable = {\n"
545             + "          then: function(resolve) {\n"
546             + "            throw new TypeError('Throwing 1');\n"
547             + "            resolve(\"Resolving\");\n"
548             + "          }\n"
549             + "        };\n"
550             + "\n"
551             + "        var p2 = Promise.resolve(thenable);\n"
552             + "        p2.then(function(v) {\n"
553             + "          log('failure');\n"
554             + "        }, function(e) {\n"
555             + "          log(e);\n"
556             + "        });\n"
557 
558             + "      }\n"
559             + "    }\n"
560             + "  </script>\n"
561             + "</head>\n"
562             + "<body onload='test()'>\n"
563             + LOG_TEXTAREA
564             + "</body>\n"
565             + "</html>";
566 
567         loadPageVerifyTextArea2(html);
568     }
569 
570     /**
571      * @throws Exception if an error occurs
572      */
573     @Test
574     @Alerts("Resolving")
575     public void resolveThenableThrowsAfterCallback() throws Exception {
576         final String html = DOCTYPE_HTML
577             + "<html>\n"
578             + "<head>\n"
579             + "  <script>\n"
580             + LOG_TEXTAREA_FUNCTION
581             + "    function test() {\n"
582             + "      if (window.Promise) {\n"
583 
584             + "        var thenable = {\n"
585             + "          then: function(resolve) {\n"
586             + "            resolve('Resolving');\n"
587             + "            throw new TypeError('Throwing 2');\n"
588             + "          }\n"
589             + "        };\n"
590             + "\n"
591             + "        var p3 = Promise.resolve(thenable);\n"
592             + "        p3.then(function(v) {\n"
593             + "          log(v);\n"
594             + "        }, function(e) {\n"
595             + "          log('failure');\n"
596             + "        });\n"
597             + "      }\n"
598             + "    }\n"
599             + "  </script>\n"
600             + "</head>\n"
601             + "<body onload='test()'>\n"
602             + LOG_TEXTAREA
603             + "</body>\n"
604             + "</html>";
605 
606         loadPageVerifyTextArea2(html);
607     }
608 
609     /**
610      * @throws Exception if an error occurs
611      */
612     @Test
613     @Alerts({"true", "[object Object]"})
614     public void resolveThenablesWithoutThen() throws Exception {
615         final String html = DOCTYPE_HTML
616             + "<html>\n"
617             + "<head>\n"
618             + "  <script>\n"
619             + LOG_TEXTAREA_FUNCTION
620             + "    function test() {\n"
621             + "      if (window.Promise) {\n"
622             + "        var p1 = Promise.resolve({ id: 17 });\n"
623             + "        log(p1 instanceof Promise);\n"
624             + "\n"
625             + "        p1.then(function(v) {\n"
626             + "            log(v);\n"
627             + "        }, function(e) {\n"
628             + "            log('failure');\n"
629             + "        });\n"
630             + "      }\n"
631             + "    }\n"
632             + "  </script>\n"
633             + "</head>\n"
634             + "<body onload='test()'>\n"
635             + LOG_TEXTAREA
636             + "</body>\n"
637             + "</html>";
638 
639         loadPageVerifyTextArea2(html);
640     }
641 
642     /**
643      * @throws Exception if an error occurs
644      */
645     @Test
646     @Alerts({"done", "1", "2"})
647     public void thenChanining() throws Exception {
648         final String html = DOCTYPE_HTML
649             + "<html>\n"
650             + "<head>\n"
651             + "  <script>\n"
652             + LOG_TEXTAREA_FUNCTION
653             + "    function test() {\n"
654             + "      if (window.Promise) {\n"
655             + "        var p = new Promise(function(resolve, reject) {\n"
656             + "          resolve(1);\n"
657             + "        });\n"
658             + "\n"
659             + "        p.then(function(value) {\n"
660             + "          log(value);\n"
661             + "          return value + 1;\n"
662             + "        }).then(function(value) {\n"
663             + "          log(value);\n"
664             + "        });\n"
665             + "        log('done');\n"
666             + "      }\n"
667             + "    }\n"
668             + "  </script>\n"
669             + "</head>\n"
670             + "<body onload='test()'>\n"
671             + LOG_TEXTAREA
672             + "</body>\n"
673             + "</html>";
674 
675         loadPageVerifyTextArea2(html);
676     }
677 
678     /**
679      * @throws Exception if an error occurs
680      */
681     @Test
682     @Alerts({"done", "undefined"})
683     public void then() throws Exception {
684         final String html = DOCTYPE_HTML
685                 + "<html>\n"
686                 + "<head>\n"
687                 + "  <script>\n"
688                 + LOG_TEXTAREA_FUNCTION
689                 + "    function test() {\n"
690                 + "      if (window.Promise) {\n"
691                 + "        var p = Promise.resolve(void 0);\n"
692                 + "        p.then(function(value) {\n"
693                 + "          log(value);\n"
694                 + "        })\n"
695                 + "        log('done');\n"
696                 + "      }\n"
697                 + "    }\n"
698                 + "  </script>\n"
699                 + "</head>\n"
700                 + "<body onload='test()'>\n"
701                 + LOG_TEXTAREA
702                 + "</body>\n"
703                 + "</html>";
704 
705         loadPageVerifyTextArea2(html);
706     }
707 
708     /**
709      * @throws Exception if an error occurs
710      */
711     @Test
712     @Alerts({"done", "undefined"})
713     public void thenAsync() throws Exception {
714         final String html = DOCTYPE_HTML
715                 + "<html>\n"
716                 + "<head>\n"
717                 + "  <script>\n"
718                 + LOG_TEXTAREA_FUNCTION
719                 + "    function test() {\n"
720                 + "      if (window.Promise) {\n"
721                 + "        var p = new Promise(function(resolve, reject) {\n"
722                 + "           window.setTimeout( function() {\n"
723                 + "             resolve(void 0);\n"
724                 + "           }, 20);\n"
725                 + "        })\n"
726                 + "        p.then(function(value) {\n"
727                 + "          log(value);\n"
728                 + "        })\n"
729                 + "        log('done');\n"
730                 + "      }\n"
731                 + "    }\n"
732                 + "  </script>\n"
733                 + "</head>\n"
734                 + "<body onload='test()'>\n"
735                 + LOG_TEXTAREA
736                 + "</body>\n"
737                 + "</html>";
738 
739         loadPageVerifyTextArea2(html);
740     }
741 
742     /**
743      * @throws Exception if an error occurs
744      */
745     @Test
746     @Alerts({"done", "1 yes", "2 yes"})
747     public void thenTwice() throws Exception {
748         final String html = DOCTYPE_HTML
749                 + "<html>\n"
750                 + "<head>\n"
751                 + "  <script>\n"
752                 + LOG_TEXTAREA_FUNCTION
753                 + "    function test() {\n"
754                 + "      if (window.Promise) {\n"
755                 + "        var p = Promise.resolve('yes');\n"
756                 + "        p.then(function(value) {\n"
757                 + "          log('1 ' + value);\n"
758                 + "        })\n"
759                 + "        p.then(function(value) {\n"
760                 + "          log('2 ' + value);\n"
761                 + "        })\n"
762                 + "        log('done');\n"
763                 + "      }\n"
764                 + "    }\n"
765                 + "  </script>\n"
766                 + "</head>\n"
767                 + "<body onload='test()'>\n"
768                 + LOG_TEXTAREA
769                 + "</body>\n"
770                 + "</html>";
771 
772         loadPageVerifyTextArea2(html);
773     }
774 
775     /**
776      * @throws Exception if an error occurs
777      */
778     @Test
779     @Alerts({"done", "1 yes", "2 yes"})
780     public void thenTwiceAsync() throws Exception {
781         final String html = DOCTYPE_HTML
782                 + "<html>\n"
783                 + "<head>\n"
784                 + "  <script>\n"
785                 + LOG_TEXTAREA_FUNCTION
786                 + "    function test() {\n"
787                 + "      if (window.Promise) {\n"
788                 + "        var p = new Promise(function(resolve, reject) {\n"
789                 + "           window.setTimeout( function() {\n"
790                 + "             resolve('yes');\n"
791                 + "           }, 20);\n"
792                 + "        })\n"
793                 + "        p.then(function(value) {\n"
794                 + "          log('1 ' + value);\n"
795                 + "        })\n"
796                 + "        p.then(function(value) {\n"
797                 + "          log('2 ' + value);\n"
798                 + "        })\n"
799                 + "        log('done');\n"
800                 + "      }\n"
801                 + "    }\n"
802                 + "  </script>\n"
803                 + "</head>\n"
804                 + "<body onload='test()'>\n"
805                 + LOG_TEXTAREA
806                 + "</body>\n"
807                 + "</html>";
808 
809         loadPageVerifyTextArea2(html);
810     }
811 
812     /**
813      * @throws Exception if an error occurs
814      */
815     @Test
816     @Alerts({"done", "first", "second"})
817     public void thenAsyncPromiseResolved() throws Exception {
818         final String html = DOCTYPE_HTML
819                 + "<html>\n"
820                 + "<head>\n"
821                 + "  <script>\n"
822                 + LOG_TEXTAREA_FUNCTION
823                 + "    function test() {\n"
824                 + "      if (window.Promise) {\n"
825                 + "        var p = new Promise(function(resolve, reject) {\n"
826                 + "           window.setTimeout( function() {\n"
827                 + "             resolve('first');\n"
828                 + "           }, 20);\n"
829                 + "        })\n"
830                 + "        var p2 = p.then(function(value) {\n"
831                 + "          log(value);\n"
832                 + "          return Promise.resolve('second');"
833                 + "        })\n"
834                 + "        p2.then(function(value) {\n"
835                 + "          log(value);\n"
836                 + "        })\n"
837                 + "        log('done');\n"
838                 + "      }\n"
839                 + "    }\n"
840                 + "  </script>\n"
841                 + "</head>\n"
842                 + "<body onload='test()'>\n"
843                 + LOG_TEXTAREA
844                 + "</body>\n"
845                 + "</html>";
846 
847         loadPageVerifyTextArea2(html);
848     }
849 
850     /**
851      * @throws Exception if an error occurs
852      */
853     @Test
854     @Alerts({"done", "first", "second"})
855     public void thenAsyncPromiseRejected() throws Exception {
856         final String html = DOCTYPE_HTML
857                 + "<html>\n"
858                 + "<head>\n"
859                 + "  <script>\n"
860                 + LOG_TEXTAREA_FUNCTION
861                 + "    function test() {\n"
862                 + "      if (window.Promise) {\n"
863                 + "        var p = new Promise(function(resolve, reject) {\n"
864                 + "           window.setTimeout( function() {\n"
865                 + "             resolve('first');\n"
866                 + "           }, 20);\n"
867                 + "        })\n"
868                 + "        var p2 = p.then(function(value) {\n"
869                 + "          log(value);\n"
870                 + "          return Promise.reject('second');"
871                 + "        })\n"
872                 + "        p2.then(function(value) {\n"
873                 + "          log('Failure');\n"
874                 + "        },"
875                 + "        function(value) {\n"
876                 + "          log(value);\n"
877                 + "        })\n"
878                 + "        log('done');\n"
879                 + "      }\n"
880                 + "    }\n"
881                 + "  </script>\n"
882                 + "</head>\n"
883                 + "<body onload='test()'>\n"
884                 + LOG_TEXTAREA
885                 + "</body>\n"
886                 + "</html>";
887 
888         loadPageVerifyTextArea2(html);
889     }
890 
891     /**
892      * @throws Exception if an error occurs
893      */
894     @Test
895     @Alerts({"done", "first", "second"})
896     public void thenAsyncPromiseAsyncResolved() throws Exception {
897         final String html = DOCTYPE_HTML
898                 + "<html>\n"
899                 + "<head>\n"
900                 + "  <script>\n"
901                 + LOG_TEXTAREA_FUNCTION
902                 + "    function test() {\n"
903                 + "      if (window.Promise) {\n"
904                 + "        var p = new Promise(function(resolve, reject) {\n"
905                 + "           window.setTimeout( function() {\n"
906                 + "             resolve('first');\n"
907                 + "           }, 20);\n"
908                 + "        })\n"
909                 + "        var p2 = p.then(function(value) {\n"
910                 + "          log(value);\n"
911                 + "          return new Promise(function(resolve, reject) {\n"
912                 + "             window.setTimeout( function() {\n"
913                 + "               resolve('second');\n"
914                 + "             }, 20);\n"
915                 + "          })\n"
916                 + "        })\n"
917                 + "        p2.then(function(value) {\n"
918                 + "          log(value);\n"
919                 + "        })\n"
920                 + "        log('done');\n"
921                 + "      }\n"
922                 + "    }\n"
923                 + "  </script>\n"
924                 + "</head>\n"
925                 + "<body onload='test()'>\n"
926                 + LOG_TEXTAREA
927                 + "</body>\n"
928                 + "</html>";
929 
930         loadPageVerifyTextArea2(html);
931     }
932 
933     /**
934      * @throws Exception if an error occurs
935      */
936     @Test
937     @Alerts({"done", "first", "second"})
938     public void thenAsyncPromiseAsyncRejected() throws Exception {
939         final String html = DOCTYPE_HTML
940                 + "<html>\n"
941                 + "<head>\n"
942                 + "  <script>\n"
943                 + LOG_TEXTAREA_FUNCTION
944                 + "    function test() {\n"
945                 + "      if (window.Promise) {\n"
946                 + "        var p = new Promise(function(resolve, reject) {\n"
947                 + "           window.setTimeout( function() {\n"
948                 + "             resolve('first');\n"
949                 + "           }, 20);\n"
950                 + "        })\n"
951                 + "        var p2 = p.then(function(value) {\n"
952                 + "          log(value);\n"
953                 + "          return new Promise(function(resolve, reject) {\n"
954                 + "             window.setTimeout( function() {\n"
955                 + "               reject('second');\n"
956                 + "             }, 20);\n"
957                 + "          })\n"
958                 + "        })\n"
959                 + "        p2.then(function(value) {\n"
960                 + "          log('Failure');\n"
961                 + "        },"
962                 + "        function(value) {\n"
963                 + "          log(value);\n"
964                 + "        })\n"
965                 + "        log('done');\n"
966                 + "      }\n"
967                 + "    }\n"
968                 + "  </script>\n"
969                 + "</head>\n"
970                 + "<body onload='test()'>\n"
971                 + LOG_TEXTAREA
972                 + "</body>\n"
973                 + "</html>";
974 
975         loadPageVerifyTextArea2(html);
976     }
977 
978     /**
979      * @throws Exception if an error occurs
980      */
981     @Test
982     @Alerts({"done", "Success first"})
983     public void thenTestAsyncChainedResolve() throws Exception {
984         final String html = DOCTYPE_HTML
985                 + "<html>\n"
986                 + "<head>\n"
987                 + "  <script>\n"
988                 + LOG_TEXTAREA_FUNCTION
989                 + "    function test() {\n"
990                 + "      if (window.Promise) {\n"
991                 + "        var p = new Promise(function(resolve, reject) {\n"
992                 + "           window.setTimeout( function() {\n"
993                 + "             resolve('first');\n"
994                 + "           }, 20);\n"
995                 + "        })\n"
996                 + "        var p2 = p.then(undefined, function(value) {\n"
997                 + "          log(value);\n"
998                 + "        })\n"
999                 + "        p2.then(function(value) {\n"
1000                 + "          log('Success ' + value);\n"
1001                 + "        },"
1002                 + "        function(value) {\n"
1003                 + "          log('Failure ' + value);\n"
1004                 + "        })\n"
1005                 + "        log('done');\n"
1006                 + "      }\n"
1007                 + "    }\n"
1008                 + "  </script>\n"
1009                 + "</head>\n"
1010                 + "<body onload='test()'>\n"
1011                 + LOG_TEXTAREA
1012                 + "</body>\n"
1013                 + "</html>";
1014 
1015         loadPageVerifyTextArea2(html);
1016     }
1017 
1018     /**
1019      * @throws Exception if an error occurs
1020      */
1021     @Test
1022     @Alerts({"done", "Failure first"})
1023     public void thenTestAsyncChainedReject() throws Exception {
1024         final String html = DOCTYPE_HTML
1025                 + "<html>\n"
1026                 + "<head>\n"
1027                 + "  <script>\n"
1028                 + LOG_TEXTAREA_FUNCTION
1029                 + "    function test() {\n"
1030                 + "      if (window.Promise) {\n"
1031                 + "        var p = new Promise(function(resolve, reject) {\n"
1032                 + "           window.setTimeout( function() {\n"
1033                 + "             reject('first');\n"
1034                 + "           }, 20);\n"
1035                 + "        })\n"
1036                 + "        var p2 = p.then(function(value) {\n"
1037                 + "          log(value);\n"
1038                 + "        }, undefined)\n"
1039                 + "        p2.then(function(value) {\n"
1040                 + "          log('Success ' + value);\n"
1041                 + "        },"
1042                 + "        function(value) {\n"
1043                 + "          log('Failure ' + value);\n"
1044                 + "        })\n"
1045                 + "        log('done');\n"
1046                 + "      }\n"
1047                 + "    }\n"
1048                 + "  </script>\n"
1049                 + "</head>\n"
1050                 + "<body onload='test()'>\n"
1051                 + LOG_TEXTAREA
1052                 + "</body>\n"
1053                 + "</html>";
1054 
1055         loadPageVerifyTextArea2(html);
1056     }
1057 
1058     /**
1059      * @throws Exception if an error occurs
1060      */
1061     @Test
1062     @Alerts({"done", "Success first"})
1063     public void thenTestAsyncChainedNotAFunction() throws Exception {
1064         final String html = DOCTYPE_HTML
1065                 + "<html>\n"
1066                 + "<head>\n"
1067                 + "  <script>\n"
1068                 + LOG_TEXTAREA_FUNCTION
1069                 + "    function test() {\n"
1070                 + "      if (window.Promise) {\n"
1071                 + "        var p = new Promise(function(resolve, reject) {\n"
1072                 + "           window.setTimeout( function() {\n"
1073                 + "             resolve('first');\n"
1074                 + "           }, 20);\n"
1075                 + "        })\n"
1076                 + "        var p2 = p.then(7);\n"
1077                 + "        var p3 = p2.then('test');\n"
1078                 + "        p3.then(function(value) {\n"
1079                 + "          log('Success ' + value);\n"
1080                 + "        },"
1081                 + "        function(value) {\n"
1082                 + "          log('Failure ' + value);\n"
1083                 + "        })\n"
1084                 + "        log('done');\n"
1085                 + "      }\n"
1086                 + "    }\n"
1087                 + "  </script>\n"
1088                 + "</head>\n"
1089                 + "<body onload='test()'>\n"
1090                 + LOG_TEXTAREA
1091                 + "</body>\n"
1092                 + "</html>";
1093 
1094         loadPageVerifyTextArea2(html);
1095     }
1096 
1097     /**
1098      * @throws Exception if an error occurs
1099      */
1100     @Test
1101     @Alerts({"Success", "string", "oh, no!", "after catch"})
1102     public void catchTest() throws Exception {
1103         final String html = DOCTYPE_HTML
1104                 + "<html>\n"
1105                 + "<head>\n"
1106                 + "  <script>\n"
1107                 + LOG_TEXTAREA_FUNCTION
1108                 + "    function test() {\n"
1109                 + "      if (window.Promise) {\n"
1110                 + "        var p = new Promise(function(resolve, reject) {\n"
1111                 + "          resolve('Success');\n"
1112                 + "        });\n"
1113                 + "\n"
1114                 + "        p.then(function(value) {\n"
1115                 + "          log(value);\n"
1116                 + "          throw 'oh, no!';\n"
1117                 + "        }).catch(function(e) {\n"
1118                 + "          log(typeof e);\n"
1119                 + "          log(e);\n"
1120                 + "        }).then(function(e) {\n"
1121                 + "          log('after catch');\n"
1122                 + "        }, function() {\n"
1123                 + "          log('failure');\n"
1124                 + "        });\n"
1125                 + "      }\n"
1126                 + "    }\n"
1127                 + "  </script>\n"
1128                 + "</head>\n"
1129                 + "<body onload='test()'>\n"
1130                 + LOG_TEXTAREA
1131                 + "</body>\n"
1132                 + "</html>";
1133 
1134         loadPageVerifyTextArea2(html);
1135     }
1136 
1137     /**
1138      * @throws Exception if an error occurs
1139      */
1140     @Test
1141     @Alerts({"Success", "string", "oh, no!", "after catch"})
1142     public void catchTestAsync() throws Exception {
1143         final String html = DOCTYPE_HTML
1144                 + "<html>\n"
1145                 + "<head>\n"
1146                 + "  <script>\n"
1147                 + LOG_TEXTAREA_FUNCTION
1148                 + "    function test() {\n"
1149                 + "      if (window.Promise) {\n"
1150                 + "        var p = new Promise(function(resolve, reject) {\n"
1151                 + "           window.setTimeout( function() {\n"
1152                 + "             resolve('Success');\n"
1153                 + "           }, 20);\n"
1154                 + "        })\n"
1155                 + "        p.then(function(value) {\n"
1156                 + "          log(value);\n"
1157                 + "          throw 'oh, no!';\n"
1158                 + "        }).catch(function(e) {\n"
1159                 + "          log(typeof e);\n"
1160                 + "          log(e);\n"
1161                 + "        }).then(function(e) {\n"
1162                 + "          log('after catch');\n"
1163                 + "        }, function() {\n"
1164                 + "          log('failure');\n"
1165                 + "        });\n"
1166                 + "      }\n"
1167                 + "    }\n"
1168                 + "  </script>\n"
1169                 + "</head>\n"
1170                 + "<body onload='test()'>\n"
1171                 + LOG_TEXTAREA
1172                 + "</body>\n"
1173                 + "</html>";
1174 
1175         loadPageVerifyTextArea2(html);
1176     }
1177 
1178     /**
1179      * @throws Exception if an error occurs
1180      */
1181     @Test
1182     @Alerts({"done", "Success first"})
1183     public void catchTestAsyncChained() throws Exception {
1184         final String html = DOCTYPE_HTML
1185                 + "<html>\n"
1186                 + "<head>\n"
1187                 + "  <script>\n"
1188                 + LOG_TEXTAREA_FUNCTION
1189                 + "    function test() {\n"
1190                 + "      if (window.Promise) {\n"
1191                 + "        var p = new Promise(function(resolve, reject) {\n"
1192                 + "           window.setTimeout( function() {\n"
1193                 + "             resolve('first');\n"
1194                 + "           }, 20);\n"
1195                 + "        })\n"
1196                 + "        var p2 = p.catch(function(value) {\n"
1197                 + "          log(value);\n"
1198                 + "        })\n"
1199                 + "        p2.then(function(value) {\n"
1200                 + "          log('Success ' + value);\n"
1201                 + "        },"
1202                 + "        function(value) {\n"
1203                 + "          log('Failure ' + value);\n"
1204                 + "        })\n"
1205                 + "        log('done');\n"
1206                 + "      }\n"
1207                 + "    }\n"
1208                 + "  </script>\n"
1209                 + "</head>\n"
1210                 + "<body onload='test()'>\n"
1211                 + LOG_TEXTAREA
1212                 + "</body>\n"
1213                 + "</html>";
1214 
1215         loadPageVerifyTextArea2(html);
1216     }
1217 
1218     /**
1219      * @throws Exception if an error occurs
1220      */
1221     @Test
1222     @Alerts({"done", "Success"})
1223     public void thenInsideEventHandler() throws Exception {
1224         final String html = DOCTYPE_HTML
1225                 + "<html>\n"
1226                 + "<head>\n"
1227                 + "  <script>\n"
1228                 + LOG_TEXTAREA_FUNCTION
1229                 + "    function test() {\n"
1230                 + "      if (window.Promise) {\n"
1231                 + "        document.getElementById('btn1').onclick = function() {\n"
1232                 + "          new Promise(function(resolve, reject) {\n"
1233                 + "            window.setTimeout( function() {\n"
1234                 + "              resolve('Success');\n"
1235                 + "            }, 20);\n"
1236                 + "          }).then(function(value) {\n"
1237                 + "            log(value);\n"
1238                 + "          });\n"
1239                 + "          log('done');\n"
1240                 + "        };\n"
1241                 + "      }\n"
1242                 + "    }\n"
1243                 + "  </script>\n"
1244                 + "</head>\n"
1245                 + "<body onload='test()'>\n"
1246                 + "  <button id='btn1'>BTN1</button>\n"
1247                 + LOG_TEXTAREA
1248                 + "</body>\n"
1249                 + "</html>\n";
1250 
1251         final WebDriver driver = loadPage2(html);
1252         driver.findElement(By.id("btn1")).click();
1253 
1254         verifyTextArea2(driver, getExpectedAlerts());
1255     }
1256 
1257     /**
1258      * @throws Exception if an error occurs
1259      */
1260     @Test
1261     @Alerts({"create thenable 4", "fulfilled"})
1262     public void thenThenable() throws Exception {
1263         final String html = DOCTYPE_HTML
1264             + "<html>\n"
1265             + "<head>\n"
1266             + "  <script>\n"
1267             + LOG_TEXTAREA_FUNCTION
1268             + "    function test() {\n"
1269             + "      if (window.Promise) {\n"
1270 
1271             + "        var p1 = Promise.resolve(4);\n"
1272             + "        p2 = p1.then(function(v) {\n"
1273             + "          log('create thenable ' + v);\n"
1274             + "          return { then: function(onFulfill, onReject) { onFulfill('fulfilled'); }};\n"
1275             + "        });\n"
1276             + "\n"
1277             + "        p2.then(function(v) {\n"
1278             + "            log(v);\n"
1279             + "        }, function(e) {\n"
1280             + "            log('failure');\n"
1281             + "        });\n"
1282 
1283             + "      }\n"
1284             + "    }\n"
1285             + "  </script>\n"
1286             + "</head>\n"
1287             + "<body onload='test()'>\n"
1288             + LOG_TEXTAREA
1289             + "</body>\n"
1290             + "</html>";
1291 
1292         loadPageVerifyTextArea2(html);
1293     }
1294 
1295     /**
1296      * @throws Exception if an error occurs
1297      */
1298     @Test
1299     @Alerts("failure1")
1300     public void thenThenableThrows() throws Exception {
1301         final String html = DOCTYPE_HTML
1302             + "<html>\n"
1303             + "<head>\n"
1304             + "  <script>\n"
1305             + LOG_TEXTAREA_FUNCTION
1306             + "    function test() {\n"
1307             + "      if (window.Promise) {\n"
1308 
1309             + "        var thenable = {\n"
1310             + "          then: function(resolve) {\n"
1311             + "            throw new TypeError('Throwing 1');\n"
1312             + "            resolve(\"Resolving\");\n"
1313             + "          }\n"
1314             + "        };\n"
1315             + "\n"
1316             + "        var p1 = Promise.resolve(1);\n"
1317             + "        p2 = p1.then(thenable);\n"
1318 
1319             + "        p2.then(function(v) {\n"
1320             + "          log('failure' + v);\n"
1321             + "        }, function(e) {\n"
1322             + "          log(e);\n"
1323             + "        });\n"
1324 
1325             + "      }\n"
1326             + "    }\n"
1327             + "  </script>\n"
1328             + "</head>\n"
1329             + "<body onload='test()'>\n"
1330             + LOG_TEXTAREA
1331             + "</body>\n"
1332             + "</html>";
1333 
1334         loadPageVerifyTextArea2(html);
1335     }
1336 
1337     /**
1338      * @throws Exception if an error occurs
1339      */
1340     @Test
1341     @Alerts({"done", "failure1"})
1342     public void thenNotThenable() throws Exception {
1343         final String html = DOCTYPE_HTML
1344             + "<html>\n"
1345             + "<head>\n"
1346             + "  <script>\n"
1347             + LOG_TEXTAREA_FUNCTION
1348             + "    function test() {\n"
1349             + "      if (window.Promise) {\n"
1350 
1351             + "        var elseable = {\n"
1352             + "          else: function(resolve) {\n"
1353             + "            resolve(\"Resolving\");\n"
1354             + "          }\n"
1355             + "        };\n"
1356             + "\n"
1357             + "        var p1 = Promise.resolve(1);\n"
1358             + "        try{\n"
1359             + "          p2 = p1.then(elseable);\n"
1360             + "          log('done');\n"
1361             + "        } catch(e) { log(e instanceof TypeError); }\n"
1362 
1363             + "        p2.then(function(v) {\n"
1364             + "          log('failure' + v);\n"
1365             + "        }, function(e) {\n"
1366             + "          log(e);\n"
1367             + "        });\n"
1368 
1369             + "      }\n"
1370             + "    }\n"
1371             + "  </script>\n"
1372             + "</head>\n"
1373             + "<body onload='test()'>\n"
1374             + LOG_TEXTAREA
1375             + "</body>\n"
1376             + "</html>";
1377 
1378         loadPageVerifyTextArea2(html);
1379     }
1380 
1381     /**
1382      * @throws Exception if an error occurs
1383      */
1384     @Test
1385     @Alerts("1")
1386     public void thenThenableThrowsAfterCallback() throws Exception {
1387         final String html = DOCTYPE_HTML
1388             + "<html>\n"
1389             + "<head>\n"
1390             + "  <script>\n"
1391             + LOG_TEXTAREA_FUNCTION
1392             + "    function test() {\n"
1393             + "      if (window.Promise) {\n"
1394 
1395             + "        var thenable = {\n"
1396             + "          then: function(resolve) {\n"
1397             + "            resolve('Resolving');\n"
1398             + "            throw new TypeError('Throwing 2');\n"
1399             + "          }\n"
1400             + "        };\n"
1401             + "\n"
1402             + "        var p1 = Promise.resolve(1);\n"
1403             + "        p2 = p1.then(thenable);\n"
1404 
1405             + "        p2.then(function(v) {\n"
1406             + "          log(v);\n"
1407             + "        }, function(e) {\n"
1408             + "          log('failure');\n"
1409             + "        });\n"
1410             + "      }\n"
1411             + "    }\n"
1412             + "  </script>\n"
1413             + "</head>\n"
1414             + "<body onload='test()'>\n"
1415             + LOG_TEXTAREA
1416             + "</body>\n"
1417             + "</html>";
1418 
1419         loadPageVerifyTextArea2(html);
1420     }
1421 
1422     /**
1423      * @throws Exception if an error occurs
1424      */
1425     @Test
1426     @Alerts({"done", "object", "3", "3,1337,Success"})
1427     public void allAsyncArray() throws Exception {
1428         final String html = DOCTYPE_HTML
1429             + "<html>\n"
1430             + "<head>\n"
1431             + "  <script>\n"
1432             + LOG_TEXTAREA_FUNCTION
1433             + "    function test() {\n"
1434             + "      if (window.Promise) {\n"
1435             + "        var p1 = Promise.resolve(3);\n"
1436             + "        var p2 = 1337;\n"
1437             + "        var p3 = new Promise(function(resolve, reject) {\n"
1438             + "            window.setTimeout( function() {\n"
1439             + "              resolve('Success');\n"
1440             + "            }, 20);\n"
1441             + "        });\n"
1442             + "\n"
1443             + "        Promise.all([p1, p2, p3]).then(function(values) {\n"
1444             + "          log(typeof values);\n"
1445             + "          log(values.length);\n"
1446             + "          log(values);\n"
1447             + "        });\n"
1448             + "        log('done');\n"
1449             + "      }\n"
1450             + "    }\n"
1451             + "</script></head>\n"
1452             + "<body onload='test()'>\n"
1453             + LOG_TEXTAREA
1454             + "</body>\n"
1455             + "</html>\n";
1456 
1457         loadPageVerifyTextArea2(html);
1458     }
1459 
1460     /**
1461      * @throws Exception if an error occurs
1462      */
1463     @Test
1464     @Alerts({"done", "first 3,1337,Success", "second 3,Success"})
1465     public void allAsyncArray2() throws Exception {
1466         final String html = DOCTYPE_HTML
1467             + "<html>\n"
1468             + "<head>\n"
1469             + "  <script>\n"
1470             + LOG_TEXTAREA_FUNCTION
1471             + "    function test() {\n"
1472             + "      if (window.Promise) {\n"
1473             + "        var p1 = Promise.resolve(3);\n"
1474             + "        var p2 = 1337;\n"
1475             + "        var p3 = new Promise(function(resolve, reject) {\n"
1476             + "            window.setTimeout( function() {\n"
1477             + "              resolve('Success');\n"
1478             + "            }, 20);\n"
1479             + "        });\n"
1480             + "\n"
1481             + "        Promise.all([p1, p2, p3]).then(function(values) {\n"
1482             + "          log('first ' + values);\n"
1483             + "        });\n"
1484             + "        Promise.all([p1, p3]).then(function(values) {\n"
1485             + "          log('second ' + values);\n"
1486             + "        });\n"
1487             + "        log('done');\n"
1488             + "      }\n"
1489             + "    }\n"
1490             + "</script></head>\n"
1491             + "<body onload='test()'>\n"
1492             + LOG_TEXTAREA
1493             + "</body>\n"
1494             + "</html>\n";
1495 
1496         loadPageVerifyTextArea2(html);
1497     }
1498 
1499     /**
1500      * @throws Exception if an error occurs
1501      */
1502     @Test
1503     @Alerts({"done", "object", "3", "3,1337,Success"})
1504     public void allAsyncSet() throws Exception {
1505         final String html = DOCTYPE_HTML
1506             + "<html>\n"
1507             + "<head>\n"
1508             + "  <script>\n"
1509             + LOG_TEXTAREA_FUNCTION
1510             + "    function test() {\n"
1511             + "      if (window.Promise) {\n"
1512             + "        var p1 = Promise.resolve(3);\n"
1513             + "        var p2 = 1337;\n"
1514             + "        var p3 = new Promise(function(resolve, reject) {\n"
1515             + "            window.setTimeout( function() {\n"
1516             + "              resolve('Success');\n"
1517             + "            }, 20);\n"
1518             + "        });\n"
1519             + "\n"
1520             + "        Promise.all(new Set([p1, p2, p3])).then(function(values) {\n"
1521             + "          log(typeof values);\n"
1522             + "          log(values.length);\n"
1523             + "          log(values);\n"
1524             + "        });\n"
1525             + "        log('done');\n"
1526             + "      }\n"
1527             + "    }\n"
1528             + "</script></head>\n"
1529             + "<body onload='test()'>\n"
1530             + LOG_TEXTAREA
1531             + "</body>\n"
1532             + "</html>\n";
1533 
1534         loadPageVerifyTextArea2(html);
1535     }
1536 
1537     /**
1538      * @throws Exception if an error occurs
1539      */
1540     @Test
1541     @Alerts({"done", "string", "Failed"})
1542     public void allRejectAsync() throws Exception {
1543         final String html = DOCTYPE_HTML
1544             + "<html>\n"
1545             + "<head>\n"
1546             + "  <script>\n"
1547             + LOG_TEXTAREA_FUNCTION
1548             + "    function test() {\n"
1549             + "      if (window.Promise) {\n"
1550             + "        var p1 = Promise.resolve(3);\n"
1551             + "        var p2 = 1337;\n"
1552             + "        var p3 = new Promise(function(resolve, reject) {\n"
1553             + "            window.setTimeout( function() {\n"
1554             + "              reject('Failed');\n"
1555             + "            }, 20);\n"
1556             + "        });\n"
1557             + "\n"
1558             + "        Promise.all([p1, p2, p3]).then(function(value) {\n"
1559             + "            log('failure');\n"
1560             + "        }, function(value) {\n"
1561             + "          log(typeof value);\n"
1562             + "          log(value);\n"
1563             + "        });\n"
1564             + "        log('done');\n"
1565             + "      }\n"
1566             + "    }\n"
1567             + "</script></head>\n"
1568             + "<body onload='test()'>\n"
1569             + LOG_TEXTAREA
1570             + "</body>\n"
1571             + "</html>\n";
1572 
1573         loadPageVerifyTextArea2(html);
1574     }
1575 
1576     /**
1577      * @throws Exception if an error occurs
1578      */
1579     @Test
1580     @Alerts({"done", "first Failed", "second Failed"})
1581     public void allRejectAsync2() throws Exception {
1582         final String html = DOCTYPE_HTML
1583             + "<html>\n"
1584             + "<head>\n"
1585             + "  <script>\n"
1586             + LOG_TEXTAREA_FUNCTION
1587             + "    function test() {\n"
1588             + "      if (window.Promise) {\n"
1589             + "        var p1 = Promise.resolve(3);\n"
1590             + "        var p2 = 1337;\n"
1591             + "        var p3 = new Promise(function(resolve, reject) {\n"
1592             + "            window.setTimeout( function() {\n"
1593             + "              reject('Failed');\n"
1594             + "            }, 20);\n"
1595             + "        });\n"
1596             + "\n"
1597             + "        Promise.all([p1, p2, p3]).then(function(value) {\n"
1598             + "            log('failure');\n"
1599             + "        }, function(value) {\n"
1600             + "          log('first ' + value);\n"
1601             + "        });\n"
1602             + "        Promise.all([p1, p3]).then(function(value) {\n"
1603             + "            log('failure');\n"
1604             + "        }, function(value) {\n"
1605             + "          log('second ' + value);\n"
1606             + "        });\n"
1607             + "        log('done');\n"
1608             + "      }\n"
1609             + "    }\n"
1610             + "</script></head>\n"
1611             + "<body onload='test()'>\n"
1612             + LOG_TEXTAREA
1613             + "</body>\n"
1614             + "</html>\n";
1615 
1616         loadPageVerifyTextArea2(html);
1617     }
1618 
1619     /**
1620      * @throws Exception if an error occurs
1621      */
1622     @Test
1623     @Alerts({"done", "Success 2"})
1624     public void raceAsync() throws Exception {
1625         final String html = DOCTYPE_HTML
1626             + "<html>\n"
1627             + "<head>\n"
1628             + "  <script>\n"
1629             + LOG_TEXTAREA_FUNCTION
1630             + "    function test() {\n"
1631             + "      if (window.Promise) {\n"
1632             + "        var p1 = new Promise(function(resolve, reject) {\n"
1633             + "            window.setTimeout( function() {\n"
1634             + "              resolve('Success');\n"
1635             + "            }, 40);\n"
1636             + "        });\n"
1637             + "        var p2 = new Promise(function(resolve, reject) {\n"
1638             + "            window.setTimeout( function() {\n"
1639             + "              resolve('Success 2');\n"
1640             + "            }, 20);\n"
1641             + "        });\n"
1642             + "\n"
1643             + "        Promise.race([p1, p2]).then(function(value) {\n"
1644             + "          log(value);\n"
1645             + "        }, function(value) {\n"
1646             + "          log('failure');\n"
1647             + "        });\n"
1648             + "        log('done');\n"
1649             + "      }\n"
1650             + "    }\n"
1651             + "</script></head>\n"
1652             + "<body onload='test()'>\n"
1653             + LOG_TEXTAREA
1654             + "</body>\n"
1655             + "</html>\n";
1656 
1657         loadPageVerifyTextArea2(html);
1658     }
1659 
1660     /**
1661      * @throws Exception if an error occurs
1662      */
1663     @Test
1664     @Alerts({"done", "first Success 2", "second Success 2"})
1665     public void raceAsync2() throws Exception {
1666         final String html = DOCTYPE_HTML
1667             + "<html>\n"
1668             + "<head>\n"
1669             + "  <script>\n"
1670             + LOG_TEXTAREA_FUNCTION
1671             + "    function test() {\n"
1672             + "      if (window.Promise) {\n"
1673             + "        var p1 = new Promise(function(resolve, reject) {\n"
1674             + "            window.setTimeout( function() {\n"
1675             + "              resolve('Success');\n"
1676             + "            }, 40);\n"
1677             + "        });\n"
1678             + "        var p2 = new Promise(function(resolve, reject) {\n"
1679             + "            window.setTimeout( function() {\n"
1680             + "              resolve('Success 2');\n"
1681             + "            }, 20);\n"
1682             + "        });\n"
1683             + "\n"
1684             + "        Promise.race([p1, p2]).then(function(value) {\n"
1685             + "          log('first ' + value);\n"
1686             + "        }, function(value) {\n"
1687             + "          log('failure');\n"
1688             + "        });\n"
1689             + "        Promise.race([p1, p2]).then(function(value) {\n"
1690             + "          log('second ' + value);\n"
1691             + "        }, function(value) {\n"
1692             + "          log('failure');\n"
1693             + "        });\n"
1694             + "        log('done');\n"
1695             + "      }\n"
1696             + "    }\n"
1697             + "</script></head>\n"
1698             + "<body onload='test()'>\n"
1699             + LOG_TEXTAREA
1700             + "</body>\n"
1701             + "</html>\n";
1702 
1703         loadPageVerifyTextArea2(html);
1704     }
1705 
1706     /**
1707      * @throws Exception if an error occurs
1708      */
1709     @Test
1710     @Alerts({"done", "Failed"})
1711     public void raceRejectAsync() throws Exception {
1712         final String html = DOCTYPE_HTML
1713             + "<html>\n"
1714             + "<head>\n"
1715             + "  <script>\n"
1716             + LOG_TEXTAREA_FUNCTION
1717             + "    function test() {\n"
1718             + "      if (window.Promise) {\n"
1719             + "        var p1 = new Promise(function(resolve, reject) {\n"
1720             + "            window.setTimeout( function() {\n"
1721             + "              resolve('Success');\n"
1722             + "            }, 40);\n"
1723             + "        });\n"
1724             + "        var p2 = new Promise(function(resolve, reject) {\n"
1725             + "            window.setTimeout( function() {\n"
1726             + "              reject('Failed');\n"
1727             + "            }, 20);\n"
1728             + "        });\n"
1729             + "\n"
1730             + "        Promise.race([p1, p2]).then(function(value) {\n"
1731             + "          log('failure');\n"
1732             + "        }, function(value) {\n"
1733             + "          log(value);\n"
1734             + "        });\n"
1735             + "        log('done');\n"
1736             + "      }\n"
1737             + "    }\n"
1738             + "</script></head>\n"
1739             + "<body onload='test()'>\n"
1740             + LOG_TEXTAREA
1741             + "</body>\n"
1742             + "</html>\n";
1743 
1744         loadPageVerifyTextArea2(html);
1745     }
1746 
1747     /**
1748      * @throws Exception if an error occurs
1749      */
1750     @Test
1751     @Alerts({"done", "first Failed", "second Failed"})
1752     public void raceRejectAsync2() throws Exception {
1753         final String html = DOCTYPE_HTML
1754             + "<html>\n"
1755             + "<head>\n"
1756             + "  <script>\n"
1757             + LOG_TEXTAREA_FUNCTION
1758             + "    function test() {\n"
1759             + "      if (window.Promise) {\n"
1760             + "        var p1 = new Promise(function(resolve, reject) {\n"
1761             + "            window.setTimeout( function() {\n"
1762             + "              resolve('Success');\n"
1763             + "            }, 40);\n"
1764             + "        });\n"
1765             + "        var p2 = new Promise(function(resolve, reject) {\n"
1766             + "            window.setTimeout( function() {\n"
1767             + "              reject('Failed');\n"
1768             + "            }, 20);\n"
1769             + "        });\n"
1770             + "\n"
1771             + "        Promise.race([p1, p2]).then(function(value) {\n"
1772             + "          log('failure');\n"
1773             + "        }, function(value) {\n"
1774             + "          log('first ' + value);\n"
1775             + "        });\n"
1776             + "        Promise.race([p1, p2]).then(function(value) {\n"
1777             + "          log('failure');\n"
1778             + "        }, function(value) {\n"
1779             + "          log('second ' + value);\n"
1780             + "        });\n"
1781             + "        log('done');\n"
1782             + "      }\n"
1783             + "    }\n"
1784             + "</script></head>\n"
1785             + "<body onload='test()'>\n"
1786             + LOG_TEXTAREA
1787             + "</body>\n"
1788             + "</html>\n";
1789 
1790         loadPageVerifyTextArea2(html);
1791     }
1792 
1793     /**
1794      * @throws Exception if the test fails
1795      */
1796     @Test
1797     @Alerts("")
1798     public void changeLocationFromPromise() throws Exception {
1799         final String html = DOCTYPE_HTML
1800               + "<html>\n"
1801               + "<head>\n"
1802               + "  <title>test</title>\n"
1803               + "  <script>\n"
1804               + "    function test() {\n"
1805               + "      if (window.Promise) {\n"
1806               + "        Promise.resolve(1).then(function () {\n"
1807               + "          location.href = 'about:blank';\n"
1808               + "        });\n"
1809               + "      }\n"
1810               + "    }\n"
1811               + "  </script>\n"
1812               + "</head>\n"
1813               + "<body onload='test()'>\n"
1814               + "</body>\n"
1815               + "</html>";
1816 
1817         final WebDriver driver = loadPage2(html);
1818         Thread.sleep(100);
1819         assertTitle(driver, getExpectedAlerts()[0]);
1820     }
1821 
1822     /**
1823      * @throws Exception if the test fails
1824      */
1825     @Test
1826     @Alerts(DEFAULT = {"function\\sPromise()\\s{\\s[native\\scode]\\s}", "true", "[GC]"},
1827             FF = {"function\\sPromise()\\s{\\n\\s\\s\\s\\s[native\\scode]\\n}", "true", "[GC]"},
1828             FF_ESR = {"function\\sPromise()\\s{\\n\\s\\s\\s\\s[native\\scode]\\n}", "true", "[GC]"})
1829     public void speciesValue() throws Exception {
1830         final String html = DOCTYPE_HTML
1831               + "<html>\n"
1832               + "<head>\n"
1833               + "  <script>\n"
1834               + LOG_TITLE_FUNCTION_NORMALIZE
1835               + "    function test() {\n"
1836               + "      if (window.Promise) {\n"
1837               + "        log(Promise[Symbol.species]);\n"
1838               + "        log(Promise === Promise[Symbol.species]);\n"
1839 
1840               + "        let desc = Object.getOwnPropertyDescriptor(Promise, Symbol.species);\n"
1841               + "        let props = '[';\n"
1842               + "        if (desc.get != undefined) props += 'G';\n"
1843               + "        if (desc.set != undefined) props += 'S';\n"
1844               + "        if (desc.writable) props += 'W';\n"
1845               + "        if (desc.configurable) props += 'C';\n"
1846               + "        if (desc.enumerable) props += 'E';\n"
1847               + "        props += ']';\n"
1848               + "        log(props);\n"
1849               + "      }\n"
1850               + "    }\n"
1851               + "  </script>\n"
1852               + "</head>\n"
1853               + "<body onload='test()'>\n"
1854               + "</body>\n"
1855               + "</html>";
1856 
1857         loadPageVerifyTitle2(html);
1858     }
1859 }