1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import java.io.InputStream;
18 import java.net.URL;
19 import java.util.Collections;
20
21 import org.apache.commons.io.IOUtils;
22 import org.htmlunit.WebDriverTestCase;
23 import org.htmlunit.junit.BrowserRunner;
24 import org.htmlunit.junit.annotation.Alerts;
25 import org.htmlunit.junit.annotation.BuggyWebDriver;
26 import org.htmlunit.junit.annotation.HtmlUnitNYI;
27 import org.htmlunit.util.MimeType;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.openqa.selenium.By;
31 import org.openqa.selenium.WebDriver;
32 import org.openqa.selenium.WebElement;
33 import org.openqa.selenium.htmlunit.HtmlUnitDriver;
34
35
36
37
38
39
40
41
42
43
44
45
46 @RunWith(BrowserRunner.class)
47 public class HtmlElement2Test extends WebDriverTestCase {
48
49
50
51
52 @Test
53 public void onpropertychange() throws Exception {
54 final String html = DOCTYPE_HTML
55 + "<html><head><script>\n"
56 + LOG_TITLE_FUNCTION
57 + " function test() {\n"
58 + " document.getElementById('input1').value = 'New Value';\n"
59 + " }\n"
60 + " function handler() {\n"
61 + " log(event.propertyName);\n"
62 + " }\n"
63 + "</script></head>\n"
64 + "<body onload='test()'>\n"
65 + " <input id='input1' onpropertychange='handler()'>\n"
66 + "</body></html>";
67
68 loadPageVerifyTitle2(html);
69 }
70
71
72
73
74 @Test
75 @Alerts({"true", "true"})
76 public void duplicateId() throws Exception {
77 final String html = DOCTYPE_HTML
78 + "<html>\n"
79 + "<script>\n"
80 + LOG_TITLE_FUNCTION
81 + " function test() {\n"
82 + " var value = document.getElementById('duplicateID').innerHTML;\n"
83 + " log(value.length > 10);\n"
84 + " document.getElementById('duplicateID').style.display = 'block';\n"
85 + " log(value === document.getElementById('duplicateID').innerHTML);\n"
86 + " }\n"
87 + "</script>\n"
88 + "</head>\n"
89 + "<body onload='test()'>\n"
90 + " <fieldset id='duplicateID'><span id='duplicateID'></span></fieldset>\n"
91 + "</body></html>";
92
93 loadPageVerifyTitle2(html);
94 }
95
96
97
98
99 @Test
100 public void onpropertychange2() throws Exception {
101 final String html = DOCTYPE_HTML
102 + "<html><head><script>\n"
103 + LOG_TITLE_FUNCTION
104 + " function test() {\n"
105 + " document.getElementById('input1').value = 'New Value';\n"
106 + " }\n"
107 + " function handler() {\n"
108 + " log(1);\n"
109 + " document.getElementById('input1').dir='rtl';\n"
110 + " }\n"
111 + "</script></head>\n"
112 + "<body onload='test()'>\n"
113 + " <input id='input1' onpropertychange='handler()'>\n"
114 + "</body></html>";
115
116 loadPageVerifyTitle2(html);
117 }
118
119
120
121
122
123
124
125 @Test
126 @Alerts({"false", "true", "a", "a", "b", "b", "b", "c"})
127 public void clonedNodeAttributes() throws Exception {
128 final String html = DOCTYPE_HTML
129 + "<html><body id='a' title='b'><script>\n"
130 + LOG_TITLE_FUNCTION
131 + "var x = document.body.cloneNode(true);\n"
132 + "log(document.body == x);\n"
133 + "log(document.getElementById('a') == document.body);\n"
134 + "log(document.body.id);\n"
135 + "log(x.id);\n"
136 + "log(document.body.title);\n"
137 + "log(x.title);\n"
138 + "x.title = 'c';\n"
139 + "log(document.body.title);\n"
140 + "log(x.title);\n"
141 + "</script></body></html>";
142
143 loadPageVerifyTitle2(html);
144 }
145
146
147
148
149
150
151 @Test
152 @Alerts({"true", "undefined", "undefined"})
153 public void textAndXmlUndefined() throws Exception {
154 final String html = DOCTYPE_HTML
155 + "<html><head></head>\n"
156 + "<body>\n"
157 + " <input type='text' id='textfield1' onfocus='log(1)'>\n"
158 + " <script>\n"
159 + LOG_TITLE_FUNCTION
160 + " var node = document.getElementById('textfield1');\n"
161 + " log(node.attributes[0].nodeName.length > 0);\n"
162 + " log(node.attributes[0].text);\n"
163 + " log(node.attributes[0].xml);\n"
164 + " </script>\n"
165 + "</body></html>";
166
167 loadPageVerifyTitle2(html);
168 }
169
170
171
172
173 @Test
174 @Alerts("something")
175 @BuggyWebDriver(FF = "",
176 FF_ESR = "")
177 @HtmlUnitNYI(CHROME = "initialsomething",
178 EDGE = "initialsomething",
179 FF = "initialsomething",
180 FF_ESR = "initialsomething")
181
182
183 public void contentEditable() throws Exception {
184 final String html = DOCTYPE_HTML
185 + "<html>\n"
186 + "<body contentEditable><p>initial</p></body>\n"
187 + "</html>";
188
189 final WebDriver driver = loadPage2(html);
190 final WebElement body = driver.findElement(By.xpath("//body"));
191 body.clear();
192 body.sendKeys("something");
193 assertEquals(getExpectedAlerts()[0], body.getText());
194 }
195
196
197
198
199 @Test
200
201 @Alerts("down: 16,0 down: 49,0 press: 33,33 up: 49,0 up: 16,0"
202 + " down: 16,0 down: 220,0 press: 124,124 up: 220,0 up: 16,0")
203
204 @BuggyWebDriver(FF_ESR = "down: 49,0 press: 33,33 up: 49,0 down: 220,0 press: 124,124 up: 220,0",
205 FF = "down: 49,0 press: 33,33 up: 49,0 down: 220,0 press: 124,124 up: 220,0")
206 public void shiftKeys() throws Exception {
207 final String html = DOCTYPE_HTML
208 + "<html><head><script>\n"
209 + " function appendMessage(message) {\n"
210 + " document.getElementById('result').innerHTML += message + ' ';\n"
211 + " }\n"
212 + "</script></head>\n"
213 + "<body >\n"
214 + " <input id='input1' onkeyup=\"appendMessage('up: ' + event.keyCode + ',' + event.charCode)\" "
215 + "onkeypress=\"appendMessage('press: ' + event.keyCode + ',' + event.charCode)\" "
216 + "onkeydown=\"appendMessage('down: ' + event.keyCode + ',' + event.charCode)\"><br>\n"
217 + "<p id='result'></p>\n"
218 + "</body></html>";
219
220 final WebDriver driver = loadPage2(html);
221 final WebElement input = driver.findElement(By.id("input1"));
222 final WebElement result = driver.findElement(By.id("result"));
223 input.sendKeys("!|");
224 assertEquals(getExpectedAlerts()[0], result.getText());
225 }
226
227
228
229
230 @Test
231 @Alerts(DEFAULT = "[object HTMLInputElement] [object HTMLBodyElement]",
232 CHROME = "[object HTMLInputElement] onblur onfocusout [object HTMLBodyElement]",
233 EDGE = "[object HTMLInputElement] onblur onfocusout [object HTMLBodyElement]")
234 public void removeActiveElement() throws Exception {
235 final String html = DOCTYPE_HTML
236 + "<html>\n"
237 + "<head>\n"
238 + "<script>\n"
239 + "function test() {\n"
240 + " var elem = document.getElementById('text1');\n"
241 + " elem.focus();\n"
242 + " document.title += ' ' + document.activeElement;\n"
243 + " elem.parentNode.removeChild(elem);\n"
244 + " document.title += ' ' + document.activeElement;\n"
245 + "}\n"
246 + "</script>\n"
247 + "</head>\n"
248 + "<body onload='test()'>\n"
249 + "<form name='form1'>\n"
250 + " <input id='text1' onblur='document.title += \" onblur\"' "
251 + "onfocusout='document.title += \" onfocusout\"'>\n"
252 + "</form>\n"
253 + "</body></html>";
254
255 final WebDriver driver = loadPage2(html);
256 assertTitle(driver, getExpectedAlerts()[0]);
257 }
258
259
260
261
262 @Test
263 @Alerts(DEFAULT = "[object HTMLInputElement] [object HTMLBodyElement]",
264 CHROME = "[object HTMLInputElement] onblur1 onfocusout1 [object HTMLBodyElement]",
265 EDGE = "[object HTMLInputElement] onblur1 onfocusout1 [object HTMLBodyElement]")
266 public void removeParentOfActiveElement() throws Exception {
267 final String html = DOCTYPE_HTML
268 + "<html>\n"
269 + "<head>\n"
270 + "<script>\n"
271 + "function test() {\n"
272 + " var elem = document.getElementById('text1');\n"
273 + " elem.focus();\n"
274 + " document.title += ' ' + document.activeElement;\n"
275
276 + " var elem = document.getElementById('parent');\n"
277 + " elem.parentNode.removeChild(elem);\n"
278 + " document.title += ' ' + document.activeElement;\n"
279 + "}\n"
280 + "</script>\n"
281 + "</head>\n"
282 + "<body onload='test()'>\n"
283 + "<form name='form1'>\n"
284 + " <div id='parent'>\n"
285 + " <input id='text1' onblur='document.title += \" onblur1\"' "
286 + "onfocusout='document.title += \" onfocusout1\"'>\n"
287 + " <input id='text2' onblur='document.title += \" onblur2\"' "
288 + "onfocusout='document.title += \" onfocusout2\"'>\n"
289 + " </div>\n"
290 + "</form>\n"
291 + "</body></html>";
292
293 final WebDriver driver = loadPage2(html);
294 assertTitle(driver, getExpectedAlerts()[0]);
295 }
296
297
298
299
300
301
302 @Test
303 @Alerts({"before appendChild;after appendChild;image onload;after removeChild;", "2"})
304 public void addRemove() throws Exception {
305 try (InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img")) {
306 final byte[] directBytes = IOUtils.toByteArray(is);
307 final URL urlImage = new URL(URL_FIRST, "img.jpg");
308 getMockWebConnection().setResponse(urlImage, directBytes, 200, "ok", "image/jpg", Collections.emptyList());
309 }
310
311 final String html = DOCTYPE_HTML
312 + "<html>\n"
313 + "<head>\n"
314 + "<script>\n"
315 + "function test() {\n"
316 + " var elem = document.createElement('img');\n"
317 + " elem.setAttribute('alt', '');\n"
318 + " elem.setAttribute('src', 'img.jpg');\n"
319 + " elem.style.display = 'none';\n"
320 + " elem.onload = function() {\n"
321 + " document.title += 'image onload;';"
322 + " document.body.removeChild(elem);\n"
323 + " document.title += 'after removeChild;';"
324 + " }\n"
325 + " document.title += 'before appendChild;';"
326 + " document.body.appendChild(elem);\n"
327 + " document.title += 'after appendChild;';"
328 + "}\n"
329 + "</script>\n"
330 + "</head>\n"
331 + "<body onload='test()'>\n"
332 + "</body></html>";
333
334 final int count = getMockWebConnection().getRequestCount();
335 final WebDriver driver = getWebDriver();
336 if (driver instanceof HtmlUnitDriver) {
337 ((HtmlUnitDriver) driver).setDownloadImages(true);
338 }
339 loadPage2(html);
340
341 assertTitle(driver, getExpectedAlerts()[0]);
342 assertEquals(Integer.parseInt(getExpectedAlerts()[1]), getMockWebConnection().getRequestCount() - count);
343 }
344
345
346
347
348 @Test
349 public void keyPressEventWhenPreventsDefault() throws Exception {
350 final String html = DOCTYPE_HTML
351 + "<html>\n"
352 + "<body>\n"
353 + " <input id='suppress' onkeydown='event.preventDefault()' onkeypress='alert(\"press\")'>\n"
354 + "</body></html>";
355
356 final WebDriver driver = loadPage2(html);
357 driver.findElement(By.id("suppress")).sendKeys("s");
358 verifyAlerts(driver, getExpectedAlerts());
359 }
360
361
362
363
364 @Test
365 @Alerts("press")
366 public void keyUpEventWhenPreventsDefault() throws Exception {
367 final String html = DOCTYPE_HTML
368 + "<html>\n"
369 + "<body>\n"
370 + " <input id='suppress' onkeydown='event.preventDefault()' onkeyup='alert(\"press\")'>\n"
371 + "</body></html>";
372
373 final WebDriver driver = loadPage2(html);
374 driver.findElement(By.id("suppress")).sendKeys("s");
375 verifyAlerts(driver, getExpectedAlerts());
376 }
377
378
379
380
381 @Test
382 @Alerts({"[object HTMLHtmlElement]", "null"})
383 public void detach() throws Exception {
384 final String html = DOCTYPE_HTML
385 + "<html><head><script>\n"
386 + LOG_TITLE_FUNCTION
387 + " function test() {\n"
388 + " var xhr = new XMLHttpRequest();\n"
389 + " xhr.onload = function () {\n"
390 + " var xml = xhr.responseXML;\n"
391 + " log(xml.documentElement);\n"
392 + " xml.removeChild(xml.firstChild);\n"
393 + " log(xml.documentElement);\n"
394 + " }\n"
395 + " xhr.open('GET', '" + URL_SECOND + "');\n"
396 + " xhr.send();\n"
397 + " }\n"
398 + "</script></head><body onload='test()'>\n"
399 + "</body></html>\n";
400
401 final String xml = "<html xmlns=\"http://www.w3.org/1999/xhtml\"></html>";
402 getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.APPLICATION_XML);
403 loadPage2(html);
404 verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
405 }
406
407
408
409
410 @Test
411 @Alerts("Hello-world")
412 public void typeAtEndOfEditableDiv() throws Exception {
413 final String html = DOCTYPE_HTML
414 + "<html><head><script>\n"
415 + " function test() {\n"
416 + " alert(document.getElementById('myInput').value);\n"
417 + " }\n"
418 + "</script></head>\n"
419 + "<body>\n"
420 + " <input id='myButton' type='button' onclick='test()'>\n"
421 + " <div id='myInput' contenteditable='true'>Hello</div>\n"
422 + "</body></html>";
423
424 final WebDriver driver = loadPage2(html);
425 final WebElement div = driver.findElement(By.id("myInput"));
426 div.sendKeys("-world");
427
428 assertEquals(getExpectedAlerts()[0], div.getText());
429 }
430
431
432
433
434 @Test
435 @Alerts("Hello-world")
436 @BuggyWebDriver(FF = "Hello\n-world",
437 FF_ESR = "Hello\n-world")
438 public void typeAtEndOfEditableDivWithParagraphInside() throws Exception {
439 final String html = DOCTYPE_HTML
440 + "<html><head><script>\n"
441 + " function test() {\n"
442 + " alert(document.getElementById('myInput').value);\n"
443 + " }\n"
444 + "</script></head>\n"
445 + "<body>\n"
446 + " <input id='myButton' type='button' onclick='test()'>\n"
447 + " <div id='myInput' contenteditable='true'><p>Hello</p></div>\n"
448 + "</body></html>";
449
450 final WebDriver driver = loadPage2(html);
451 final WebElement div = driver.findElement(By.id("myInput"));
452 div.sendKeys("-world");
453
454 assertEquals(getExpectedAlerts()[0], div.getText());
455 }
456
457
458
459
460
461 @Test
462 @Alerts({"bottom", "bottom", "bottom", "", "bottom", "bottom"})
463 public void setGetStyle() throws Exception {
464 final String html = DOCTYPE_HTML
465 + "<html>\n"
466 + "<head>\n"
467 + "<script>\n"
468 + LOG_TITLE_FUNCTION
469 + " function test() {\n"
470 + " var d = document.createElement('div');\n"
471 + " d.style.verticalAlign = 'bottom';\n"
472 + " log(d.style.getPropertyValue('vertical-align'));\n"
473
474 + " d = document.getElementById('style-already-set');\n"
475 + " log(d.style.getPropertyValue('vertical-align'));\n"
476 + " document.body.removeChild(d);\n"
477 + " log(d.style.getPropertyValue('vertical-align'));\n"
478
479 + " d = document.getElementById('style-unset');\n"
480 + " log(d.style.getPropertyValue('vertical-align'));\n"
481 + " d.style.verticalAlign = 'bottom';\n"
482 + " log(d.style.getPropertyValue('vertical-align'));\n"
483 + " document.body.removeChild(d);\n"
484 + " log(d.style.getPropertyValue('vertical-align'));\n"
485
486 + " }\n"
487 + "</script>\n"
488 + "</head>\n"
489 + "<body onload='test()'>\n"
490 + " <div id='style-already-set' style='vertical-align: bottom'></div>\n"
491 + " <div id='style-unset'></div>"
492 + "</body>\n"
493 + "</html>";
494
495 loadPageVerifyTitle2(html);
496 }
497 }