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