1 var test = require("tape")
3 module.exports = testDocument
5 function testDocument(document) {
6 var cleanup = require('./cleanup')(document)
7 var Event = require('../event');
9 test("document is a Document", function (assert) {
10 assert.equal(typeof document.createTextNode, "function")
11 assert.equal(typeof document.createElement, "function")
12 assert.equal(typeof document.createDocumentFragment, "function")
17 test("document has a head property", function(assert) {
18 assert.equal(document.head.tagName, "HEAD")
22 test("document has nodeType 9", function (assert) {
23 assert.equal(document.nodeType, 9)
27 test("can do stuff", function (assert) {
28 var div = document.createElement("div")
29 div.className = "foo bar"
31 var span = document.createElement("span")
33 span.textContent = "Hello! <&>"
35 var html = String(div.outerHTML || div)
37 assert.equal(html, "<div class=\"foo bar\">" +
38 "<span>Hello! <&></span></div>")
44 test("can createDocumentFragment", function (assert) {
45 var frag = document.createDocumentFragment()
47 assert.equal(frag.nodeType, 11)
49 var h1 = document.createElement("h1")
50 var h2 = document.createElement("h2")
52 assert.equal(h1.nodeType, 1)
53 assert.equal(h1.nodeType, 1)
56 assert.equal(fragString(frag), "<h1></h1>")
59 assert.equal(fragString(frag), "<h1></h1><h2></h2>")
62 assert.equal(fragString(frag), "<h2></h2>")
64 frag.replaceChild(h1, h2)
65 assert.equal(fragString(frag), "<h1></h1>")
71 test("can getElementById", function (assert) {
73 function append_div(id, parent) {
74 var div = document.createElement("div")
76 parent.appendChild(div)
80 var div1 = append_div(1, document.body)
81 var div2 = append_div(2, document.body)
82 var div3 = append_div(3, document.body)
84 var div11 = append_div(11, div1)
85 var div12 = append_div(12, div1)
86 var div21 = append_div(21, div2)
87 var div22 = append_div(22, div2)
88 var div221 = append_div(221, div22)
89 var div222 = append_div(222, div22)
91 assert.equal(document.getElementById(1), div1)
92 assert.equal(document.getElementById("2"), div2)
93 assert.equal(document.getElementById(3), div3)
94 assert.equal(document.getElementById(11), div11)
95 assert.equal(document.getElementById(12), div12)
96 assert.equal(document.getElementById(21), div21)
97 assert.equal(document.getElementById(22), div22)
98 assert.equal(document.getElementById(221), div221)
99 assert.equal(document.getElementById(222), div222)
105 test("can getElementsByClassName for a single class", function(assert) {
106 function append_div(className, parent) {
107 var div = document.createElement("div")
108 div.className = className
109 parent.appendChild(div)
113 function assertSingleMatch(className, expectedElement) {
114 var result = document.getElementsByClassName(className)
115 assert.equal(result.length, 1)
116 assert.equal(result[0], expectedElement)
119 var divA = append_div("A", document.body)
120 var divB = append_div("B", document.body)
121 var divC = append_div("C", document.body)
123 var divA1 = append_div("A1", divA)
124 var divA2 = append_div("A2", divA)
125 var divB1 = append_div("B1", divB)
126 var divB2 = append_div("B2", divB)
127 var divB2a = append_div("B2a", divB2)
128 var divB2b = append_div("B2b", divB2)
130 assertSingleMatch("A", divA)
131 assertSingleMatch("B", divB)
132 assertSingleMatch("C", divC)
133 assertSingleMatch("A1", divA1)
134 assertSingleMatch("A2", divA2)
135 assertSingleMatch("B1", divB1)
136 assertSingleMatch("B2", divB2)
137 assertSingleMatch("B2a", divB2a)
138 assertSingleMatch("B2b", divB2b)
144 test("can getElementsByClassName for many elements", function (assert) {
145 function h(className) {
146 var div = document.createElement("div")
147 div.className = className
151 document.body.appendChild(h("multi-class-bar"))
152 document.body.appendChild(h("multi-class-bar"))
154 var elems = document.getElementsByClassName("multi-class-bar")
155 assert.equal(elems.length, 2)
161 test("can getElementsByClassName for many classes", function(assert) {
162 function append_div(classNames, parent) {
163 var div = document.createElement("div")
164 div.className = classNames
165 parent.appendChild(div)
169 function assertMatch(classNames, expectedElements) {
170 var result = document.getElementsByClassName(classNames)
171 assert.equal(result.length, expectedElements.length)
172 for (var i = 0; i < expectedElements.length; i++) {
173 assert.notEqual(expectedElements.indexOf(result[i]), -1)
177 var divXYZ = append_div("X Y Z", document.body)
178 var divYZ = append_div("Y Z", document.body)
179 var divZX = append_div("Z X", document.body)
181 var divX1X2 = append_div("X1 X2", divXYZ)
182 var divX1X2Y1 = append_div("X1 X2 Y1", divXYZ)
185 assertMatch("X", [divXYZ, divZX])
186 assertMatch("Y Z", [divXYZ, divYZ])
187 assertMatch("X Y Z", [divXYZ])
188 assertMatch("X1 X2", [divX1X2, divX1X2Y1])
194 test("can create/manipulate textnodes", function (assert) {
195 var textnode = document.createTextNode("hello")
197 assert.equal(textnode.nodeType, 3)
198 assert.equal(textnode.data, "hello")
199 assert.equal(typeof textnode.replaceData, "function")
201 textnode.replaceData(0, 7, "nightly")
202 assert.equal(textnode.nodeType, 3)
203 assert.equal(textnode.data, "nightly")
204 assert.equal(typeof textnode.replaceData, "function")
206 textnode.replaceData(1, 1, "ou")
207 assert.equal(textnode.nodeType, 3)
208 assert.equal(textnode.data, "noughtly")
213 test("owner document is set", function (assert) {
214 var textnode = document.createTextNode("hello")
215 var domnode = document.createElement("div")
216 var fragment = document.createDocumentFragment()
218 assert.equal(textnode.ownerDocument, document)
219 assert.equal(domnode.ownerDocument, document)
220 assert.equal(fragment.ownerDocument, document)
225 test("Create namespaced nodes", function (assert) {
226 var svgURI = "http://www.w3.org/2000/svg"
227 var htmlURI = "http://www.w3.org/1999/xhtml"
229 var noNS = document.createElement("div")
230 var svgNS = document.createElementNS(svgURI, "svg")
231 var emptyNS = document.createElementNS("", "div")
232 var nullNS = document.createElementNS(null, "div")
233 var undefNS = document.createElementNS(undefined, "div")
234 var caseNS = document.createElementNS("Oops", "AbC")
235 var htmlNS = document.createElement("div")
237 assert.equal(noNS.tagName, "DIV")
238 assert.equal(noNS.namespaceURI, htmlURI)
239 assert.equal(elemString(noNS), "<div></div>")
241 assert.equal(svgNS.tagName, "svg")
242 assert.equal(svgNS.namespaceURI, svgURI)
243 assert.equal(elemString(svgNS), "<svg></svg>")
245 assert.equal(emptyNS.tagName, "div")
246 assert.equal(emptyNS.namespaceURI, null)
247 assert.equal(elemString(emptyNS), "<div></div>")
249 assert.equal(nullNS.tagName, "div")
250 assert.equal(nullNS.namespaceURI, null)
251 assert.equal(elemString(nullNS), "<div></div>")
253 assert.equal(undefNS.tagName, "div")
254 assert.equal(undefNS.namespaceURI, "undefined")
255 assert.equal(elemString(undefNS), "<div></div>")
257 assert.equal(caseNS.tagName, "AbC")
258 assert.equal(caseNS.namespaceURI, "Oops")
259 assert.equal(elemString(caseNS), "<AbC></AbC>")
261 assert.equal(htmlNS.tagName, "DIV")
262 assert.equal(htmlNS.namespaceURI, htmlURI)
263 assert.equal(elemString(htmlNS), "<div></div>")
268 test("Can insert before", function (assert) {
269 var rootNode = document.createElement("div")
270 var child = document.createElement("div")
271 var newElement = document.createElement("div")
272 rootNode.appendChild(child)
273 var el = rootNode.insertBefore(newElement, child)
274 assert.equal(el, newElement)
275 assert.equal(rootNode.childNodes.length, 2)
276 assert.equal(rootNode.childNodes[0], newElement)
277 assert.equal(rootNode.childNodes[1], child)
282 test("Insert before null appends to end", function (assert) {
283 var rootNode = document.createElement("div")
284 var child = document.createElement("div")
285 var newElement = document.createElement("div")
286 rootNode.appendChild(child)
287 var el = rootNode.insertBefore(newElement, null)
288 assert.equal(el, newElement)
289 assert.equal(rootNode.childNodes.length, 2)
290 assert.equal(rootNode.childNodes[0], child)
291 assert.equal(rootNode.childNodes[1], newElement)
296 test("Node insertions remove node from parent", function (assert) {
297 var parent = document.createElement("div")
298 var c1 = document.createElement("div")
299 var c2 = document.createElement("div")
300 var c3 = document.createElement("div")
301 parent.appendChild(c1)
302 parent.appendChild(c2)
303 parent.appendChild(c3)
305 var rootNode = document.createElement("div")
307 var node1 = rootNode.appendChild(c1)
308 assert.equal(node1, c1)
309 assert.equal(parent.childNodes.length, 2)
310 assert.equal(c1.parentNode, rootNode)
312 var node2 = rootNode.insertBefore(c2, c1)
313 assert.equal(node2, c2)
314 assert.equal(parent.childNodes.length, 1)
315 assert.equal(c2.parentNode, rootNode)
317 var node3 = rootNode.replaceChild(c3, c2)
318 assert.equal(node3, c2)
319 assert.equal(parent.childNodes.length, 0)
320 assert.equal(c3.parentNode, rootNode)
321 assert.equal(c2.parentNode, null)
327 test("input has type=text by default", function (assert) {
328 var elem = document.createElement("input")
329 assert.equal(elem.getAttribute("type"), "text");
330 assert.equal(elemString(elem), "<input type=\"text\" />")
334 test("input type=text can be overridden", function (assert) {
335 var elem = document.createElement("input")
336 elem.setAttribute("type", "hidden")
337 assert.equal(elem.getAttribute("type"), "hidden");
338 assert.equal(elemString(elem), "<input type=\"hidden\" />")
342 test("can set and get attributes", function (assert) {
343 var elem = document.createElement("div")
344 assert.equal(elem.getAttribute("foo"), null)
345 assert.equal(elemString(elem), "<div></div>")
346 assert.notOk(elem.hasAttribute('foo'))
348 elem.setAttribute("foo", "bar")
349 assert.equal(elem.getAttribute("foo"), "bar")
350 assert.equal(elemString(elem), "<div foo=\"bar\"></div>")
351 assert.ok(elem.hasAttribute('foo'))
353 elem.removeAttribute("foo")
354 assert.equal(elem.getAttribute("foo"), null)
355 assert.equal(elemString(elem), "<div></div>")
356 assert.notOk(elem.hasAttribute('foo'))
361 test("can set and set style properties", function(assert) {
362 var elem = document.createElement("div")
363 assert.equal(elemString(elem), "<div></div>")
365 elem.style.color = "red";
366 assert.equal(elem.style.color, "red")
367 assert.equal(elemString(elem), "<div style=\"color:red;\"></div>")
369 elem.style.background = "blue";
370 assert.equal(elem.style.color, "red")
371 assert.equal(elem.style.background, "blue")
372 assert.equal(elemString(elem),
373 "<div style=\"color:red;background:blue;\"></div>")
378 test("can set and get namespaced attributes", function(assert) {
379 var elem = document.createElement("div")
381 var ns = "http://ns.com/my"
382 assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
383 elem.setAttributeNS(ns, "myns:myattr", "the value")
384 assert.equal(elem.getAttributeNS(ns, "myattr"), "the value")
385 assert.equal(elemString(elem), '<div myns:myattr="the value"></div>')
386 elem.removeAttributeNS(ns, "myattr")
387 assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
389 // Should work much like get/setAttribute when namespace is null.
390 assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
391 assert.equal(elem.getAttribute("foo"), null)
392 elem.setAttributeNS(null, "foo", "bar")
393 assert.equal(elem.getAttributeNS(null, "foo"), "bar")
394 assert.equal(elem.getAttribute("foo"), "bar")
395 elem.removeAttributeNS(null, "foo")
396 assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
397 assert.equal(elem.getAttribute("foo"), null)
401 test("can getElementsByTagName", function(assert) {
402 var parent = document.createElement("div")
403 var child1 = document.createElement("span")
404 var child2 = document.createElement("span")
409 child1.appendChild(child2)
410 parent.appendChild(child1)
411 document.body.appendChild(parent)
413 var elems = document.getElementsByTagName("SPAN")
415 assert.equal(elems.length, 2)
416 assert.equal(elems[0].id, "foo")
417 assert.equal(elems[1].id, "bar")
423 test("can getElementsByTagName with *", function(assert) {
424 document.body.appendChild(document.createElement("div"))
426 var elems = document.getElementsByTagName("*")
428 assert.equal(elems.length, 4)
429 assert.equal(elems[0].tagName, "HTML")
430 assert.equal(elems[1].tagName, "HEAD")
431 assert.equal(elems[2].tagName, "BODY")
432 assert.equal(elems[3].tagName, "DIV")
438 test("getElement* methods search outside the body", function(assert) {
439 var html = document.documentElement;
440 assert.equal(document.getElementsByTagName("html")[0], html)
443 assert.equal(document.getElementById("foo"), html)
445 html.className = "bar"
446 assert.equal(document.getElementsByClassName("bar")[0], html)
456 test("getElement* methods can be passed to map()", function(assert) {
457 var e1 = document.createElement("div")
458 var e2 = document.createElement("span")
460 document.body.appendChild(e1)
461 document.body.appendChild(e2)
464 ["div", "span"].map(document.getElementsByTagName.bind(document)),
472 ["1", "2"].map(document.getElementById.bind(document)),
480 ["foo", "bar"].map(document.getElementsByClassName.bind(document)),
488 test("can check if it contains an element", function(assert) {
489 var el = document.createElement("div")
490 document.body.appendChild(el)
492 assert.equals(document.contains(document.body), true)
493 assert.equals(document.contains(el), true)
499 test("can do events", function (assert) {
501 function incx() { x++ }
503 var ev = new Event();
504 ev.initEvent("click");
505 document.addEventListener("click", incx)
506 document.dispatchEvent(ev)
510 document.removeEventListener("click", incx)
511 document.dispatchEvent(ev)
517 function blankAttributeNS() {
518 // Most browsers conform to the latest version of the DOM spec,
519 // which requires `getAttributeNS` to return `null` when the attribute
520 // doesn't exist, but some browsers (including phantomjs) implement the
521 // old version of the spec and return an empty string instead, see:
522 // https://developer.mozilla.org/en-US/docs/Web/API/element.getAttributeNS#Return_value
523 var div = document.createElement("div")
524 var blank = div.getAttributeNS(null, "foo")
525 if (!(blank === null || blank === "")) {
526 throw "Expected blank attribute to be either null or empty string"
531 function elemString(element) {
532 var html = String(element) || "[]"
534 if (html.charAt(0) === "[") {
535 html = element.outerHTML
536 if (!html && !element.parentNode) {
537 var div = document.createElement("div")
538 div.appendChild(element)
540 div.removeChild(element)
547 function fragString(fragment) {
548 var html = String(fragment)
551 if (html === "[object DocumentFragment]") {
553 for (var i = 0; i < fragment.childNodes.length; i++) {
554 var node = fragment.childNodes[i]
555 innerHTML.push(String(node.outerHTML || node))
557 html = innerHTML.join("")