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;
16  
17  import org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.junit.annotation.Alerts;
19  import org.htmlunit.junit.annotation.HtmlUnitNYI;
20  import org.junit.jupiter.api.Test;
21  import org.openqa.selenium.WebDriver;
22  
23  /**
24   * Tests for NativeError.
25   *
26   * @author Ahmed Ashour
27   * @author Marc Guillemot
28   * @author Frank Danek
29   * @author Ronald Brill
30   */
31  public class NativeErrorTest extends WebDriverTestCase {
32  
33      /**
34       * @throws Exception if the test fails
35       */
36      @Test
37      @Alerts({"string", "true"})
38      public void stack() throws Exception {
39          final String html = DOCTYPE_HTML
40              + "<html><head><script>\n"
41              + LOG_TITLE_FUNCTION
42              + "function test() {\n"
43              + "  try {\n"
44              + "    null.method();\n"
45              + "  } catch(e) {\n"
46              + "    if (e.stack) {\n"
47              + "      var s = e.stack;\n"
48              + "      log(typeof s);\n"
49              + "      log(s.length > 0);\n"
50              + "    }\n"
51              + "    else\n"
52              + "      log('undefined');\n"
53              + "  }\n"
54              + "}\n"
55              + "</script></head><body onload='test()'>\n"
56              + "</body></html>";
57  
58          loadPageVerifyTitle2(html);
59      }
60  
61      /**
62       * @throws Exception if the test fails
63       */
64      @Test
65      @Alerts({"string", "true"})
66      public void stackNewError() throws Exception {
67          final String html = DOCTYPE_HTML
68              + "<html><head><script>\n"
69              + LOG_TITLE_FUNCTION
70              + "function test() {\n"
71              + "  try {\n"
72              + "    throw new Error();\n"
73              + "  } catch(e) {\n"
74              + "    if (e.stack) {\n"
75              + "      var s = e.stack;\n"
76              + "      log(typeof s);\n"
77              + "      log(s.length > 0);\n"
78              + "    }\n"
79              + "    else\n"
80              + "      log('undefined');\n"
81              + "  }\n"
82              + "}\n"
83              + "</script></head><body onload='test()'>\n"
84              + "</body></html>";
85  
86          loadPageVerifyTitle2(html);
87      }
88  
89      /**
90       * @throws Exception if the test fails
91       */
92      @Test
93      @Alerts({"string", "true"})
94      public void stackNewErrorWithoutThrow() throws Exception {
95          final String html = DOCTYPE_HTML
96              + "<html><head><script>\n"
97              + LOG_TITLE_FUNCTION
98              + "function test() {\n"
99              + "  var e = new Error();\n"
100             + "  if (e.stack) {\n"
101             + "    var s = e.stack;\n"
102             + "    log(typeof s);\n"
103             + "    log(s.length > 0);\n"
104             + "  }\n"
105             + "  else\n"
106             + "    log('undefined');\n"
107             + "}\n"
108             + "</script></head><body onload='test()'>\n"
109             + "</body></html>";
110 
111         loadPageVerifyTitle2(html);
112     }
113 
114     /**
115      * @throws Exception if the test fails
116      */
117     @Test
118     @Alerts("true")
119     public void stackInNewError() throws Exception {
120         final String html = DOCTYPE_HTML
121             + "<html><head><script>\n"
122             + LOG_TITLE_FUNCTION
123             + "function test() {\n"
124             + "  var e = new Error();\n"
125             + "  log('stack' in e);\n"
126             + "}\n"
127             + "</script></head><body onload='test()'>\n"
128             + "</body></html>";
129 
130         loadPageVerifyTitle2(html);
131     }
132 
133     /**
134      * @throws Exception if the test fails
135      */
136     @Test
137     @Alerts(DEFAULT = "method (url)",
138             FF = "method@url",
139             FF_ESR = "method@url")
140     @HtmlUnitNYI(CHROME = "method()@url",
141             EDGE = "method()@url",
142             FF = "method()@url",
143             FF_ESR = "method()@url")
144     public void stackContent() throws Exception {
145         final String html = DOCTYPE_HTML
146             + "<html><head><script>\n"
147             + LOG_TITLE_FUNCTION
148             + "function test() {\n"
149             + "  try {\n"
150             + "    null.method();\n"
151             + "  } catch(e) {\n"
152             + "    if (e.stack) {\n"
153             + "      var s = e.stack;\n"
154             + "      if (s.indexOf('test()@') != -1) {\n"
155             + "        log('method()@url');\n"
156             + "      } else if (s.indexOf('test@') != -1) {\n"
157             + "        log('method@url');\n"
158             + "      } else if (s.indexOf('test (') != -1) {\n"
159             + "        log('method (url)');\n"
160             + "      } else if (s.indexOf('test() (') != -1) {\n"
161             + "        log('method() (url)');\n"
162             + "      }\n"
163             + "    }\n"
164             + "    else\n"
165             + "      log('undefined');\n"
166             + "  }\n"
167             + "}\n"
168             + "</script></head><body onload='test()'>\n"
169             + "</body></html>";
170 
171         loadPageVerifyTitle2(html);
172     }
173 
174     /**
175      * @throws Exception if the test fails
176      */
177     @Test
178     @Alerts(DEFAULT = "method (url)",
179             FF = "method@url",
180             FF_ESR = "method@url")
181     @HtmlUnitNYI(CHROME = "method()@url",
182             EDGE = "method()@url",
183             FF = "method()@url",
184             FF_ESR = "method()@url")
185     public void stackContentNewError() throws Exception {
186         final String html = DOCTYPE_HTML
187             + "<html><head><script>\n"
188             + LOG_TITLE_FUNCTION
189             + "function test() {\n"
190             + "  try {\n"
191             + "    throw new Error();\n"
192             + "  } catch(e) {\n"
193             + "    if (e.stack) {\n"
194             + "      var s = e.stack;\n"
195             + "      if (s.indexOf('test()@') != -1) {\n"
196             + "        log('method()@url');\n"
197             + "      } else if (s.indexOf('test@') != -1) {\n"
198             + "        log('method@url');\n"
199             + "      } else if (s.indexOf('test (') != -1) {\n"
200             + "        log('method (url)');\n"
201             + "      } else if (s.indexOf('test() (') != -1) {\n"
202             + "        log('method() (url)');\n"
203             + "      }\n"
204             + "    }\n"
205             + "    else\n"
206             + "      log('undefined');\n"
207             + "  }\n"
208             + "}\n"
209             + "</script></head><body onload='test()'>\n"
210             + "</body></html>";
211 
212         loadPageVerifyTitle2(html);
213     }
214 
215     /**
216      * @throws Exception if the test fails
217      */
218     @Test
219     @Alerts({"true", "kcats"})
220     public void stackOverwrite() throws Exception {
221         final String html = DOCTYPE_HTML
222             + "<html><head><script>\n"
223             + LOG_TITLE_FUNCTION
224             + "function test() {\n"
225             + "  try {\n"
226             + "    null.method();\n"
227             + "  } catch(e) {\n"
228             + "    if (e.stack) {\n"
229             + "      var s = e.stack;\n"
230             + "      log(s.length > 10);\n"
231 
232             + "      e.stack = 'kcats';\n"
233             + "      var s = e.stack;\n"
234             + "      log(s);\n"
235             + "    }\n"
236             + "    else\n"
237             + "      log('undefined');\n"
238             + "  }\n"
239             + "}\n"
240             + "</script></head><body onload='test()'>\n"
241             + "</body></html>";
242 
243         loadPageVerifyTitle2(html);
244     }
245 
246     /**
247      * @throws Exception if the test fails
248      */
249     @Test
250     @Alerts(DEFAULT = "10",
251             FF = "undefined",
252             FF_ESR = "undefined")
253     public void stackTraceLimit() throws Exception {
254         final String html = DOCTYPE_HTML
255             + "<html><head><script>\n"
256             + LOG_TITLE_FUNCTION
257             + "function test() {\n"
258             + "  log(Error.stackTraceLimit);\n"
259             + "}\n"
260             + "</script></head><body onload='test()'>\n"
261             + "</body></html>";
262 
263         loadPageVerifyTitle2(html);
264     }
265 
266     /**
267      * @throws Exception if the test fails
268      */
269     @Test
270     @Alerts("function captureStackTrace() { [native code] }")
271     public void captureStackTrace() throws Exception {
272         final String html = DOCTYPE_HTML
273             + "<html><head><script>\n"
274             + LOG_TITLE_FUNCTION
275             + "function test() {\n"
276             + "  log(Error.captureStackTrace);\n"
277             + "}\n"
278             + "</script></head><body onload='test()'>\n"
279             + "</body></html>";
280 
281         loadPageVerifyTitle2(html);
282     }
283 
284     /**
285      * @throws Exception if the test fails
286      */
287     @Test
288     public void stackLineSeparator() throws Exception {
289         final String lineSeparator = System.getProperty("line.separator");
290         try {
291             System.setProperty("line.separator", "\r\n");
292 
293             final String html = DOCTYPE_HTML
294                 + "<html><head><script>\n"
295                 + LOG_TITLE_FUNCTION
296                 + "function test() {\n"
297                 + "  try {\n"
298                 + "    throw new Error();\n"
299                 + "  } catch(e) {\n"
300                 + "    log(e.stack.replace('\\r', '\\\\r').replace('\\n', '\\\\n'));\n"
301                 + "  }"
302                 + "}\n"
303                 + "</script></head><body onload='test()'>\n"
304                 + "</body></html>";
305 
306             final WebDriver driver = loadPage2(html);
307             final String title = driver.getTitle();
308             assertTrue(title, title.contains("\\n"));
309             assertFalse(title, title.contains("\\r"));
310         }
311         finally {
312             System.setProperty("line.separator", lineSeparator);
313         }
314     }
315 }