1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.css;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.annotation.Alerts;
19 import org.junit.jupiter.api.Test;
20 import org.openqa.selenium.By;
21 import org.openqa.selenium.WebDriver;
22
23
24
25
26
27
28
29
30 public class CSSStyleDeclaration2Test extends WebDriverTestCase {
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 @Test
104 @Alerts({"bottom: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
105 "left: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
106 "right: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
107 "top: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]"})
108 public void width_like_properties() throws Exception {
109 width_like_properties("bottom", "left", "right", "top");
110 }
111
112
113
114
115 @Test
116 @Alerts({"borderBottomWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]",
117 "borderLeftWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]",
118 "borderRightWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]",
119 "borderTopWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]"})
120 public void width_like_properties_border() throws Exception {
121 width_like_properties("borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopWidth");
122 }
123
124
125
126
127 @Test
128 @Alerts({"marginBottom: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
129 "marginLeft: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
130 "marginRight: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
131 "marginTop: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]"})
132 public void width_like_properties_margin() throws Exception {
133 width_like_properties("marginBottom", "marginLeft", "marginRight", "marginTop");
134 }
135
136
137
138
139 @Test
140 @Alerts({"paddingBottom: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
141 "paddingLeft: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
142 "paddingRight: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
143 "paddingTop: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]"})
144 public void width_like_properties_padding() throws Exception {
145 width_like_properties("paddingBottom", "paddingLeft", "paddingRight", "paddingTop");
146 }
147
148
149
150
151 @Test
152 @Alerts({"height: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
153 "width: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
154 "maxHeight: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
155 "maxWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
156 "minHeight: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
157 "minWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]"})
158 public void width_like_properties_heightWidth() throws Exception {
159 width_like_properties("height", "width", "maxHeight", "maxWidth", "minHeight", "minWidth");
160 }
161
162
163
164
165 @Test
166 @Alerts(DEFAULT = {"fontSize: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
167 "letterSpacing: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]",
168 "outlineWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]",
169 "textIndent: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
170 "verticalAlign: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
171 "wordSpacing: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]"},
172 FF = {"fontSize: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
173 "letterSpacing: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
174 "outlineWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]",
175 "textIndent: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
176 "verticalAlign: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
177 "wordSpacing: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]"},
178 FF_ESR = {"fontSize: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
179 "letterSpacing: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
180 "outlineWidth: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42em]",
181 "textIndent: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
182 "verticalAlign: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]",
183 "wordSpacing: initial [] 42.0 [] 42.7 [] 42 [] 42px [42px] 42mm [42mm] 42em [42em] 42% [42%]"})
184 public void width_like_properties_font() throws Exception {
185 width_like_properties("fontSize", "letterSpacing", "outlineWidth", "textIndent",
186 "verticalAlign", "wordSpacing");
187 }
188
189 private void width_like_properties(final String... properties) throws Exception {
190 final String props = "'" + String.join("', '", properties) + "'";
191 final String html = DOCTYPE_HTML
192 + "<html><head><script>\n"
193 + LOG_TITLE_FUNCTION
194 + "function test() {\n"
195 + " var properties = [" + props + "];\n"
196 + "\n"
197 + " for (var prop in properties) {\n"
198 + " prop = properties[prop];\n"
199 + " var result = prop + ':';\n"
200
201 + " var node = document.createElement('div');\n"
202 + " result += ' initial [' + node.style[prop] + ']';\n"
203
204 + " node.style[prop] = '42.0';\n"
205 + " result += ' 42.0 [' + node.style[prop] + ']';\n"
206
207 + " node.style[prop] = '42.7';\n"
208 + " result += ' 42.7 [' + node.style[prop] + ']';\n"
209
210 + " node.style[prop] = '42';\n"
211 + " result += ' 42 [' + node.style[prop] + ']';\n"
212
213 + " node.style[prop] = '42px';\n"
214 + " result += ' 42px [' + node.style[prop] + ']';\n"
215
216 + " node.style[prop] = '42mm';\n"
217 + " result += ' 42mm [' + node.style[prop] + ']';\n"
218
219 + " node.style[prop] = '42em';\n"
220 + " result += ' 42em [' + node.style[prop] + ']';\n"
221
222 + " node.style[prop] = '42%';\n"
223 + " result += ' 42% [' + node.style[prop] + ']';\n"
224
225 + " log(result);\n"
226 + " }\n"
227 + "}\n"
228 + "</script></head>\n"
229 + "<body onload='test()'></body></html>";
230
231 loadPageVerifyTitle2(html);
232 }
233
234
235
236
237 @Test
238 @Alerts({"", "baseline", "sub", "super", "text-top",
239 "text-bottom", "middle", "top", "bottom",
240 "1.7em", "4px", "32%",
241 "inherit", "initial", "revert", "unset",
242 "unset", "unset", "unset"})
243 public void verticalAlign() throws Exception {
244 checkPropertyValues("vertical-align",
245 "baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom",
246 "1.7em", "4px", "32%",
247 "inherit", "initial", "revert", "unset",
248 "1 px", "7mond", "not-supported");
249 checkPropertyValuesDirect("verticalAlign",
250 "baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom",
251 "1.7em", "4px", "32%",
252 "inherit", "initial", "revert", "unset",
253 "1 px", "7mond", "not-supported");
254 }
255
256 private void checkPropertyValuesDirect(final String property, final String... propertyValues) throws Exception {
257 final String propValues = "'" + String.join("', '", propertyValues) + "'";
258 final String html = DOCTYPE_HTML
259 + "<html><head><script>\n"
260 + LOG_TITLE_FUNCTION
261 + "function test() {\n"
262 + " var propValues = [" + propValues + "];\n"
263 + "\n"
264 + " var node = document.createElement('div');\n"
265 + " var styleVal = node.style." + property + ";\n"
266 + " log(styleVal);\n"
267
268 + " propValues.forEach(propValue => {\n"
269 + " node.style." + property + " = propValue;\n"
270 + " styleVal = node.style." + property + ";\n"
271 + " log(styleVal);\n"
272 + " });\n"
273 + "}\n"
274 + "</script></head>\n"
275 + "<body onload='test()'></body></html>";
276
277 loadPageVerifyTitle2(html);
278 }
279
280 private void checkPropertyValues(final String property, final String... propertyValues) throws Exception {
281 final String propValues = "'" + String.join("', '", propertyValues) + "'";
282 final String html = DOCTYPE_HTML
283 + "<html><head><script>\n"
284 + LOG_TITLE_FUNCTION
285 + "function test() {\n"
286 + " var propValues = [" + propValues + "];\n"
287 + "\n"
288 + " var node = document.createElement('div');\n"
289 + " var styleVal = node.style['" + property + "'];\n"
290 + " log(styleVal);\n"
291
292 + " propValues.forEach(propValue => {\n"
293 + " node.style['" + property + "'] = propValue;\n"
294 + " styleVal = node.style['" + property + "'];\n"
295 + " log(styleVal);\n"
296 + " });\n"
297 + "}\n"
298 + "</script></head>\n"
299 + "<body onload='test()'></body></html>";
300
301 loadPageVerifyTitle2(html);
302 }
303
304
305
306
307 @Test
308 public void properties() throws Exception {
309 final String html = DOCTYPE_HTML
310 + "<html>\n"
311 + "<head><title>Tester</title>\n"
312 + "<script>\n"
313 + "function test() {\n"
314 + " var style = document.getElementById('myDiv').style;\n"
315 + " var array = [];\n"
316 + " for (var i in style) {\n"
317 + " try {\n"
318 + " if (eval('style.' + i) == '') { array.push(i); }\n"
319 + " } catch(e) {}\n"
320 + " }\n"
321 + " array.sort();\n"
322 + " document.getElementById('myLog').value = array.join('\\n');\n"
323 + "}\n"
324 + "</script></head>\n"
325 + "<body onload='test()'>\n"
326 + " <div id='myDiv'><br></div>\n"
327 + LOG_TEXTAREA
328 + "</body></html>";
329
330 final String expected = loadExpectation("CSSStyleDeclaration2Test.properties", ".txt");
331
332 final WebDriver driver = loadPage2(html);
333 verify(() -> driver.findElement(By.id("myLog")).getDomProperty("value"), expected);
334 }
335
336
337
338
339
340 @Test
341 public void properties2() throws Exception {
342 final String html = DOCTYPE_HTML
343 + "<html>\n"
344 + "<head>\n"
345 + "<script>\n"
346 + "function test() {\n"
347 + " var style = document.getElementById('myDiv').style;\n"
348 + " var array = [];\n"
349 + " for (var i in style) {\n"
350 + " try {\n"
351 + " if (eval('style.' + i) === '') { array.push(i); }\n"
352 + " } catch(e) {}\n"
353 + " }\n"
354 + " array.sort();\n"
355 + " document.getElementById('myLog').value = array.join('\\n');\n"
356 + "}\n"
357 + "</script></head>\n"
358 + "<body onload='test()'>\n"
359 + " <div id='myDiv'><br></div>\n"
360 + LOG_TEXTAREA
361 + "</body></html>";
362
363 final String expected = loadExpectation("CSSStyleDeclaration2Test.properties2", ".txt");
364
365 final WebDriver driver = loadPage2(html);
366 verify(() -> driver.findElement(By.id("myLog")).getDomProperty("value"), expected);
367 }
368
369
370
371
372 @Test
373 @Alerts({"0", "0"})
374 public void setLength() throws Exception {
375 final String html = DOCTYPE_HTML
376 + "<html>\n"
377 + "<head>\n"
378 + "<script>\n"
379 + LOG_TITLE_FUNCTION
380 + "function test() {\n"
381 + " var style = document.body.style;\n"
382 + " try {\n"
383 + " log(style.length);\n"
384 + " style.length = 100;\n"
385 + " log(style.length);\n"
386 + " } catch(e) { log(e); }\n"
387 + "}\n"
388 + "</script></head>\n"
389 + "<body onload='test()'>\n"
390 + "</body></html>";
391
392 loadPageVerifyTitle2(html);
393 }
394
395
396
397
398 @Test
399 @Alerts({"0", "Type error"})
400 public void setLengthStrictMode() throws Exception {
401 final String html = DOCTYPE_HTML
402 + "<html>\n"
403 + "<head>\n"
404 + "<script>\n"
405 + LOG_TITLE_FUNCTION
406 + "function test() {\n"
407 + " 'use strict';\n"
408 + " var style = document.body.style;\n"
409 + " try {\n"
410 + " log(style.length);\n"
411 + " style.length = 100;\n"
412 + " log(style.length);\n"
413 + " } catch(e) { log('Type error'); }\n"
414 + "}\n"
415 + "</script></head>\n"
416 + "<body onload='test()'>\n"
417 + "</body></html>";
418
419 loadPageVerifyTitle2(html);
420 }
421
422
423
424
425 @Test
426 @Alerts({"function values() { [native code] }", "no for..of", "display"})
427 public void iterator() throws Exception {
428 final String html = DOCTYPE_HTML
429 + "<html><head>\n"
430 + "</head>\n"
431 + "<script>\n"
432 + LOG_TITLE_FUNCTION
433 + " function test() {\n"
434 + " var style = document.body.style;\n"
435
436 + " if (typeof Symbol != 'undefined') {\n"
437 + " log(style[Symbol.iterator]);\n"
438 + " }\n"
439
440 + " if (!style.forEach) {\n"
441 + " log('no for..of');\n"
442 + " }\n"
443
444 + " if (typeof Symbol === 'undefined') {\n"
445 + " return;\n"
446 + " }\n"
447
448 + " for (var i of style) {\n"
449 + " log(i);\n"
450 + " }\n"
451 + " }\n"
452 + "</script>\n"
453 + "</head><body onload='test()' style='display: inline'>\n"
454 + " <div></div>\n"
455 + "</body></html>";
456
457 loadPageVerifyTitle2(html);
458 }
459 }