1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.BrowserRunner;
19 import org.htmlunit.junit.annotation.Alerts;
20 import org.htmlunit.junit.annotation.HtmlUnitNYI;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.openqa.selenium.WebDriverException;
24
25
26
27
28
29
30
31 @RunWith(BrowserRunner.class)
32 public class ScriptableObjectTest extends WebDriverTestCase {
33
34
35
36
37
38
39
40 @Test
41 @Alerts({"default", "default", "default"})
42 public void readOnlyPrototype() throws Exception {
43 final String html = DOCTYPE_HTML
44 + "<html><body>\n"
45 + "<script>\n"
46 + LOG_TITLE_FUNCTION
47 + " var proto = Object.create(Object.prototype, {\n"
48 + " myProp: {\n"
49 + " get: function() { return 'default'; }\n"
50 + " }\n"
51 + " });\n"
52 + " var o1 = Object.create(proto);\n"
53 + " var o2 = Object.create(proto);\n"
54 + " o2.myProp = 'bar';\n"
55 + " log(o2.myProp);\n"
56 + " log(o1.myProp);\n"
57 + " log(proto.myProp)"
58 + "</script>\n"
59 + "</body>\n"
60 + "</html>\n";
61
62 loadPageVerifyTitle2(html);
63 }
64
65
66
67
68 @Test
69 @Alerts({"2", "symbol", "symbol", "1", "c"})
70 public void getOwnPropertySymbols() throws Exception {
71 final String html = DOCTYPE_HTML
72 + "<html><body>\n"
73 + "<script>\n"
74 + LOG_TITLE_FUNCTION
75 + " if (Object.getOwnPropertySymbols) {\n"
76
77 + " var obj = {};\n"
78 + " var a = Symbol('a');\n"
79 + " var b = Symbol.for('b');\n"
80
81 + " obj[a] = 'localSymbol';\n"
82 + " obj[b] = 'globalSymbol';\n"
83 + " obj['c'] = 'something else';\n"
84
85 + " var objectSymbols = Object.getOwnPropertySymbols(obj);\n"
86 + " log(objectSymbols.length);\n"
87 + " log(typeof objectSymbols[0]);\n"
88 + " log(typeof objectSymbols[1]);\n"
89
90 + " var objectNames = Object.getOwnPropertyNames(obj);\n"
91 + " log(objectNames.length);\n"
92 + " log(objectNames[0]);\n"
93
94 + " } else { log('not defined'); }\n"
95 + "</script>\n"
96 + "</body>\n"
97 + "</html>\n";
98
99 loadPageVerifyTitle2(html);
100 }
101
102
103
104
105 @Test
106 @Alerts({"TypeError", "true", "true"})
107 public void ctorNotChangeableForPrimitives() throws Exception {
108 final String html = DOCTYPE_HTML
109 + "<html><body>\n"
110 + "<script>\n"
111 + LOG_TITLE_FUNCTION
112 + " let val = null;\n"
113 + " try {\n"
114 + " val.constructor = 1;\n"
115 + " } catch(e) { logEx(e); }\n"
116
117 + " val = 'abc';\n"
118 + " val.constructor = Number;"
119 + " log(val.constructor === String)\n"
120
121
122 + " val.foo = 'bar';\n"
123
124
125 + " log (val.foo === undefined);\n"
126
127 + "</script>\n"
128 + "</body>\n"
129 + "</html>\n";
130
131 loadPageVerifyTitle2(html);
132 }
133
134
135
136
137
138 @Test
139 @Alerts({"TypeError", "true", "true"})
140 @HtmlUnitNYI(CHROME = "org.htmlunit.ScriptException: TypeError: Cannot set property \"constructor\" of abc",
141 EDGE = "org.htmlunit.ScriptException: TypeError: Cannot set property \"constructor\" of abc",
142 FF = "org.htmlunit.ScriptException: TypeError: Cannot set property \"constructor\" of abc",
143 FF_ESR = "org.htmlunit.ScriptException: TypeError: Cannot set property \"constructor\" of abc")
144 public void ctorNotChangeableForPrimitivesStrict() throws Exception {
145 final String html = DOCTYPE_HTML
146 + "<html><body>\n"
147 + "<script>\n"
148 + LOG_TITLE_FUNCTION
149
150 + " 'use strict';\n"
151
152 + " let val = null;\n"
153 + " try {\n"
154 + " val.constructor = 1;\n"
155 + " } catch(e) { logEx(e); }\n"
156
157 + " val = 'abc';\n"
158 + " val.constructor = Number;"
159 + " log(val.constructor === String)\n"
160
161
162 + " val.foo = 'bar';\n"
163
164
165 + " log (val.foo === undefined);\n"
166
167 + "</script>\n"
168 + "</body>\n"
169 + "</html>\n";
170
171 try {
172 loadPageVerifyTitle2(html);
173 }
174 catch (final WebDriverException e) {
175 assertTrue(e.getMessage(), e.getMessage().startsWith(getExpectedAlerts()[0]));
176 }
177 }
178
179
180
181
182 @Test
183 @Alerts({"true", "false", "true", "ctor", "true"})
184 public void ctorChangeableHasNoEffectForTypeOf() throws Exception {
185 final String html = DOCTYPE_HTML
186 + "<html><body>\n"
187 + "<script>\n"
188 + LOG_TITLE_FUNCTION
189
190 + " let a = [];\n"
191 + " a.constructor = String\n"
192 + " log(a.constructor === String);\n"
193 + " log(a instanceof String);\n"
194 + " log(a instanceof Array);\n"
195
196 + " try {\n"
197 + " a = new Event('test');\n"
198 + " log('ctor');\n"
199 + " a.constructor = 'bar';\n"
200 + " log(a.constructor === 'bar');\n"
201 + " } catch(e) { logEx(e) }\n"
202
203 + "</script>\n"
204 + "</body>\n"
205 + "</html>\n";
206
207 loadPageVerifyTitle2(html);
208 }
209
210
211
212
213 @Test
214 @Alerts({"true", "false", "true", "ctor", "true"})
215 public void ctorChangeableHasNoEffectForTypeOfStrict() throws Exception {
216 final String html = DOCTYPE_HTML
217 + "<html><body>\n"
218 + "<script>\n"
219 + " 'use strict';\n"
220 + LOG_TITLE_FUNCTION
221
222 + " let a = [];\n"
223 + " a.constructor = String\n"
224 + " log(a.constructor === String);\n"
225 + " log(a instanceof String);\n"
226 + " log(a instanceof Array);\n"
227
228 + " try {\n"
229 + " a = new Event('test');\n"
230 + " log('ctor');\n"
231 + " a.constructor = 'bar';\n"
232 + " log(a.constructor === 'bar');\n"
233 + " } catch(e) { logEx(e) }\n"
234
235 + "</script>\n"
236 + "</body>\n"
237 + "</html>\n";
238
239 loadPageVerifyTitle2(html);
240 }
241
242
243
244
245 @Test
246 @Alerts("true")
247 public void ctorChangeableHasNoEffectForSealed() throws Exception {
248 final String html = DOCTYPE_HTML
249 + "<html><body>\n"
250 + "<script>\n"
251 + LOG_TITLE_FUNCTION
252
253 + " let a = Object.seal({});\n"
254 + " a.constructor = Number;\n"
255 + " log(a.constructor === Object);\n"
256
257 + "</script>\n"
258 + "</body>\n"
259 + "</html>\n";
260
261 loadPageVerifyTitle2(html);
262 }
263
264
265
266
267 @Test
268 @Alerts("true")
269 @HtmlUnitNYI(CHROME = "TypeError",
270 EDGE = "TypeError",
271 FF = "TypeError",
272 FF_ESR = "TypeError")
273 public void ctorChangeableHasNoEffectForSealedStrict() throws Exception {
274 final String html = DOCTYPE_HTML
275 + "<html><body>\n"
276 + "<script>\n"
277 + LOG_TITLE_FUNCTION
278
279 + " 'use strict';\n"
280
281 + " let a = Object.seal({});\n"
282 + " try {\n"
283 + " a.constructor = Number;\n"
284 + " log(a.constructor === Object);\n"
285 + " } catch(e) { logEx(e) }\n"
286
287 + "</script>\n"
288 + "</body>\n"
289 + "</html>\n";
290
291 loadPageVerifyTitle2(html);
292 }
293 }