Java tutorial
/* * Copyright (c) 2002-2017 Gargoyle Software Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gargoylesoftware.htmlunit.javascript.host.dom; import static com.gargoylesoftware.htmlunit.javascript.host.xml.XMLDocumentTest.LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION; import static com.gargoylesoftware.htmlunit.javascript.host.xml.XMLDocumentTest.SERIALIZE_XML_DOCUMENT_TO_STRING_FUNCTION; import static com.gargoylesoftware.htmlunit.javascript.host.xml.XMLDocumentTest.callLoadXMLDocumentFromString; import static com.gargoylesoftware.htmlunit.javascript.host.xml.XMLDocumentTest.callSerializeXMLDocumentToString; import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import com.gargoylesoftware.htmlunit.BrowserRunner; import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; import com.gargoylesoftware.htmlunit.WebDriverTestCase; import com.gargoylesoftware.htmlunit.html.HtmlPageTest; /** * Tests for {@link Node}. * * @author Brad Clarke * @author <a href="mailto:george@murnock.com">George Murnock</a> * @author Bruce Faulkner * @author Marc Guillemot * @author Ahmed Ashour * @author Frank Danek * @author Ronald Brill */ @RunWith(BrowserRunner.class) public class NodeTest extends WebDriverTestCase { /** * @throws Exception on test failure */ @Test @Alerts({ "[object HTMLSpanElement]", "[object Text]", "null" }) public void lastChild() throws Exception { final String html = "<html><head>\n" + "<script>\n" + "function doTest() {\n" + " alert(document.getElementById('myNode').lastChild);\n" + " alert(document.getElementById('onlyTextNode').lastChild);\n" + " alert(document.getElementById('emptyNode').lastChild);\n" + "}\n" + "</script>\n" + "</head>\n" + "<body onload='doTest()'>\n" + " <div id='myNode'>hello world<span>Child Node</span></div>\n" + " <div id='onlyTextNode'>hello</div>\n" + " <div id='emptyNode'></div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception on test failure */ @Test @Alerts("true") public void hasChildNodes_true() throws Exception { final String html = "<html><head><title>test_hasChildNodes</title>\n" + "<script>\n" + "function doTest() {\n" + " alert(document.getElementById('myNode').hasChildNodes());\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "<p id='myNode'>hello world<span>Child Node</span></p>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception on test failure */ @Test @Alerts("false") public void hasChildNodes_false() throws Exception { final String html = "<html><head><title>test_hasChildNodes</title>\n" + "<script>\n" + "function doTest() {\n" + " alert(document.getElementById('myNode').hasChildNodes());\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "<p id='myNode'></p>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts(DEFAULT = { "4", "function", "3" }, IE = { "4", "undefined", "exception" }) public void remove() throws Exception { final String html = "<html><body>\n" + "<div id='div1'></div>\n" + "<script>\n" + "var div1 = document.getElementById('div1');\n" + "try {\n" + " alert(document.body.childNodes.length);\n" + " alert(typeof div1.remove);\n" + " div1.remove();\n" + " alert(document.body.childNodes.length);\n" + "}\n" + "catch (e) { alert('exception'); }\n" + "</script></body></html>"; loadPageWithAlerts2(html); } /** * Regression test for removeChild. * @throws Exception if the test fails */ @Test @Alerts({ "true", "true" }) public void removeChild() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + "function doTest() {\n" + " var form = document.forms['form1'];\n" + " var div = form.firstChild;\n" + " var removedDiv = form.removeChild(div);\n" + " alert(div==removedDiv);\n" + " alert(form.firstChild==null);\n" + "}\n" + "</script></head><body onload='doTest()'>\n" + "<form name='form1'><div id='formChild'/></form>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts("exception") public void removeChildSibling() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + "function doTest() {\n" + " var div1 = document.getElementById('div1');\n" + " var div2 = document.getElementById('div2');\n" + " try {\n" + " div1.removeChild(div2);\n" + " } catch(e) { alert('exception') }\n" + "}\n" + "</script></head>\n" + "<body onload='doTest()'>\n" + " <div id='div1'></div>\n" + " <div id='div2'></div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Regression test for replaceChild. * @throws Exception if the test fails */ @Test @Alerts({ "true", "true", "true" }) public void replaceChild_Normal() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + "function doTest() {\n" + " var form = document.forms['form1'];\n" + " var div1 = form.firstChild;\n" + " var div2 = document.getElementById('newChild');\n" + " var removedDiv = form.replaceChild(div2,div1);\n" + " alert(div1==removedDiv);\n" + " alert(form.firstChild==div2);\n" + " var newDiv = document.createElement('div');\n" + " form.replaceChild(newDiv, div2);\n" + " alert(form.firstChild==newDiv);\n" + "}\n" + "</script></head><body onload='doTest()'>\n" + "<form name='form1'><div id='formChild'/></form>\n" + "</body><div id='newChild'/></html>"; loadPageWithAlerts2(html); } /** * The common browsers always return node names in uppercase. Test this. * @throws Exception on test failure */ @Test @Alerts("DIV") public void nodeNameIsUppercase() throws Exception { final String html = "<html><head>\n" + "<script>\n" + "function doTest() {\n" + " alert(document.getElementById('myNode').nodeName);\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "<div id='myNode'>hello world<span>Child Node</span></div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception on test failure */ @Test @Alerts({ "2", "SPAN", "2", "#text", "H1", "H2" }) public void getChildNodes() throws Exception { final String html = "<html><head>\n" + "<script>\n" + "function doTest() {\n" + " var aNode = document.getElementById('myNode');\n" + " alert(aNode.childNodes.length);\n" + " alert(aNode.childNodes[0].nodeName);\n" + " alert(aNode.childNodes[0].childNodes.length);\n" + " alert(aNode.childNodes[0].childNodes[0].nodeName);\n" + " alert(aNode.childNodes[0].childNodes[1].nodeName);\n" + " alert(aNode.childNodes[1].nodeName);\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "<div id='myNode'><span>Child Node 1-A" + "<h1>Child Node 1-B</h1></span>" + "<h2>Child Node 2-A</h2></div>" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception on test failure */ @Test @Alerts({ "nb nodes: 2", "8", "1" }) public void childNodes_Comments() throws Exception { final String html = "<html><head><title>test</title>\n" + "</head>\n" + "<body><!-- comment --><script>\n" + "var nodes = document.body.childNodes;\n" + "alert('nb nodes: ' + nodes.length);\n" + "for (var i = 0; i < nodes.length; i++)\n" + " alert(nodes[i].nodeType);\n" + "</script></body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception on test failure */ @Test @Alerts({ "length: 5", "tempNode.name: undefined", "tempNode.name: input1", "tempNode.name: undefined", "tempNode.name: input2", "tempNode.name: undefined" }) public void getChildNodesProperties() throws Exception { final String html = "<html><head><title>test_getChildNodes</title>\n" + "<script>\n" + "function doTest() {\n" + " var testForm = document.getElementById('testForm');\n" + " var childNodes = testForm.childNodes;\n" + " var length = childNodes.length;\n" + " alert('length: ' + length);\n" + " for (var i = 0; i < length; i++) {\n" + " var tempNode = childNodes.item(i);\n" + " alert('tempNode.name: ' + tempNode.name);\n" + " }\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "<form name='testForm' id='testForm'>foo\n" // some text, because IE doesn't see "\n" as a text node here + "<input type='hidden' name='input1' value='1'>\n" + "<input type='hidden' name='input2' value='2'>\n" + "</form>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * The common browsers always return node names in uppercase. Test this. * @throws Exception on test failure */ @Test @Alerts({ "document: 9", "document.body: 1", "body child 1: 3", "body child 2: 8" }) public void nodeType() throws Exception { final String html = "<html><head><title>test</title>\n" + "<script>\n" + "function doTest() {\n" + " alert('document: ' + document.nodeType);\n" + " alert('document.body: ' + document.body.nodeType);\n" + " alert('body child 1: ' + document.body.childNodes[0].nodeType);\n" + " alert('body child 2: ' + document.body.childNodes[1].nodeType);\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "some text<!-- some comment -->\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Test for bug 1716129. * @throws Exception on test failure */ @Test @Alerts("exception") public void attachEvent() throws Exception { final String html = "<html><head>\n" + "<title>First</title>\n" + "<script>\n" + "function test() {\n" + " var oField = document.getElementById('div1');\n" + " try {\n" + " oField.attachEvent('onclick', foo1);\n" + " oField.attachEvent('onclick', foo2);\n" + " } catch(e) { alert('exception') }\n" + "}\n" + "function foo1() {alert('in foo1');}\n" + "function foo2() {alert('in foo2');}\n" + "</script></head><body onload='test()'>\n" + "<div id='div1'>bla</div>\n" + "</body></html>"; final WebDriver driver = loadPage2(html); verifyAlerts(driver, getExpectedAlerts()); driver.findElement(By.id("div1")).click(); } /** * @throws Exception if the test fails */ @Test @Alerts(DEFAULT = { "true", "false" }, FF = { "isSameNode not supported" }) public void isSameNode() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var d1 = document.getElementById('div1');\n" + " var d2 = document.getElementById('div2');\n" + " try {\n" + " alert(d1.isSameNode(d1));\n" + " alert(d1.isSameNode(d2));\n" + " } catch(e) {\n" + " alert('isSameNode not supported');\n" + " }\n" + " }\n" + "</script></head><body onload='test()'>\n" + "<div id='div1'/>\n" + "<div id='div2'/>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Test element.appendChild: If the parent has a null parentNode, * IE creates a DocumentFragment be the parent's parentNode. * * @throws Exception if the test fails */ @Test @Alerts({ "null", "null" }) public void appendChild_parentNode() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var div1 = document.createElement('div');\n" + " var div2 = document.createElement('div');\n" + " alert(div1.parentNode);\n" + " div1.appendChild(div2);\n" + " if(div1.parentNode)\n" + " alert(div1.parentNode.nodeName);\n" + " else\n" + " alert(div1.parentNode);\n" + " }\n" + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * The HTML node can't be inserted anywhere else! * @throws Exception if the test fails */ @Test @Alerts({ "1", "exception", "1", "exception", "1", "exception", "1" }) public void append_insert_html_node() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + "function test() {\n" + " var htmlNode = document.documentElement;\n" + " var body = document.body;\n" + " alert(body.childNodes.length);\n" + " try { body.appendChild(htmlNode); } catch(e) { alert('exception'); }\n" + " alert(body.childNodes.length);\n" + " try { body.insertBefore(htmlNode, body.firstChild); } catch(e) { alert('exception'); }\n" + " alert(body.childNodes.length);\n" + " try { body.replaceChild(htmlNode, body.firstChild); } catch(e) { alert('exception'); }\n" + " alert(body.childNodes.length);\n" + "}\n" + "</script></head><body onload='test()'><span>hi</span></body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts("2") public void appendChild_of_DocumentFragment() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var fragment = document.createDocumentFragment();\n" + " var div1 = document.createElement('div');\n" + " div1.id = 'div1';\n" + " var div2 = document.createElement('div');\n" + " div2.id = 'div2';\n" + " fragment.appendChild(div1);\n" + " fragment.appendChild(div2);\n" + " var div = document.getElementById('myDiv');\n" + " div.appendChild(fragment);\n" + " alert(div.childNodes.length);\n" + " }\n" + "</script></head><body onload='test()'>\n" + "<div id='myDiv'></div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts({ "3", "3", "3", "3", "3", "3", "3", "3" }) public void nodePrototype() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " try {\n" + " alert(document.body.TEXT_NODE);\n" + " alert(Node.TEXT_NODE);\n" + " document.body.TEXT_NODE = 123;\n" + " alert(document.body.TEXT_NODE);\n" + " alert(Node.TEXT_NODE);\n" + " Node.TEXT_NODE = 456;\n" + " alert(document.body.TEXT_NODE);\n" + " alert(Node.TEXT_NODE);\n" + " delete Node.TEXT_NODE;\n" + " delete document.body.TEXT_NODE;\n" + " alert(document.body.TEXT_NODE);\n" + " alert(Node.TEXT_NODE);\n" + " } catch(e) {\n" + " alert('not supported');\n" + " }\n" + " }\n" + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts({ "<div id=\"myDiv2\"></div><div id=\"myDiv3\"></div>", "myDiv2", "<div>one</div><div>two</div><div id=\"myDiv3\"></div>" }) public void replaceChild() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " try {\n" + " var element = document.getElementById('myDiv2');\n" + " var range = element.ownerDocument.createRange();\n" + " range.setStartAfter(element);\n" + " var fragment = range.createContextualFragment('<div>one</div><div>two</div>');\n" + " var parent = element.parentNode;\n" + " alert(parent.innerHTML);\n" + " alert(parent.replaceChild(fragment, parent.firstChild).id);\n" + " alert(parent.innerHTML);\n" + " } catch(e) {\n" + " alert('exception thrown');\n" + " }\n" + " }\n" + "</script></head><body onload='test()'>\n" + " <div id='myDiv'><div id='myDiv2'></div><div id='myDiv3'></div></div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts({ "<div id=\"myDiv2\"></div><div id=\"myDiv3\"></div>", "myDiv2", "<div id=\"myDiv3\"></div>" }) public void replaceChild_EmptyDocumentFragment() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var element = document.getElementById('myDiv2');\n" + " try {\n" + " var range = element.ownerDocument.createRange();\n" + " range.setStartAfter(element);\n" + " var fragment = range.createContextualFragment('');\n" + " var parent = element.parentNode;\n" + " alert(parent.innerHTML);\n" + " alert(parent.replaceChild(fragment, parent.firstChild).id);\n" + " alert(parent.innerHTML);\n" + " } catch(e) {\n" + " alert('exception thrown');\n" + " }\n" + " }\n" + "</script></head><body onload='test()'>\n" + " <div id='myDiv'><div id='myDiv2'></div><div id='myDiv3'></div></div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Verifies that listeners are copied only for IE. * @throws Exception if an error occurs */ @Test @Alerts("in click") public void cloneNode_copiesListenerOnlyForIE() throws Exception { final String html = "<html>\n" + " <head>\n" + " <script>\n" + " function go() {\n" + " var node = document.createElement('button');\n" + " var f = function() { alert('in click') };\n" + " if (node.attachEvent)\n" + " node.attachEvent('onclick', f);\n" + " else\n" + " node.addEventListener('click', f, true);\n" + " document.body.appendChild(node);\n" + " node.click();\n" + " var clone = node.cloneNode(true);\n" + " document.body.appendChild(clone);\n" + " clone.click();\n" + " var div = document.createElement('div');\n" + " div.appendChild(node);\n" + " var cloneDiv = div.cloneNode(true);\n" + " document.body.appendChild(cloneDiv);\n" + " cloneDiv.firstChild.click();\n" + " }\n" + " </script>\n" + " </head>\n" + " <body onload='go()'>\n" + " <div id='foo'></div>\n" + " </body>\n" + "</html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts({ "1", "1", "2", "4", "8", "16", "32" }) public void documentPositionConstants() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " try {\n" + " alert(document.body.DOCUMENT_POSITION_DISCONNECTED);\n" + " alert(Node.DOCUMENT_POSITION_DISCONNECTED);\n" + " alert(Node.DOCUMENT_POSITION_PRECEDING);\n" + " alert(Node.DOCUMENT_POSITION_FOLLOWING);\n" + " alert(Node.DOCUMENT_POSITION_CONTAINS);\n" + " alert(Node.DOCUMENT_POSITION_CONTAINED_BY);\n" + " alert(Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);\n" + " } catch(e) {\n" + " alert('not supported');\n" + " }\n" + " }\n" + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts({ "0", "20", "20", "4", "10", "10", "2", "20", "exception" }) public void compareDocumentPosition() throws Exception { final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + " var div1 = document.getElementById('div1');\n" + " var div2 = document.getElementById('div2');\n" + " var div3 = document.getElementById('div3');\n" + " if (!div1.compareDocumentPosition) { alert('compareDocumentPosition not available'); return }\n" + " alert(div1.compareDocumentPosition(div1));\n" + " alert(div1.compareDocumentPosition(div2));\n" + " alert(div1.compareDocumentPosition(div3));\n" + " alert(div1.compareDocumentPosition(div4));\n" + " alert(div2.compareDocumentPosition(div1));\n" + " alert(div3.compareDocumentPosition(div1));\n" + " alert(div4.compareDocumentPosition(div1));\n" + " alert(div2.compareDocumentPosition(div3));\n" + " try {\n" + " alert(div2.compareDocumentPosition({}));\n" + " } catch(e) { alert('exception'); }\n" + "}\n" + "</script></head><body onload='test()'>\n" + "<div id='div1'>\n" + " <div id='div2'>\n" + " <div id='div3'>\n" + " </div>\n" + " </div>\n" + "</div>\n" + "<div id='div4'>\n" + "</div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts({ "0", "16" }) public void compareDocumentPosition2() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var div = document.createElement('div');\n" + " var childDiv = document.createElement('div');\n" + " try {\n" + " alert(div.compareDocumentPosition(childDiv) & Node.DOCUMENT_POSITION_CONTAINED_BY);\n" + " div.appendChild(childDiv);\n" + " alert(div.compareDocumentPosition(childDiv) & Node.DOCUMENT_POSITION_CONTAINED_BY);\n" + " } catch(e) {alert('exception');}\n" + " }\n" + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts("bk") public void prefix() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + "function test() {\n" + " var text = \"<bk:book xmlns:bk='urn:loc.gov:books'></bk:book>\";\n" + " var doc = " + callLoadXMLDocumentFromString("text") + ";\n" + " alert(doc.documentElement.prefix);\n" + "}\n" + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts("<root><![CDATA[abc]]><![CDATA[def]]></root>") public void xml() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var doc = document.implementation.createDocument('', '', null);\n" + " var root = doc.appendChild(doc.createElement('root'));\n" + " var cdata = root.appendChild(doc.createCDATASection('abcdef'));\n" + " cdata.splitText(3);\n" + " alert(" + callSerializeXMLDocumentToString("doc") + ");\n" + " }\n" + SERIALIZE_XML_DOCUMENT_TO_STRING_FUNCTION + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Regression test to verify that insertBefore correctly appends * the new child object when the reference child object is null. * @throws Exception if the test fails */ @Test @Alerts({ "3", "SPAN" }) public void insertBefore_nullRef() throws Exception { insertBefore("aNode.insertBefore(newNode, null);"); } /** * @throws Exception if the test fails */ @Test @Alerts("exception") public void insertBefore_myself() throws Exception { insertBefore("aNode.insertBefore(newNode, newNode);"); } /** * @throws Exception if the test fails */ @Test @Alerts("exception") public void insertBefore_sibling() throws Exception { insertBefore("aNode.insertBefore(newNode, siblingNode);"); } /** * @throws Exception on test failure */ @Test public void insertBefore_undefinedRef() throws Exception { final String html = "<html><head><title>foo</title>\n" + "<script>\n" + "function doTest() {\n" + " try {\n" + " var e = document.createElement('div');\n" + " e.innerHTML='new element';\n" + " document.body.insertBefore(e, undefined);\n" + " } catch(e) {alert('exception');}\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Regression test to verify that insertBefore correctly appends * the new child object when the reference child object is null. * @throws Exception if the test fails */ @Test @Alerts(DEFAULT = "exception", IE = { "3", "SPAN" }) public void insertBefore_noSecondArg() throws Exception { insertBefore("aNode.insertBefore(newNode);"); } /** * @throws Exception if the test fails */ private void insertBefore(final String insertJSLine) throws Exception { final String html = "<html>\n" + "<head>\n" + " <title>test_insertBefore</title>\n" + " <script>\n" + " function doTest() {\n" + " var newNode = document.createElement('span');\n" + " var siblingNode = document.getElementById('sibingNode');\n" + " var aNode = document.getElementById('myNode');\n" + " try {\n" + insertJSLine + " alert(aNode.childNodes.length);\n" + " alert(aNode.childNodes[2].nodeName);\n" + " }\n" + " catch (e) { alert('exception'); }\n" + " }\n" + " </script>\n" + "</head>\n" + "<body onload='doTest()'>\n" + "<div id='myNode'><span>Child Node 1-A</span><h1>Child Node 2-A</h1></div>\n" + "<h2 id='sibingNode'>Sibling</h2>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Regression test to verify that insertBefore correctly appends * the new child object when the reference child object is null. * @throws Exception if the test fails */ @Test @Alerts({ "3", "SPAN" }) public void insertBeforeFragment_nullRef() throws Exception { insertBeforeFragment("aNode.insertBefore(fragment, null);"); } /** * @throws Exception if the test fails */ @Test @Alerts("exception") public void insertBeforeFragment_myself() throws Exception { insertBeforeFragment("aNode.insertBefore(fragment, fragment);"); } /** * @throws Exception if the test fails */ @Test @Alerts("exception") public void insertBeforeFragment_sibling() throws Exception { insertBeforeFragment("aNode.insertBefore(fragment, siblingNode);"); } /** * Regression test to verify that insertBefore correctly appends * the new child object when the reference child object is null. * @throws Exception if the test fails */ @Test @Alerts(DEFAULT = "exception", IE = { "3", "SPAN" }) public void insertBeforeFragment_noSecondArg() throws Exception { insertBeforeFragment("aNode.insertBefore(fragment);"); } /** * @throws Exception if the test fails */ private void insertBeforeFragment(final String insertJSLine) throws Exception { final String html = "<html>\n" + "<head>\n" + " <title>test_insertBefore</title>\n" + " <script>\n" + " function doTest() {\n" + " var fragment = document.createDocumentFragment('span');\n" + " fragment.appendChild(document.createElement('span'));\n" + " var aNode = document.getElementById('myNode');\n" + " try {\n" + insertJSLine + " alert(aNode.childNodes.length);\n" + " alert(aNode.childNodes[2].nodeName);\n" + " }\n" + " catch (e) { alert('exception'); }\n" + " }\n" + " </script>\n" + "</head>\n" + "<body onload='doTest()'>\n" + "<div id='myNode'><h6>Child Node 1-A</h6><h1>Child Node 2-A</h1></div>\n" + "<h2 id='sibingNode'>Sibling</h2>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * Test element.appendChild: If the parent has a null parentNode, * IE creates a DocumentFragment be the parent's parentNode. * * @throws Exception if the test fails */ @Test @Alerts({ "null", "null" }) public void insertBefore_parentNode() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var div1 = document.createElement('div');\n" + " var div2 = document.createElement('div');\n" + " alert(div1.parentNode);\n" + " div1.insertBefore(div2, null);\n" + " if(div1.parentNode)\n" + " alert(div1.parentNode.nodeName);\n" + " else\n" + " alert(div1.parentNode);\n" + " }\n" + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts("[object HTMLTableColElement]") public void insertBefore_inTable() throws Exception { final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + " var table = document.getElementById('myTable');\n" + " var colGroup = table.insertBefore(document.createElement('colgroup'), null);\n" + " alert(colGroup);\n" + "}\n" + "</script></head><body onload='test()'>\n" + " <table id='myTable'></table>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception on test failure */ @Test @Alerts(DEFAULT = "exception", IE = {}) public void insertBefore_newElement() throws Exception { final String html = "<html><head><title>foo</title>\n" + "<script>\n" + "function doTest() {\n" + " try {\n" + " var e = document.createElement('div');\n" + " e.innerHTML='new element';\n" + " document.body.insertBefore(e);\n" + " } catch(e) {alert('exception');}\n" + "}\n" + "</script>\n" + "</head><body onload='doTest()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts(DEFAULT = { "4", "3", "abc", "def", "123456", "true", "0", "2", "123", "456", "1", "true" }, IE = { "4", "3", "abc", "def", "123456", "false", "0", "2", "123", "456", "1", "false" }) public void normalize() throws Exception { final String html = "<html><head><title>foo</title><script>\n" + " function test() {\n" + " var doc = document.implementation.createDocument('', '', null);\n" + " var root = doc.appendChild(doc.createElement('root'));\n" + " var cdata = root.appendChild(doc.createCDATASection('abcdef'));\n" + " cdata.splitText(3);\n" + " var text = root.appendChild(doc.createTextNode('123456'));\n" + " text.splitText(3);\n" + " alert(root.childNodes.length);\n" + " root.normalize();\n" + " alert(root.childNodes.length);\n" + " alert(root.childNodes.item(0).data);\n" + " alert(root.childNodes.item(1).data);\n" + " alert(root.childNodes.item(2).data);\n" + " alert(root.childNodes.item(2) == text);\n" + "\n" + " var body = document.body;\n" + " alert(body.childNodes.length);\n" + " text = body.appendChild(document.createTextNode('123456'));\n" + " text.splitText(3);\n" + " alert(body.childNodes.length);\n" + " alert(body.childNodes.item(0).nodeValue);\n" + " alert(body.childNodes.item(1).nodeValue);\n" + " body.normalize();\n" + " alert(body.childNodes.length);\n" + " alert(body.childNodes.item(0) == text);\n" + " }\n" + "</script></head><body onload='test()'></body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts(DEFAULT = { "[object Element]", "[object HTMLHtmlElement]" }, IE = { "undefined", "[object HTMLHtmlElement]" }) public void parentElement() throws Exception { final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + "<html><head><title>foo</title><script>\n" + "function test() {\n" + " var text = '<hello>hi</hello>';\n" + " var doc = " + callLoadXMLDocumentFromString("text") + ";\n" + " alert(doc.documentElement.firstChild.parentElement);\n" + " alert(document.body.parentElement);\n" + "}\n" + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION + "</script></head><body onload='test()'>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts(DEFAULT = { "hi", "undefined", "abcd", "undefined" }, IE = { "hi", "null", "abcd", "null" }) public void attributes() throws Exception { final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + "<html><head><title>foo</title><script>\n" + "function test() {\n" + " var text = '<hello>hi</hello>';\n" + " var doc = " + callLoadXMLDocumentFromString("text") + ";\n" + " var node = doc.documentElement.firstChild;\n" + " alert(node.nodeValue);\n" + " alert(node.attributes);\n" + "\n" + " node = document.getElementById('myId').firstChild;\n" + " alert(node.nodeValue);\n" + " alert(node.attributes);\n" + "}\n" + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION + "</script></head><body onload='test()'>\n" + " <div id='myId'>abcd</div>\n" + "</body></html>"; loadPageWithAlerts2(html); } /** * @throws Exception if an error occurs */ @Test @Alerts({ "true", "true" }) public void addEventListener() throws Exception { final String html = "<html>\n" + " <head>\n" + " <script>\n" + " function test() {\n" + " var node = document.createElement('button');\n" + " alert(node.addEventListener !== undefined);\n" + " alert(node.removeEventListener !== undefined);\n" + " }\n" + " </script>\n" + " </head>\n" + " <body onload='test()'>\n" + " </body>\n" + "</html>"; loadPageWithAlerts2(html); } /** * @throws Exception if the test fails */ @Test @Alerts("exception") public void event() throws Exception { final String firstHtml = "<html>\n" + "<head><title>First Page</title>\n" + "<script>\n" + " function test() {\n" + " var iframe = document.createElement('iframe');\n" + " document.body.appendChild(iframe);\n" + " iframe.contentWindow.location.replace('" + URL_SECOND + "');\n" + "}\n" + "</script>\n" + "</head>\n" + "<body onload='test()'>\n" + " <input type='button' id='myInput' value='Test me'>\n" + " <div id='myDiv'></div>\n" + "</body>\n" + "</html>"; final String secondHtml = "<html>\n" + " <head>\n" + " <script>\n" + " var handler = function() {\n" + " alert(parent.event);\n" + " parent.document.getElementById('myDiv').style.display = 'none';\n" + " alert(parent.event);\n" + " }\n" + " function test() {\n" + " try {\n" + " parent.document.body.attachEvent('onclick', handler);\n" + " } catch(e) { alert('exception') }\n" + " }\n" + " </script>\n" + " </head>\n" + " <body onload='test()'>\n" + " </body>\n" + "</html>"; getMockWebConnection().setResponse(URL_SECOND, secondHtml); final WebDriver driver = loadPage2(firstHtml); verifyAlerts(driver, getExpectedAlerts()); driver.findElement(By.id("myInput")).click(); } /** * Verifies that attributes belonging to cloned nodes are available via JavaScript. * http://sourceforge.net/p/htmlunit/bugs/659/ * @throws Exception if an error occurs */ @Test @Alerts("id=bar") public void cloneAttributesAvailable() throws Exception { final String html = "<html>\n" + " <head>\n" + " <script>\n" + " function go() {\n" + " var node = document.getElementById('foo');\n" + " var clone = node.cloneNode(true);\n" + " clone.id = 'bar';\n" + " node.appendChild(clone);\n" + " alert(clone.attributes['id'].nodeName + '=' + clone.attributes['id'].nodeValue);\n" + " }\n" + " </script>\n" + " </head>\n" + " <body onload='go()'>\n" + " <div id='foo'></div>\n" + " </body>\n" + "</html>"; final WebDriver driver = loadPageWithAlerts2(html); final WebElement element = driver.findElement(By.id("bar")); final String value = element.getAttribute("id"); assertEquals("bar", value); } /** * @throws Exception if an error occurs */ @Test @Alerts("Hello") public void setTextContent() throws Exception { final String html = "<html>\n" + " <head>\n" + " <script>\n" + " function test() {\n" + " var foo = document.getElementById('foo');\n" + " foo.textContent = 'Hello';\n" + " if (foo.firstChild) {\n" + " alert(foo.firstChild.wholeText);\n" + " }\n" + " }\n" + " </script>\n" + " </head>\n" + " <body onload='test()'>\n" + " <span id='foo'></span>\n" + " </body>\n" + "</html>"; loadPageWithAlerts2(html); } /** * @throws Exception if an error occurs */ @Test @Alerts("null") public void cloneParent() throws Exception { final String html = "<!DOCTYPE><html>\n" + " <head>\n" + " <script>\n" + " function test() {\n" + " var foo = document.getElementById('foo');\n" + " var clone = foo.cloneNode(true);\n" + " alert(clone.parentNode);\n" + " if (clone.parentNode) {\n" + " alert(clone.parentNode.URL);\n" + " alert(clone.parentNode.nodeType);\n" + " }\n" + " }\n" + " </script>\n" + " </head>\n" + " <body onload='test()'>\n" + " <span id='foo'></span>\n" + " </body>\n" + "</html>"; loadPageWithAlerts2(html); } }